如何从Android应用程序获取垃圾数据?

时间:2022-08-04 07:37:44

How can I get crash data (stack traces at least) from my Android application? At least when working on my own device being retrieved by cable, but ideally from any instance of my application running on the wild so that I can improve it and make it more solid.

如何从我的Android应用程序中获取崩溃数据(至少是堆栈跟踪)?至少在我自己的设备上使用有线电视进行检索时,最好是在我的应用程序的任何实例上运行,这样我就可以改进它,使它更可靠。

29 个解决方案

#1


338  

You might try the ACRA (Application Crash Report for Android) library:

您可以尝试使用ACRA (Android应用程序崩溃报告)库:

ACRA is a library enabling Android Application to automatically post their crash reports to a GoogleDoc form. It is targetted to android applications developers to help them get data from their applications when they crash or behave erroneously.

ACRA是一个允许Android应用程序自动将崩溃报告发布到GoogleDoc表单的库。它的目标是android应用程序开发人员,帮助他们在崩溃或行为错误时从应用程序中获取数据。

It's easy to install in your app, highly configurable and don't require you to host a server script anywhere... reports are sent to a Google Doc spreadsheet !

它很容易安装在你的应用程序中,高度可配置,并且不需要你在任何地方托管服务器脚本…报告被发送到一个谷歌文档电子表格!

#2


278  

For sample applications and debugging purposes, I use a simple solution that allows me to write the stacktrace to the sd card of the device and/or upload it to a server. This solution has been inspired by Project android-remote-stacktrace (specifically, the save-to-device and upload-to-server parts) and I think it solves the problem mentioned by Soonil. It's not optimal, but it works and you can improve it if you want to use it in a production application. If you decide to upload the stacktraces to the server, you can use a php script (index.php) to view them. If you're interested, you can find all the sources below - one java class for your application and two optional php scrips for the server hosting the uploaded stacktraces.

对于示例应用程序和调试目的,我使用一个简单的解决方案,它允许我将stacktrace写入设备的sd卡,或者将其上传到服务器。这个解决方案的灵感来自Project android-remote-stacktrace(具体地说,是sato -to-device和uploadto -server部件),我认为它解决了Soonil所提到的问题。它不是最佳的,但它可以工作,如果您想在生产应用程序中使用它,您可以改进它。如果您决定将堆栈跟踪上载到服务器,您可以使用php脚本(index.php)来查看它们。如果您感兴趣,您可以找到以下所有的源—一个java类用于您的应用程序,两个可选的php脚本用于托管上传的堆栈跟踪。

In a Context (e.g. the main Activity), call

在上下文(例如主要活动)中,调用。

if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
    Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(
            "/sdcard/<desired_local_path>", "http://<desired_url>/upload.php"));
}

CustomExceptionHandler

CustomExceptionHandler

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;

    private String localPath;

    private String url;

    /* 
     * if any of the parameters is null, the respective functionality 
     * will not be used 
     */
    public CustomExceptionHandler(String localPath, String url) {
        this.localPath = localPath;
        this.url = url;
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    public void uncaughtException(Thread t, Throwable e) {
        String timestamp = TimestampFormatter.getInstance().getTimestamp();
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = timestamp + ".stacktrace";

        if (localPath != null) {
            writeToFile(stacktrace, filename);
        }
        if (url != null) {
            sendToServer(stacktrace, filename);
        }

        defaultUEH.uncaughtException(t, e);
    }

    private void writeToFile(String stacktrace, String filename) {
        try {
            BufferedWriter bos = new BufferedWriter(new FileWriter(
                    localPath + "/" + filename));
            bos.write(stacktrace);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendToServer(String stacktrace, String filename) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("filename", filename));
        nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
        try {
            httpPost.setEntity(
                    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            httpClient.execute(httpPost);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

upload.php

upload.php

<?php
    $filename = isset($_POST['filename']) ? $_POST['filename'] : "";
    $message = isset($_POST['stacktrace']) ? $_POST['stacktrace'] : "";
    if (!ereg('^[-a-zA-Z0-9_. ]+$', $filename) || $message == ""){
        die("This script is used to log debug data. Please send the "
                . "logging message and a filename as POST variables.");
    }
    file_put_contents($filename, $message . "\n", FILE_APPEND);
?>

index.php

index . php

<?php
    $myDirectory = opendir(".");
    while($entryName = readdir($myDirectory)) {
        $dirArray[] = $entryName;
    }
    closedir($myDirectory);
    $indexCount = count($dirArray);
    sort($dirArray);
    print("<TABLE border=1 cellpadding=5 cellspacing=0 \n");
    print("<TR><TH>Filename</TH><TH>Filetype</th><th>Filesize</TH></TR>\n");
    for($index=0; $index < $indexCount; $index++) {
        if ((substr("$dirArray[$index]", 0, 1) != ".") 
                && (strrpos("$dirArray[$index]", ".stacktrace") != false)){ 
            print("<TR><TD>");
            print("<a href=\"$dirArray[$index]\">$dirArray[$index]</a>");
            print("</TD><TD>");
            print(filetype($dirArray[$index]));
            print("</TD><TD>");
            print(filesize($dirArray[$index]));
            print("</TD></TR>\n");
        }
    }
    print("</TABLE>\n");
?>

#3


54  

You can also try BugSense. BugSense collects and analyzed all crash reports and gives you meaningful and visual reports. It's free and it's only 1 line of code in order to integrate.

你也可以试试BugSense。BugSense收集并分析所有的崩溃报告,并提供有意义的和可视化的报告。它是免费的,只有一行代码才能集成。

Disclaimer: I am a co-founder

免责声明:我是联合创始人。

#4


42  

In Android 2.2 it's now possible to automatically get Crash Reports from Android Market Applications:

在Android 2.2中,现在可以自动从Android Market应用程序得到崩溃报告:

New bug reporting feature for Android Market apps enables developers to receive crash and freeze reports from their users. The reports will be available when they log into their publisher account.

Android Market应用的新bug报告功能使开发人员能够接收崩溃并冻结用户的报告。当他们登录到他们的发布者帐户时,这些报告将会提供。

http://developer.android.com/sdk/android-2.2-highlights.html

http://developer.android.com/sdk/android - 2.2 highlights.html

#5


24  

It is possible to handle these exceptions with Thread.setDefaultUncaughtExceptionHandler(), however this appears to mess with Android's method of handling exceptions. I attempted to use a handler of this nature:

使用Thread.setDefaultUncaughtExceptionHandler()来处理这些异常是可能的,但是这似乎会干扰Android处理异常的方法。我试图使用这种性质的处理程序:

private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable ex){
        Log.e(Constants.TAG, "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);

        //hack to rethrow unchecked exceptions
        if(ex instanceof RuntimeException)
            throw (RuntimeException)ex;
        if(ex instanceof Error)
            throw (Error)ex;

        //this should really never happen
        Log.e(Constants.TAG, "uncaught_exception handler: unable to rethrow checked exception");
    }
}

However, even with rethrowing the exceptions, I was unable to get the desired behavior, ie logging the exception while still allowing Android to shutdown the component it had happened it, so I gave up on it after a while.

然而,即使重新抛出异常,我也无法得到想要的行为(在允许Android关闭它所发生的组件的情况下,也可以记录这个异常),所以我在一段时间后放弃了它。

#6


18  

Ok, well I looked at the provided samples from rrainn and Soonil, and I found a solution that does not mess up error handling.

好的,我看了从rrainn和Soonil提供的样本,我找到了一个解决方案,它不会搞砸错误处理。

I modified the CustomExceptionHandler so it stores the original UncaughtExceptionHandler from the Thread we associate the new one. At the end of the new "uncaughtException"- Method I just call the old function using the stored UncaughtExceptionHandler.

我修改了CustomExceptionHandler,这样它就可以从我们关联新线程的线程中存储原始的UncaughtExceptionHandler。在新“uncaughtException”的结尾,我用存储的UncaughtExceptionHandler调用旧函数。

In the DefaultExceptionHandler class you need sth. like this:

在DefaultExceptionHandler类中,您需要如下所示:

public class DefaultExceptionHandler implements UncaughtExceptionHandler{
  private UncaughtExceptionHandler mDefaultExceptionHandler;

  //constructor
  public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)
  {
       mDefaultExceptionHandler= pDefaultExceptionHandler;
  }
  public void uncaughtException(Thread t, Throwable e) {       
        //do some action like writing to file or upload somewhere         

        //call original handler  
        mStandardEH.uncaughtException(t, e);        

        // cleanup, don't know if really required
        t.getThreadGroup().destroy();
  }
}

With that modification on the code at http://code.google.com/p/android-remote-stacktrace you have a good working base for logging in the field to your webserver or to sd-card.

在http://code.google.com/p/android-remote-stacktrace上修改代码,您就有了一个良好的工作基础,可以登录到您的web服务器或sd卡。

#7


18  

I've been using Crittercism for my Android and iOS apps -- heard about them on techcrunch. Pretty happy with them so far!

我一直在为我的安卓和iOS应用程序使用Crittercism——在techcrunch上听说过。到目前为止,他们都很开心!

#8


18  

I see that the question is too old, and hope my answer is helpful for others having the same issue...

我认为这个问题太老了,希望我的回答能帮助其他有同样问题的人……

Give Crashlytics a try. It will give indepth insight into all the crashes on all the devices having your application and send a notification to you through email..And the best part is its completely free to use..

给Crashlytics一试。它将深入了解所有应用程序的崩溃,并通过电子邮件向您发送通知。最好的部分是完全免费使用。

#9


16  

Google Play Developers Console actually gives you the Stack traces from those apps that have crashed and had sent the reports, it has also a very good charts to help you see the information, see example below:

谷歌游戏开发人员控制台实际上提供了那些已经崩溃的应用程序的堆栈跟踪,并且已经发送了报告,它还提供了一个非常好的图表来帮助您查看信息,请看下面的示例:

如何从Android应用程序获取垃圾数据?

#10


13  

I made my own version here : http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html

我在这里创建了自己的版本:http://androidblogger.blogspot.com/2009/12/howto -to- your-application-crash.html。

It's basically the same thing, but I'm using a mail rather than a http connexion to send the report, and, more important, I added some informations like application version, OS version, Phone model, or avalaible memory to my report...

基本上是一样的,但是我使用的是邮件而不是http connexion来发送报告,更重要的是,我添加了一些信息,比如应用程序版本、操作系统版本、手机模型,或者是我的报告中的avalaible内存……

#11


11  

use this to catch the exception details:

用这个来捕捉异常细节:

String stackTrace = Log.getStackTraceString(exception); 

store this in database and maintain the log.

将此存储在数据库中并维护日志。

#12


8  

You can also use a whole (simple) service for it rather than only library. Our company just released a service just for that: http://apphance.com.

您还可以使用整个(简单的)服务,而不仅仅是库。我们公司刚刚发布了一个服务:http://apphance.com。

It has a simple .jar library (for Android) that you add and integrate in 5 minutes and then the library gathers not only crash information but also logs from running application, as well as it lets your testers report problems straight from device - including the whole context (device rotation, whether it is connected to a wifi or not and more). You can look at the logs using a very nice and useful web panel, where you can track sessions with your application, crashes, logs, statistics and more. The service is in closed beta test phase now, but you can request access and we give it to you very quickly.

它有一个简单的. jar库(Android)在5分钟,然后添加和整合图书馆收集不仅崩溃信息也从正在运行的应用程序日志,以及它可以让测试人员报告问题直接从设备——包括整个上下文(设备旋转,是否它是连接到一个无线网络等等)。您可以使用一个非常好的和有用的web面板查看日志,您可以在其中跟踪应用程序、崩溃、日志、统计数据等等。该服务目前处于封闭测试阶段,但您可以请求访问,我们很快就会给您。

Disclaimer: I am CTO of Polidea, and co-creator of the service.

免责声明:我是Polidea的CTO,也是该服务的共同创建者。

#13


5  

This is very brute, but it is possible to run logcat anywhere, so a quick and dirty hack is to add to any catch block getRuntime().exec("logcat >> /sdcard/logcat.log");

这是非常残忍的,但是可以在任何地方运行logcat,因此一个快速而肮脏的hack是添加到任何catch块getRuntime()。exec(“logcat > > / sdcard / logcat.log”);

#14


5  

Thanks resources present in * in helping me to find this answer.

感谢在*的资源帮助我找到这个答案。

You can find your remotely Android crash reports directly into your email. remmember you have to put your email inside CustomExceptionHandler class.

你可以直接在你的电子邮件中找到你的远程Android崩溃报告。remmember你必须把你的电子邮件放在CustomExceptionHandler类里面。

public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

Steps required :

步骤:

1st) in onCreate of your activity use this section of your code.

1)在onCreate中,使用这段代码。

    if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
    }   

2nd) use this overridden version of CustomExceptionHandler class of ( rrainn ), according to my phpscript.

根据我的phpscript,使用这个重载版本的CustomExceptionHandler类(rrainn)。

package com.vxmobilecomm.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;
    public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

    Activity activity;

    public CustomExceptionHandler(Activity activity) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.activity = activity;
    }

    public void uncaughtException(Thread t, Throwable e) {

        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = "error" + System.nanoTime() + ".stacktrace";

        Log.e("Hi", "url != null");
        sendToServer(stacktrace, filename);

        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString() + "\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i = 0; i < arr.length; i++) {
            report += "    " + arr[i].toString() + "\n";
        }
        report += "-------------------------------\n\n";

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if (cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i = 0; i < arr.length; i++) {
                report += "    " + arr[i].toString() + "\n";
            }
        }
        report += "-------------------------------\n\n";

        defaultUEH.uncaughtException(t, e);
    }

    private void sendToServer(String stacktrace, String filename) {
        AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
                getAppLable(activity));
        async.execute("");
    }

    public String getAppLable(Context pContext) {
        PackageManager lPackageManager = pContext.getPackageManager();
        ApplicationInfo lApplicationInfo = null;
        try {
            lApplicationInfo = lPackageManager.getApplicationInfo(
                    pContext.getApplicationInfo().packageName, 0);
        } catch (final NameNotFoundException e) {
        }
        return (String) (lApplicationInfo != null ? lPackageManager
                .getApplicationLabel(lApplicationInfo) : "Unknown");
    }

    public class AsyncTaskClass extends AsyncTask<String, String, InputStream> {
        InputStream is = null;
        String stacktrace;
        final String filename;
        String applicationName;

        AsyncTaskClass(final String stacktrace, final String filename,
                String applicationName) {
            this.applicationName = applicationName;
            this.stacktrace = stacktrace;
            this.filename = filename;
        }

        @Override
        protected InputStream doInBackground(String... params) 
        { 
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(
                    "http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php?");

            Log.i("Error", stacktrace);

            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                        6);

                nameValuePairs.add(new BasicNameValuePair("data", stacktrace));
                nameValuePairs.add(new BasicNameValuePair("to",sendErrorLogsTo));
                nameValuePairs.add(new BasicNameValuePair("subject",applicationName));

                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                HttpResponse response = httpclient.execute(httppost);

                HttpEntity entity1 = response.getEntity();

                BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
                        entity1);

                is = bufHttpEntity.getContent();

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return is;
        }

        @Override
        protected void onPostExecute(InputStream result) {
            super.onPostExecute(result);

            Log.e("Stream Data", getStringFromInputStream(is));
        }
    }

    // convert InputStream to String
    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

#15


5  

There is a tool called fabric, this is a crash analytic tool, which will allow you to get crash reports , when application deployed live and during development. Adding this tool to your application was simple as well.. When your application crash that report of the crash can be viewed from your fabric.io dashboard . thw report was catched automatically.it won't ask user for permission. Whether he/she want to send the bug/crash report. And this is completely free... https://get.fabric.io/

有一个叫做fabric的工具,这是一个崩溃分析工具,它可以让您在应用程序部署时和开发期间得到崩溃报告。将此工具添加到应用程序中也很简单。当您的应用程序崩溃时,可以从您的fabric上查看崩溃报告。io仪表板。那份报告是自动完成的。它不会请求用户允许。是否要发送错误/崩溃报告。这是完全免费的…https://get.fabric.io/

#16


5  

Google Firebase is Google's latest(2016) way to provide you with crash/error data on your phone. Include it in your build.gradle file :

谷歌Firebase是谷歌最新的(2016)方式,为您提供手机的崩溃/错误数据。把它包含在你的构建中。gradle文件:

compile 'com.google.firebase:firebase-crash:9.0.0'

Fatal crashes are logged automatically without requiring user input and you can also log non-fatal crashes or other events like so :

在不需要用户输入的情况下自动记录致命的崩溃,您也可以记录非致命的崩溃或其他事件:

try
{

}
catch(Exception ex)
{
    FirebaseCrash.report(new Exception(ex.toString()));
}

#17


4  

We use our home-grown system inside the company and it serves us very well. It's an android library that send crash reports to server and server that receives reports and makes some analytics. Server groups exceptions by exception name, stacktrace, message. It helps to identify most critical issues that need to be fixed. Our service is in public beta now so everyone can try it. You can create account at http://watchcat.co or you can just take a look how it works using demo access http://watchcat.co/reports/index.php?demo.

我们在公司内部使用我们自己的系统,这对我们很有帮助。它是一个android库,向服务器和服务器发送崩溃报告,接收报告并进行一些分析。服务器组异常的例外名称,堆栈跟踪,消息。它有助于确定需要修复的最关键问题。我们的服务现在是公开测试版,所以每个人都可以尝试。您可以在http://watchcat中创建帐户。co或者您可以看看它是如何使用演示访问http://watchcat.co/reports/index.php?demo。

#18


3  

I found one more great web application to track the error reports.

我找到了一个更好的web应用程序来跟踪错误报告。

https://mint.splunk.com/

https://mint.splunk.com/

Small number of steps to configure.

配置的步骤很少。

  1. Login or sign up and configure using the above link. Once you done creating a application they will provide a line to configure like below.
  2. 使用上面的链接登录或注册和配置。一旦您完成了创建一个应用程序,它们将提供如下所示的行。
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. Add the following in the application's build.gradl.
  2. 在应用程序的build.gradl中添加以下内容。
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. Add the code which we copied above and add it to every activity.

    Mint.initAndStartSession(YourActivity.this, "api_key");

    Mint.initAndStartSession(YourActivity。这个,”api_key”);

That's it. You login and go to you application dashboard, you will get all the error reports.

就是这样。您登录并进入应用程序指示板,您将得到所有的错误报告。

Hope it helps someone.

希望它能帮助一些人。

#19


3  

While many of the answers on this page are useful, it is easy for them to become out of date. The AppBrain website aggregates statistics which allow you to find the most popular crash reporting solution that is current:

虽然这个页面上的许多答案都是有用的,但是它们很容易过时。AppBrain网站汇集了统计数据,让你找到最流行的崩溃报告解决方案:

Android crash reporting libraries

Android崩溃报告库

如何从Android应用程序获取垃圾数据?

You can see that at the time of posting this picture, Crashlytics is used in 5.24% of apps and 12.38% of installs.

您可以看到,在发布这张照片的时候,Crashlytics应用在5.24%的应用程序和12.38%的安装程序中。

#20


2  

If you want answers immediately you can use logcat

如果你想立即得到答案,你可以用logcat。

$adb shell logcat -f /sdcard/logoutput.txt *:E

$adb shell logcat -f /sdcard/logoutput。txt *:E

If there's too much junk in your log right now, try clearing it first.

如果现在你的日志中有太多的垃圾,试着先清除它。

$adb shell logcat -c

亚洲开发银行美元壳logcat - c

Then try running your app then logcat again.

然后再尝试运行你的应用程序,然后再次登录。

#21


2  

For an alternate crash reporting/exception tracking service check out Raygun.io - it's got a bunch of nice logic for handling Android crashes, including decent user experience when plugging it in to your app (two lines of code in your main Activity and a few lines of XML pasted into AndroidManifest).

对于一个备用的崩溃报告/异常跟踪服务,请查看Raygun。io——在处理Android崩溃时,它有很多不错的逻辑,包括在你的应用程序(你的主要活动中有两行代码,以及几行XML粘贴到AndroidManifest中)时的良好用户体验。

When your app crashes, it'll automatically grab the stack trace, environment data for hard/software, user tracking info, any custom data you specify etc. It posts it to the API asynchronously so no blocking of the UI thread, and caches it to disk if there's no network available.

当您的应用程序崩溃时,它会自动抓取堆栈跟踪、硬/软件环境数据、用户跟踪信息、您指定的任何自定义数据等。它会异步地将其发送到API,这样就不会阻塞UI线程,如果没有可用的网络,就将其缓存到磁盘。

Disclaimer: I built the Android provider :)

免责声明:我创建了Android供应商:)

#22


2  

There is this android library called Sherlock. It gives you the full report of crash along with device and application information. Whenever a crash occurs, it displays a notification in the notification bar and on clicking of the notification, it opens the crash details. You can also share crash details with others via email or other sharing options.

有一个叫做夏洛克的安卓图书馆。它提供了与设备和应用程序信息一起崩溃的完整报告。当发生崩溃时,它会在通知栏中显示通知并单击通知,它将打开崩溃的详细信息。您还可以通过电子邮件或其他共享选项与他人共享崩溃细节。

Installation

安装

android {
    dataBinding {
      enabled = true
    }
}

compile('com.github.ajitsing:sherlock:1.0.0@aar') {
    transitive = true
}

Demo

演示

如何从Android应用程序获取垃圾数据?

#23


2  

Now a days Firebase Crash reports are very popular and easier to use. Please refer following link for more information: Firebase Crash Reporting

现在,Firebase的崩溃报告非常流行,并且更容易使用。更多信息请参考以下链接:Firebase崩溃报告。

Hope it will help you.

希望它能帮到你。

#24


1  

Just Started to use ACRA https://github.com/ACRA/acra using Google Forms as backend and it's very easy to setup & use, it's the default.

开始使用谷歌格式的ACRA https://github.com/ACRA/acra作为后端,它很容易设置和使用,这是默认的。

BUT Sending reports to Google Forms are going to be deprecated (then removed): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google-Form-Spreadsheet-usage

但是,将报告发送到谷歌表单将被废弃(然后删除):https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/acra/acra/wiki/notification -on-Google- form - spreadsheet -usage。

Anyway it's possible to define your own sender https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender you can give a try to email sender for example.

无论如何,你可以定义你自己的发送者https://github.com/acra/acra/acra/wiki/advancedusage #wiki-Implementing_your_own_sender你可以尝试发送电子邮件发送者。

With minimum effort it's possible to send reports to bugsense: http://www.bugsense.com/docs/android#acra

通过最小的努力,可以将报告发送给bugsense: http://www.bugsense.com/docs/android#acra。

NB The bugsense free account is limited to 500 report/month

NB免费帐户被限制在500报告/月。

#25


1  

Late to the party, I support and believe ACRA is the best option among all. Its easy to setup and configure. I have created a detailed guide with inputs from all over to fetch the crash report using ACRA and mail the same to my email address using MandrillAp.

在晚会上,我支持并相信ACRA是最好的选择。它易于设置和配置。我已经创建了一个详细的指南,其中包括使用ACRA来获取崩溃报告,并使用MandrillAp将相同的邮件发送到我的电子邮件地址。

Link to post: https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

帖子链接:https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

Link to sample project on github: https://github.com/ayushhgoyal/AcraSample

链接到github上的示例项目:https://github.com/ayushhgoyal/AcraSample。

#26


1  

I'm one of the founders of Bugsnag which we designed for exactly this purpose. Bugsnag automatically captures unhandled exceptions in Android apps and sends them to our dashboard, where you can prioritize fixes and dive into diagnostic information.

我是bugblock的创始人之一,我们正是为这个目的而设计的。在Android应用程序中,bugcatch自动捕获未处理的异常,并将它们发送到我们的仪表板,在那里,您可以对修复进行优先级排序,并深入到诊断信息中。

Here are some important things to consider when selecting or building a crash reporting system, along with some code snippets:

在选择或构建崩溃报告系统时,需要考虑一些重要的事情,以及一些代码片段:

  • Detects unhandled exceptions automatically (example code)
  • 自动检测未处理的异常(示例代码)
  • Collects diagnostic data such as memory usage, device info, etc (example code)
  • 收集诊断数据,如内存使用、设备信息等(示例代码)
  • Effectively groups crashes together by root cause
  • 有效的分组由根本原因一起崩溃。
  • Allows you to track actions the user took before each crash to help reproduce (example code)
  • 允许您跟踪用户在每次崩溃前采取的操作以帮助复制(示例代码)

If you want to see some best practices around crash handling/reporting on Android you can check out the full source code for Bugsnag's crash reporting library which is fully open source, feel free to tear this apart and use it in your own applications!

如果您希望看到关于Android的崩溃处理/报告的一些最佳实践,您可以查看bugcatch的崩溃报告库的完整源代码,它是完全开源的,您可以在自己的应用程序中使用它。

#27


0  

If your app is being downloaded by other people and crashing on remote devices, you may want to look into an Android error reporting library (referenced in this SO post). If it's just on your own local device, you can use LogCat. Even if the device wasn't connected to a host machine when the crash occurred, connected the device and issuing an adb logcat command will download the entire logcat history (at least to the extent that it is buffered which is usually a loooot of log data, it's just not infinite). Do either of those options answer your question? If not can you attempt to clarify what you're looking for a bit more?

如果你的应用程序被其他人下载并在远程设备上崩溃,你可能想要查看一个Android错误报告库(在这篇文章中引用)。如果只是在本地设备上,可以使用LogCat。即使设备没有连接到主机,当崩溃发生时,连接设备并发出adb logcat命令将下载整个logcat历史(至少在它被缓冲的程度上,这通常是一个日志数据的loooot,它不是无限的)。这些选项中有哪一个能回答你的问题?如果不能,你可以试着澄清一下你想要的是什么吗?

#28


0  

Flurry analytics gives you crash info, hardware model, android version and live app usage stats. In the new SDK they seem to provide more detailed crash info http://www.flurry.com/flurry-crash-analytics.html.

Flurry analytics提供了崩溃信息、硬件模型、android版本和实时应用程序数据。在新的SDK中,他们似乎提供了更详细的崩溃信息:http://www.flurry.com/flurry-crash-analytics.html。

#29


0  

Google changed how much crash reports you actually get. Previously you only got manual reported bug reports.

谷歌改变了你实际得到的崩溃报告。以前只有手动报告的bug报告。

Since the last developer conference and the introducation of Android Vitals you also get crash reports from users which have enabled to share diagnostics data.

自从上次开发人员会议和Android Vitals的介绍之后,您还可以从用户那里获取崩溃报告,这些用户可以共享诊断数据。

You'll see all crashes collected from Android devices whose users have opted in to automatically share usage and diagnostics data. Data is available for the previous two months.

您将看到从Android设备收集到的所有崩溃,这些设备的用户选择了自动共享使用和诊断数据。数据可在前两个月使用。

View crashes & application not responding (ANR) errors

视图崩溃和应用程序没有响应(ANR)错误。

#1


338  

You might try the ACRA (Application Crash Report for Android) library:

您可以尝试使用ACRA (Android应用程序崩溃报告)库:

ACRA is a library enabling Android Application to automatically post their crash reports to a GoogleDoc form. It is targetted to android applications developers to help them get data from their applications when they crash or behave erroneously.

ACRA是一个允许Android应用程序自动将崩溃报告发布到GoogleDoc表单的库。它的目标是android应用程序开发人员,帮助他们在崩溃或行为错误时从应用程序中获取数据。

It's easy to install in your app, highly configurable and don't require you to host a server script anywhere... reports are sent to a Google Doc spreadsheet !

它很容易安装在你的应用程序中,高度可配置,并且不需要你在任何地方托管服务器脚本…报告被发送到一个谷歌文档电子表格!

#2


278  

For sample applications and debugging purposes, I use a simple solution that allows me to write the stacktrace to the sd card of the device and/or upload it to a server. This solution has been inspired by Project android-remote-stacktrace (specifically, the save-to-device and upload-to-server parts) and I think it solves the problem mentioned by Soonil. It's not optimal, but it works and you can improve it if you want to use it in a production application. If you decide to upload the stacktraces to the server, you can use a php script (index.php) to view them. If you're interested, you can find all the sources below - one java class for your application and two optional php scrips for the server hosting the uploaded stacktraces.

对于示例应用程序和调试目的,我使用一个简单的解决方案,它允许我将stacktrace写入设备的sd卡,或者将其上传到服务器。这个解决方案的灵感来自Project android-remote-stacktrace(具体地说,是sato -to-device和uploadto -server部件),我认为它解决了Soonil所提到的问题。它不是最佳的,但它可以工作,如果您想在生产应用程序中使用它,您可以改进它。如果您决定将堆栈跟踪上载到服务器,您可以使用php脚本(index.php)来查看它们。如果您感兴趣,您可以找到以下所有的源—一个java类用于您的应用程序,两个可选的php脚本用于托管上传的堆栈跟踪。

In a Context (e.g. the main Activity), call

在上下文(例如主要活动)中,调用。

if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
    Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(
            "/sdcard/<desired_local_path>", "http://<desired_url>/upload.php"));
}

CustomExceptionHandler

CustomExceptionHandler

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;

    private String localPath;

    private String url;

    /* 
     * if any of the parameters is null, the respective functionality 
     * will not be used 
     */
    public CustomExceptionHandler(String localPath, String url) {
        this.localPath = localPath;
        this.url = url;
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    public void uncaughtException(Thread t, Throwable e) {
        String timestamp = TimestampFormatter.getInstance().getTimestamp();
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = timestamp + ".stacktrace";

        if (localPath != null) {
            writeToFile(stacktrace, filename);
        }
        if (url != null) {
            sendToServer(stacktrace, filename);
        }

        defaultUEH.uncaughtException(t, e);
    }

    private void writeToFile(String stacktrace, String filename) {
        try {
            BufferedWriter bos = new BufferedWriter(new FileWriter(
                    localPath + "/" + filename));
            bos.write(stacktrace);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendToServer(String stacktrace, String filename) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("filename", filename));
        nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
        try {
            httpPost.setEntity(
                    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            httpClient.execute(httpPost);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

upload.php

upload.php

<?php
    $filename = isset($_POST['filename']) ? $_POST['filename'] : "";
    $message = isset($_POST['stacktrace']) ? $_POST['stacktrace'] : "";
    if (!ereg('^[-a-zA-Z0-9_. ]+$', $filename) || $message == ""){
        die("This script is used to log debug data. Please send the "
                . "logging message and a filename as POST variables.");
    }
    file_put_contents($filename, $message . "\n", FILE_APPEND);
?>

index.php

index . php

<?php
    $myDirectory = opendir(".");
    while($entryName = readdir($myDirectory)) {
        $dirArray[] = $entryName;
    }
    closedir($myDirectory);
    $indexCount = count($dirArray);
    sort($dirArray);
    print("<TABLE border=1 cellpadding=5 cellspacing=0 \n");
    print("<TR><TH>Filename</TH><TH>Filetype</th><th>Filesize</TH></TR>\n");
    for($index=0; $index < $indexCount; $index++) {
        if ((substr("$dirArray[$index]", 0, 1) != ".") 
                && (strrpos("$dirArray[$index]", ".stacktrace") != false)){ 
            print("<TR><TD>");
            print("<a href=\"$dirArray[$index]\">$dirArray[$index]</a>");
            print("</TD><TD>");
            print(filetype($dirArray[$index]));
            print("</TD><TD>");
            print(filesize($dirArray[$index]));
            print("</TD></TR>\n");
        }
    }
    print("</TABLE>\n");
?>

#3


54  

You can also try BugSense. BugSense collects and analyzed all crash reports and gives you meaningful and visual reports. It's free and it's only 1 line of code in order to integrate.

你也可以试试BugSense。BugSense收集并分析所有的崩溃报告,并提供有意义的和可视化的报告。它是免费的,只有一行代码才能集成。

Disclaimer: I am a co-founder

免责声明:我是联合创始人。

#4


42  

In Android 2.2 it's now possible to automatically get Crash Reports from Android Market Applications:

在Android 2.2中,现在可以自动从Android Market应用程序得到崩溃报告:

New bug reporting feature for Android Market apps enables developers to receive crash and freeze reports from their users. The reports will be available when they log into their publisher account.

Android Market应用的新bug报告功能使开发人员能够接收崩溃并冻结用户的报告。当他们登录到他们的发布者帐户时,这些报告将会提供。

http://developer.android.com/sdk/android-2.2-highlights.html

http://developer.android.com/sdk/android - 2.2 highlights.html

#5


24  

It is possible to handle these exceptions with Thread.setDefaultUncaughtExceptionHandler(), however this appears to mess with Android's method of handling exceptions. I attempted to use a handler of this nature:

使用Thread.setDefaultUncaughtExceptionHandler()来处理这些异常是可能的,但是这似乎会干扰Android处理异常的方法。我试图使用这种性质的处理程序:

private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable ex){
        Log.e(Constants.TAG, "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);

        //hack to rethrow unchecked exceptions
        if(ex instanceof RuntimeException)
            throw (RuntimeException)ex;
        if(ex instanceof Error)
            throw (Error)ex;

        //this should really never happen
        Log.e(Constants.TAG, "uncaught_exception handler: unable to rethrow checked exception");
    }
}

However, even with rethrowing the exceptions, I was unable to get the desired behavior, ie logging the exception while still allowing Android to shutdown the component it had happened it, so I gave up on it after a while.

然而,即使重新抛出异常,我也无法得到想要的行为(在允许Android关闭它所发生的组件的情况下,也可以记录这个异常),所以我在一段时间后放弃了它。

#6


18  

Ok, well I looked at the provided samples from rrainn and Soonil, and I found a solution that does not mess up error handling.

好的,我看了从rrainn和Soonil提供的样本,我找到了一个解决方案,它不会搞砸错误处理。

I modified the CustomExceptionHandler so it stores the original UncaughtExceptionHandler from the Thread we associate the new one. At the end of the new "uncaughtException"- Method I just call the old function using the stored UncaughtExceptionHandler.

我修改了CustomExceptionHandler,这样它就可以从我们关联新线程的线程中存储原始的UncaughtExceptionHandler。在新“uncaughtException”的结尾,我用存储的UncaughtExceptionHandler调用旧函数。

In the DefaultExceptionHandler class you need sth. like this:

在DefaultExceptionHandler类中,您需要如下所示:

public class DefaultExceptionHandler implements UncaughtExceptionHandler{
  private UncaughtExceptionHandler mDefaultExceptionHandler;

  //constructor
  public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)
  {
       mDefaultExceptionHandler= pDefaultExceptionHandler;
  }
  public void uncaughtException(Thread t, Throwable e) {       
        //do some action like writing to file or upload somewhere         

        //call original handler  
        mStandardEH.uncaughtException(t, e);        

        // cleanup, don't know if really required
        t.getThreadGroup().destroy();
  }
}

With that modification on the code at http://code.google.com/p/android-remote-stacktrace you have a good working base for logging in the field to your webserver or to sd-card.

在http://code.google.com/p/android-remote-stacktrace上修改代码,您就有了一个良好的工作基础,可以登录到您的web服务器或sd卡。

#7


18  

I've been using Crittercism for my Android and iOS apps -- heard about them on techcrunch. Pretty happy with them so far!

我一直在为我的安卓和iOS应用程序使用Crittercism——在techcrunch上听说过。到目前为止,他们都很开心!

#8


18  

I see that the question is too old, and hope my answer is helpful for others having the same issue...

我认为这个问题太老了,希望我的回答能帮助其他有同样问题的人……

Give Crashlytics a try. It will give indepth insight into all the crashes on all the devices having your application and send a notification to you through email..And the best part is its completely free to use..

给Crashlytics一试。它将深入了解所有应用程序的崩溃,并通过电子邮件向您发送通知。最好的部分是完全免费使用。

#9


16  

Google Play Developers Console actually gives you the Stack traces from those apps that have crashed and had sent the reports, it has also a very good charts to help you see the information, see example below:

谷歌游戏开发人员控制台实际上提供了那些已经崩溃的应用程序的堆栈跟踪,并且已经发送了报告,它还提供了一个非常好的图表来帮助您查看信息,请看下面的示例:

如何从Android应用程序获取垃圾数据?

#10


13  

I made my own version here : http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html

我在这里创建了自己的版本:http://androidblogger.blogspot.com/2009/12/howto -to- your-application-crash.html。

It's basically the same thing, but I'm using a mail rather than a http connexion to send the report, and, more important, I added some informations like application version, OS version, Phone model, or avalaible memory to my report...

基本上是一样的,但是我使用的是邮件而不是http connexion来发送报告,更重要的是,我添加了一些信息,比如应用程序版本、操作系统版本、手机模型,或者是我的报告中的avalaible内存……

#11


11  

use this to catch the exception details:

用这个来捕捉异常细节:

String stackTrace = Log.getStackTraceString(exception); 

store this in database and maintain the log.

将此存储在数据库中并维护日志。

#12


8  

You can also use a whole (simple) service for it rather than only library. Our company just released a service just for that: http://apphance.com.

您还可以使用整个(简单的)服务,而不仅仅是库。我们公司刚刚发布了一个服务:http://apphance.com。

It has a simple .jar library (for Android) that you add and integrate in 5 minutes and then the library gathers not only crash information but also logs from running application, as well as it lets your testers report problems straight from device - including the whole context (device rotation, whether it is connected to a wifi or not and more). You can look at the logs using a very nice and useful web panel, where you can track sessions with your application, crashes, logs, statistics and more. The service is in closed beta test phase now, but you can request access and we give it to you very quickly.

它有一个简单的. jar库(Android)在5分钟,然后添加和整合图书馆收集不仅崩溃信息也从正在运行的应用程序日志,以及它可以让测试人员报告问题直接从设备——包括整个上下文(设备旋转,是否它是连接到一个无线网络等等)。您可以使用一个非常好的和有用的web面板查看日志,您可以在其中跟踪应用程序、崩溃、日志、统计数据等等。该服务目前处于封闭测试阶段,但您可以请求访问,我们很快就会给您。

Disclaimer: I am CTO of Polidea, and co-creator of the service.

免责声明:我是Polidea的CTO,也是该服务的共同创建者。

#13


5  

This is very brute, but it is possible to run logcat anywhere, so a quick and dirty hack is to add to any catch block getRuntime().exec("logcat >> /sdcard/logcat.log");

这是非常残忍的,但是可以在任何地方运行logcat,因此一个快速而肮脏的hack是添加到任何catch块getRuntime()。exec(“logcat > > / sdcard / logcat.log”);

#14


5  

Thanks resources present in * in helping me to find this answer.

感谢在*的资源帮助我找到这个答案。

You can find your remotely Android crash reports directly into your email. remmember you have to put your email inside CustomExceptionHandler class.

你可以直接在你的电子邮件中找到你的远程Android崩溃报告。remmember你必须把你的电子邮件放在CustomExceptionHandler类里面。

public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

Steps required :

步骤:

1st) in onCreate of your activity use this section of your code.

1)在onCreate中,使用这段代码。

    if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
    }   

2nd) use this overridden version of CustomExceptionHandler class of ( rrainn ), according to my phpscript.

根据我的phpscript,使用这个重载版本的CustomExceptionHandler类(rrainn)。

package com.vxmobilecomm.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;
    public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

    Activity activity;

    public CustomExceptionHandler(Activity activity) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.activity = activity;
    }

    public void uncaughtException(Thread t, Throwable e) {

        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = "error" + System.nanoTime() + ".stacktrace";

        Log.e("Hi", "url != null");
        sendToServer(stacktrace, filename);

        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString() + "\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i = 0; i < arr.length; i++) {
            report += "    " + arr[i].toString() + "\n";
        }
        report += "-------------------------------\n\n";

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if (cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i = 0; i < arr.length; i++) {
                report += "    " + arr[i].toString() + "\n";
            }
        }
        report += "-------------------------------\n\n";

        defaultUEH.uncaughtException(t, e);
    }

    private void sendToServer(String stacktrace, String filename) {
        AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
                getAppLable(activity));
        async.execute("");
    }

    public String getAppLable(Context pContext) {
        PackageManager lPackageManager = pContext.getPackageManager();
        ApplicationInfo lApplicationInfo = null;
        try {
            lApplicationInfo = lPackageManager.getApplicationInfo(
                    pContext.getApplicationInfo().packageName, 0);
        } catch (final NameNotFoundException e) {
        }
        return (String) (lApplicationInfo != null ? lPackageManager
                .getApplicationLabel(lApplicationInfo) : "Unknown");
    }

    public class AsyncTaskClass extends AsyncTask<String, String, InputStream> {
        InputStream is = null;
        String stacktrace;
        final String filename;
        String applicationName;

        AsyncTaskClass(final String stacktrace, final String filename,
                String applicationName) {
            this.applicationName = applicationName;
            this.stacktrace = stacktrace;
            this.filename = filename;
        }

        @Override
        protected InputStream doInBackground(String... params) 
        { 
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(
                    "http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php?");

            Log.i("Error", stacktrace);

            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                        6);

                nameValuePairs.add(new BasicNameValuePair("data", stacktrace));
                nameValuePairs.add(new BasicNameValuePair("to",sendErrorLogsTo));
                nameValuePairs.add(new BasicNameValuePair("subject",applicationName));

                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                HttpResponse response = httpclient.execute(httppost);

                HttpEntity entity1 = response.getEntity();

                BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
                        entity1);

                is = bufHttpEntity.getContent();

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return is;
        }

        @Override
        protected void onPostExecute(InputStream result) {
            super.onPostExecute(result);

            Log.e("Stream Data", getStringFromInputStream(is));
        }
    }

    // convert InputStream to String
    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

#15


5  

There is a tool called fabric, this is a crash analytic tool, which will allow you to get crash reports , when application deployed live and during development. Adding this tool to your application was simple as well.. When your application crash that report of the crash can be viewed from your fabric.io dashboard . thw report was catched automatically.it won't ask user for permission. Whether he/she want to send the bug/crash report. And this is completely free... https://get.fabric.io/

有一个叫做fabric的工具,这是一个崩溃分析工具,它可以让您在应用程序部署时和开发期间得到崩溃报告。将此工具添加到应用程序中也很简单。当您的应用程序崩溃时,可以从您的fabric上查看崩溃报告。io仪表板。那份报告是自动完成的。它不会请求用户允许。是否要发送错误/崩溃报告。这是完全免费的…https://get.fabric.io/

#16


5  

Google Firebase is Google's latest(2016) way to provide you with crash/error data on your phone. Include it in your build.gradle file :

谷歌Firebase是谷歌最新的(2016)方式,为您提供手机的崩溃/错误数据。把它包含在你的构建中。gradle文件:

compile 'com.google.firebase:firebase-crash:9.0.0'

Fatal crashes are logged automatically without requiring user input and you can also log non-fatal crashes or other events like so :

在不需要用户输入的情况下自动记录致命的崩溃,您也可以记录非致命的崩溃或其他事件:

try
{

}
catch(Exception ex)
{
    FirebaseCrash.report(new Exception(ex.toString()));
}

#17


4  

We use our home-grown system inside the company and it serves us very well. It's an android library that send crash reports to server and server that receives reports and makes some analytics. Server groups exceptions by exception name, stacktrace, message. It helps to identify most critical issues that need to be fixed. Our service is in public beta now so everyone can try it. You can create account at http://watchcat.co or you can just take a look how it works using demo access http://watchcat.co/reports/index.php?demo.

我们在公司内部使用我们自己的系统,这对我们很有帮助。它是一个android库,向服务器和服务器发送崩溃报告,接收报告并进行一些分析。服务器组异常的例外名称,堆栈跟踪,消息。它有助于确定需要修复的最关键问题。我们的服务现在是公开测试版,所以每个人都可以尝试。您可以在http://watchcat中创建帐户。co或者您可以看看它是如何使用演示访问http://watchcat.co/reports/index.php?demo。

#18


3  

I found one more great web application to track the error reports.

我找到了一个更好的web应用程序来跟踪错误报告。

https://mint.splunk.com/

https://mint.splunk.com/

Small number of steps to configure.

配置的步骤很少。

  1. Login or sign up and configure using the above link. Once you done creating a application they will provide a line to configure like below.
  2. 使用上面的链接登录或注册和配置。一旦您完成了创建一个应用程序,它们将提供如下所示的行。
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. Add the following in the application's build.gradl.
  2. 在应用程序的build.gradl中添加以下内容。
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. Add the code which we copied above and add it to every activity.

    Mint.initAndStartSession(YourActivity.this, "api_key");

    Mint.initAndStartSession(YourActivity。这个,”api_key”);

That's it. You login and go to you application dashboard, you will get all the error reports.

就是这样。您登录并进入应用程序指示板,您将得到所有的错误报告。

Hope it helps someone.

希望它能帮助一些人。

#19


3  

While many of the answers on this page are useful, it is easy for them to become out of date. The AppBrain website aggregates statistics which allow you to find the most popular crash reporting solution that is current:

虽然这个页面上的许多答案都是有用的,但是它们很容易过时。AppBrain网站汇集了统计数据,让你找到最流行的崩溃报告解决方案:

Android crash reporting libraries

Android崩溃报告库

如何从Android应用程序获取垃圾数据?

You can see that at the time of posting this picture, Crashlytics is used in 5.24% of apps and 12.38% of installs.

您可以看到,在发布这张照片的时候,Crashlytics应用在5.24%的应用程序和12.38%的安装程序中。

#20


2  

If you want answers immediately you can use logcat

如果你想立即得到答案,你可以用logcat。

$adb shell logcat -f /sdcard/logoutput.txt *:E

$adb shell logcat -f /sdcard/logoutput。txt *:E

If there's too much junk in your log right now, try clearing it first.

如果现在你的日志中有太多的垃圾,试着先清除它。

$adb shell logcat -c

亚洲开发银行美元壳logcat - c

Then try running your app then logcat again.

然后再尝试运行你的应用程序,然后再次登录。

#21


2  

For an alternate crash reporting/exception tracking service check out Raygun.io - it's got a bunch of nice logic for handling Android crashes, including decent user experience when plugging it in to your app (two lines of code in your main Activity and a few lines of XML pasted into AndroidManifest).

对于一个备用的崩溃报告/异常跟踪服务,请查看Raygun。io——在处理Android崩溃时,它有很多不错的逻辑,包括在你的应用程序(你的主要活动中有两行代码,以及几行XML粘贴到AndroidManifest中)时的良好用户体验。

When your app crashes, it'll automatically grab the stack trace, environment data for hard/software, user tracking info, any custom data you specify etc. It posts it to the API asynchronously so no blocking of the UI thread, and caches it to disk if there's no network available.

当您的应用程序崩溃时,它会自动抓取堆栈跟踪、硬/软件环境数据、用户跟踪信息、您指定的任何自定义数据等。它会异步地将其发送到API,这样就不会阻塞UI线程,如果没有可用的网络,就将其缓存到磁盘。

Disclaimer: I built the Android provider :)

免责声明:我创建了Android供应商:)

#22


2  

There is this android library called Sherlock. It gives you the full report of crash along with device and application information. Whenever a crash occurs, it displays a notification in the notification bar and on clicking of the notification, it opens the crash details. You can also share crash details with others via email or other sharing options.

有一个叫做夏洛克的安卓图书馆。它提供了与设备和应用程序信息一起崩溃的完整报告。当发生崩溃时,它会在通知栏中显示通知并单击通知,它将打开崩溃的详细信息。您还可以通过电子邮件或其他共享选项与他人共享崩溃细节。

Installation

安装

android {
    dataBinding {
      enabled = true
    }
}

compile('com.github.ajitsing:sherlock:1.0.0@aar') {
    transitive = true
}

Demo

演示

如何从Android应用程序获取垃圾数据?

#23


2  

Now a days Firebase Crash reports are very popular and easier to use. Please refer following link for more information: Firebase Crash Reporting

现在,Firebase的崩溃报告非常流行,并且更容易使用。更多信息请参考以下链接:Firebase崩溃报告。

Hope it will help you.

希望它能帮到你。

#24


1  

Just Started to use ACRA https://github.com/ACRA/acra using Google Forms as backend and it's very easy to setup & use, it's the default.

开始使用谷歌格式的ACRA https://github.com/ACRA/acra作为后端,它很容易设置和使用,这是默认的。

BUT Sending reports to Google Forms are going to be deprecated (then removed): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google-Form-Spreadsheet-usage

但是,将报告发送到谷歌表单将被废弃(然后删除):https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/acra/acra/wiki/notification -on-Google- form - spreadsheet -usage。

Anyway it's possible to define your own sender https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender you can give a try to email sender for example.

无论如何,你可以定义你自己的发送者https://github.com/acra/acra/acra/wiki/advancedusage #wiki-Implementing_your_own_sender你可以尝试发送电子邮件发送者。

With minimum effort it's possible to send reports to bugsense: http://www.bugsense.com/docs/android#acra

通过最小的努力,可以将报告发送给bugsense: http://www.bugsense.com/docs/android#acra。

NB The bugsense free account is limited to 500 report/month

NB免费帐户被限制在500报告/月。

#25


1  

Late to the party, I support and believe ACRA is the best option among all. Its easy to setup and configure. I have created a detailed guide with inputs from all over to fetch the crash report using ACRA and mail the same to my email address using MandrillAp.

在晚会上,我支持并相信ACRA是最好的选择。它易于设置和配置。我已经创建了一个详细的指南,其中包括使用ACRA来获取崩溃报告,并使用MandrillAp将相同的邮件发送到我的电子邮件地址。

Link to post: https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

帖子链接:https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

Link to sample project on github: https://github.com/ayushhgoyal/AcraSample

链接到github上的示例项目:https://github.com/ayushhgoyal/AcraSample。

#26


1  

I'm one of the founders of Bugsnag which we designed for exactly this purpose. Bugsnag automatically captures unhandled exceptions in Android apps and sends them to our dashboard, where you can prioritize fixes and dive into diagnostic information.

我是bugblock的创始人之一,我们正是为这个目的而设计的。在Android应用程序中,bugcatch自动捕获未处理的异常,并将它们发送到我们的仪表板,在那里,您可以对修复进行优先级排序,并深入到诊断信息中。

Here are some important things to consider when selecting or building a crash reporting system, along with some code snippets:

在选择或构建崩溃报告系统时,需要考虑一些重要的事情,以及一些代码片段:

  • Detects unhandled exceptions automatically (example code)
  • 自动检测未处理的异常(示例代码)
  • Collects diagnostic data such as memory usage, device info, etc (example code)
  • 收集诊断数据,如内存使用、设备信息等(示例代码)
  • Effectively groups crashes together by root cause
  • 有效的分组由根本原因一起崩溃。
  • Allows you to track actions the user took before each crash to help reproduce (example code)
  • 允许您跟踪用户在每次崩溃前采取的操作以帮助复制(示例代码)

If you want to see some best practices around crash handling/reporting on Android you can check out the full source code for Bugsnag's crash reporting library which is fully open source, feel free to tear this apart and use it in your own applications!

如果您希望看到关于Android的崩溃处理/报告的一些最佳实践,您可以查看bugcatch的崩溃报告库的完整源代码,它是完全开源的,您可以在自己的应用程序中使用它。

#27


0  

If your app is being downloaded by other people and crashing on remote devices, you may want to look into an Android error reporting library (referenced in this SO post). If it's just on your own local device, you can use LogCat. Even if the device wasn't connected to a host machine when the crash occurred, connected the device and issuing an adb logcat command will download the entire logcat history (at least to the extent that it is buffered which is usually a loooot of log data, it's just not infinite). Do either of those options answer your question? If not can you attempt to clarify what you're looking for a bit more?

如果你的应用程序被其他人下载并在远程设备上崩溃,你可能想要查看一个Android错误报告库(在这篇文章中引用)。如果只是在本地设备上,可以使用LogCat。即使设备没有连接到主机,当崩溃发生时,连接设备并发出adb logcat命令将下载整个logcat历史(至少在它被缓冲的程度上,这通常是一个日志数据的loooot,它不是无限的)。这些选项中有哪一个能回答你的问题?如果不能,你可以试着澄清一下你想要的是什么吗?

#28


0  

Flurry analytics gives you crash info, hardware model, android version and live app usage stats. In the new SDK they seem to provide more detailed crash info http://www.flurry.com/flurry-crash-analytics.html.

Flurry analytics提供了崩溃信息、硬件模型、android版本和实时应用程序数据。在新的SDK中,他们似乎提供了更详细的崩溃信息:http://www.flurry.com/flurry-crash-analytics.html。

#29


0  

Google changed how much crash reports you actually get. Previously you only got manual reported bug reports.

谷歌改变了你实际得到的崩溃报告。以前只有手动报告的bug报告。

Since the last developer conference and the introducation of Android Vitals you also get crash reports from users which have enabled to share diagnostics data.

自从上次开发人员会议和Android Vitals的介绍之后,您还可以从用户那里获取崩溃报告,这些用户可以共享诊断数据。

You'll see all crashes collected from Android devices whose users have opted in to automatically share usage and diagnostics data. Data is available for the previous two months.

您将看到从Android设备收集到的所有崩溃,这些设备的用户选择了自动共享使用和诊断数据。数据可在前两个月使用。

View crashes & application not responding (ANR) errors

视图崩溃和应用程序没有响应(ANR)错误。