Как получить данные о сбое из моего приложения для Android?


737

Как я могу получить данные о сбоях (по крайней мере, следы стека) из моего приложения для Android? По крайней мере, при работе с моим собственным устройством, полученным по кабелю, но в идеале из любого экземпляра моего приложения, работающего на дикой природе, чтобы я мог улучшить его и сделать его более надежным.


10
Проверьте это: github.com/tomquist/Android-Error-Reporter
Том

Я вижу, что это отправляет отчет на удаленный сервер. Это может также зарегистрировать исключение в локальный файл?

1
Отчет о сбоях
gdonald

Похоже, что этот вариант более надежный. Как быть, если отчет не загружается после всех повторных попыток, может ли он записать его в файл или в sqlite db?
JPM

Ответы:


354

Вы можете попробовать библиотеку ACRA (Application Crash Report для Android) :

ACRA - это библиотека, позволяющая Android-приложению автоматически публиковать отчеты о сбоях в форме GoogleDoc. Он предназначен для разработчиков приложений для Android, чтобы помочь им получать данные из своих приложений в случае сбоя или неправильного поведения.

Его легко установить в приложении, он легко настраивается и не требует размещения серверного скрипта где-либо ... отчеты отправляются в электронную таблицу Google Doc!


8
Это легко настроить и использовать. Рекомендовано для использования перед началом рынка, и даже, возможно, после.
mxcl

1
Начал использовать его, и это несравнимо лучше, чем сообщение об ошибке в Flurry, которое я имел раньше, или домашнее, с которого я начал. Пока что меня топят на "акре".
Адриан Спиней

8
Большим преимуществом acra является возможность использовать API Google для простого анализа и визуализации данных, см. Пример на jberkel.github.com/sms-backup-plus/acra-analysis .
Ян Беркель

3
Кажется очень нестабильным для меня. Сам ACRA аварийно завершил работу и отправил отчет о сбое, а не сбой связанного приложения. -1
Сандор

19
Документы Google в качестве бэкэнда больше не поддерживаются
eliocs

305

Для примеров приложений и в целях отладки я использую простое решение, которое позволяет мне записать трассировку стека на SD-карту устройства и / или загрузить ее на сервер. Это решение было вдохновлено Project android-remote-stacktrace (в частности, частями сохранения на устройство и загрузки на сервер), и я думаю, что оно решает проблему, упомянутую Soonil. Это не оптимально, но работает, и вы можете улучшить его, если хотите использовать его в производственном приложении. Если вы решили загрузить трассировки стека на сервер, вы можете использовать php script ( index.php) для их просмотра. Если вам интересно, вы можете найти все источники ниже - один java-класс для вашего приложения и два дополнительных php-скрипта для сервера, на котором размещены загруженные стековые трассировки.

В контексте (например, основной вид деятельности), позвоните

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

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

<?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

<?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");
?>

9
Я думаю, что это вызовет правовые проблемы в некоторых штатах / странах
Сетзамора

5
ПРИМЕЧАНИЕ: HttpPost httpPost = new HttpPost(url);теперь вы должны быть в асинхронной задаче (или обработчике ... в отдельном потоке), если вы нацелены на Honeycomb или более позднюю
Bryan Denny

4
@ Джозет, что за юридические вопросы и почему?
Вареварао

2
@varevarao Правовые проблемы (возможно), потому что вы отправляете конфиденциальную информацию об устройстве без согласия пользователя, используя функцию этого кода «Отправить на сервер».
caw

2
Кажется, что defaultExceptionHandler сохраняется во время восстановления активности. Я обновил ответ, чтобы установить значение по умолчанию, только если пользовательский обработчик еще не установлен. Без этого каждый обработчик удерживает и вызывает предыдущий, вплоть до исходного. Это вызывает проблемы с дублированием журнала, а также проблемы утечки памяти.
Дэйв Макклелланд,

57

Вы также можете попробовать [BugSense] Причина: перенаправление спама на другой URL . BugSense собирает и анализирует все отчеты о сбоях и дает вам значимые и наглядные отчеты. Это бесплатно и это только 1 строка кода для интеграции.

Отказ от ответственности: я соучредитель


4
Я попробовал BugSense и его классно. Простой и свежий интерфейс, очень быстрый тоже. Нет глупых черт Легко увидеть наиболее частые сбои, а также копаться в трассировке стека.
Виджет

В последнее время мы делаем гораздо больше, чем просто отчеты о
сбоях,

Попробовал это. Ошибки работали, хотя трассировка стека не слишком полная, данные о сбоях в реальном времени не поступали. Режим отладки не работает. Я пошел по пути инициализации-один раз из класса Application (хотя это имеет смысл для большинства случаев). У BugSense есть удивительная панель инструментов, такая позорная, что по какой-то причине отчеты о сбоях не работают, и символика не находится на свободном уровне. Мне потребовалось 5 минут, чтобы установить GetSentry, и он просто работал из коробки для Android с этим универсальным клиентом: github.com/joshdholtz/Sentry-Android
albertpeiro

3
BugSense прост и легко интегрируется. НО ЭТО СЛИШКОМ ДОРОГО. Мы можем достичь той же функциональности определения ошибок, используя аналитику Flurry и Parse. Оба они бесплатны и легко интегрируются.
Venkat

44

В Android 2.2 теперь можно автоматически получать отчеты о сбоях из приложений Android Market:

Новая функция отчетов об ошибках для приложений Android Market позволяет разработчикам получать отчеты о сбоях и блокировать отчеты от своих пользователей. Отчеты будут доступны после входа в свою учетную запись издателя.

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


Я думаю, что это не просто 2.2, а просто новая рыночная функция, которую предлагает Google. Несколько дней назад я получил отчет о сбое, и в моем приложении не должно быть устройства froyo.
Януш

1
@Janusz Ты уверен? уже есть релизы Froyo для Nexus One, не считая тех Googlers, которые уже давно запускают Froyo.
Пупено

По крайней мере, должно быть обновление в версии на телефоне, даже просто еще одна версия, но как это должно работать в противном случае?
RoflcoptrException

Я не знаю, если отчеты были отправлены в Google раньше. Отчет несколько странный, потому что Google показывает пользовательский интерфейс для отправки своих видео, и это должно быть изменение в ОС, а не только на рынке. Но это говорит: Платформы 1 сообщают отчеты в неделю, и дроид не должен быть на фройо.
Януш

1
Код кнопки «Сообщить» был в AOSP некоторое время, и Ромен Гай (смутно) ответил на вопрос об этом здесь пару месяцев назад.
Кристофер Орр

30

С этими исключениями можно справиться 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");
    }
}

Тем не менее, даже с перебрасыванием исключений, я не мог получить желаемое поведение, то есть регистрировать исключение, все еще позволяя Android завершить работу компонента, в котором это произошло, поэтому я через некоторое время отказался от него.


Почему вы перебрасываете только непроверенные исключения? Мне кажется, вы должны повторно выбросить все исключения.
MatrixFrog

Похоже, кто-то преуспел с вашим подходом: jyro.blogspot.com/2009/09/crash-report-for-android-app.html
MatrixFrog

1
Хитрость заключается в том, чтобы получить предыдущий UncaughtExceptionHandler по умолчанию и обработать исключение для этого объекта после того, как вы закончили сообщать об исключении.
Том

Является ли Constants.TAGчастью платформы Android? Впервые увидев это. Не могу найти это.
Haroun Hajem

1
@HarounHajem Нам нужно определить свои собственные.
KYHSGeekCode

22

Я вижу, что вопрос слишком старый, и надеюсь, что мой ответ будет полезен для других, имеющих такую ​​же проблему ...

Дайте Crashlytics попробовать. Он позволит лучше понять все сбои на всех устройствах, на которых установлено ваше приложение, и отправит вам уведомление по электронной почте. И самое приятное, что он полностью бесплатен в использовании.


21

Хорошо, я посмотрел предоставленные образцы от Rrainn и Soonil и нашел решение, которое не мешает обработке ошибок.

Я изменил CustomExceptionHandler, чтобы он сохранял исходный UncaughtExceptionHandler из потока, с которым мы связываем новый. В конце нового «uncaughtException» - метода я просто вызываю старую функцию, используя сохраненный UncaughtExceptionHandler.

В классе DefaultExceptionHandler вам нужен sth. нравится:

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();
  }
}

С этой модификацией кода на http://code.google.com/p/android-remote-stacktrace у вас будет хорошая рабочая база для входа в поле на ваш веб-сервер или на SD-карту.


19

Консоль разработчиков Google Play фактически дает вам трассировку стека от тех приложений, которые потерпели крах и отправили отчеты, а также имеет очень хорошие диаграммы, чтобы помочь вам увидеть информацию, см. Пример ниже:

введите описание изображения здесь


2
Каким образом пользователи отправляют отчеты или как это работает, если ваше приложение отсутствует в магазине игр, можете ли вы сделать это для целей тестирования?
Lion789

Знаете ли вы, что существует какой-либо проект Android с открытым исходным кодом, который публикует свои отчеты о сбоях?
Джастин Сиви

1
Обратите внимание, что здесь будут отображаться только сбои, ANR, о которых пользователи решили сообщить
sojin

Да, действительно, в любом случае, когда у вас большая база пользователей, у вас есть много возможностей для сообщений обо всех сбоях, а также о сбоях, и сообщения ANR здесь будут самыми важными, потому что люди будут сообщать о них больше раз, так что вы сможете отфильтруйте и исправьте их в этом приоритете (больше отчетов = более важная ошибка), а (без отчетов = не эта критическая ошибка).
Eefret

18

Я использую Crittercism для своих приложений для Android и iOS - слышал о них на techcrunch. Очень доволен ими до сих пор!


К вашему сведению: отчеты о сбоях со стороны NDK не являются частью базового плана и относятся к разделу «Расширенные отчеты о сбоях». Смотрите: crittercism.com/pricing
ахаш

1
Я только что проверил отчет NDK о Twitter.Crashlytics в Twitter. Довольно неплохо (в первый день использования), когда я выпускаю, мне понадобился дополнительный шаг, чтобы поместить отображение в их систему, чтобы трассировки стека выглядели хорошо, но пригвоздили ошибка NDK, которую я использовал для проверки (сделал стратегический вызов abort (); во всем С ++ он обеспечил трассировку стека для тестирования)
Hunter-Orionnoir

14

Я сделал свою собственную версию здесь: http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html

Это в основном то же самое, но я использую почту, а не http-соединение для отправки отчета, и, что более важно, я добавил в свой отчет некоторую информацию, такую ​​как версия приложения, версия ОС, модель телефона или доступная память. ,


11

используйте это, чтобы поймать детали исключения:

String stackTrace = Log.getStackTraceString(exception); 

сохранить это в базе данных и вести журнал.


Как получить доступ к этой базе данных, приведите какой-нибудь пример. пожалуйста, если можете. спасибо в advacne
Раджендра Верма

8

Вы также можете использовать для этого целый (простой) сервис, а не только библиотеку. Наша компания только что выпустила сервис для этого: http://apphance.com .

Он имеет простую библиотеку .jar (для Android), которую вы добавляете и интегрируете за 5 минут, а затем библиотека собирает не только информацию о сбоях, но и журналы из запущенного приложения, а также позволяет вашим тестировщикам сообщать о проблемах прямо с устройства, включая весь контекст (ротация устройства, подключено ли оно к вайфай или нет и многое другое). Вы можете просматривать журналы с помощью очень удобной и полезной веб-панели, где вы можете отслеживать сессии с вашим приложением, сбои, журналы, статистику и многое другое. Сервис находится в стадии закрытого бета-тестирования, но вы можете запросить доступ, и мы предоставим его вам очень быстро.

Отказ от ответственности: я технический директор Polidea и один из создателей сервиса.


7

Спасибо за ресурсы, Stackoverflowпомогающие мне найти этот ответ.

Вы можете найти свои удаленные отчеты о сбоях Android прямо в вашей электронной почте . помните, что вы должны поместить свою электронную почту в класс CustomExceptionHandler .

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

Необходимые шаги:

1) в onCreate вашей деятельности используйте этот раздел вашего кода.

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

2) использовать эту переопределенную версию класса CustomExceptionHandler (rrainn), согласно моему phpscript.

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();

    }
}

6

В наши дни отчеты Firebase Crash очень популярны и их легче использовать. Пожалуйста, обратитесь по следующей ссылке для получения дополнительной информации: Firebase Crash Reporting

Надеюсь, это поможет вам.


5

Это очень грубо, но можно запускать logcat где угодно, поэтому быстрый и грязный хак можно добавить в любой блок catch getRuntime().exec("logcat >> /sdcard/logcat.log");


Это дало бы вывод журнала всех приложений. Фильтрация по тэгу приложения может быть приемлемой, но не думаю, что это будет хорошим способом, поскольку записи могут быть накопительными. Очистка вывода logcat после каждой записи может решить эту проблему.
bschandramohan

5

Существует инструмент, который называется Fabric, это инструмент анализа сбоев, который позволит вам получать отчеты о сбоях, когда приложение развернуто в реальном времени и в процессе разработки. Добавление этого инструмента в ваше приложение также было простым. Когда происходит сбой приложения, отчет о сбое можно просмотреть на панели инструментов fabric.io. Отчет был пойман автоматически. Он не будет запрашивать у пользователя разрешения. Хочет ли он / она отправить отчет об ошибке / сбое. И это совершенно бесплатно ... https://get.fabric.io/


5

Google Firebase - это новейший (2016) способ Google предоставить вам данные о сбоях / ошибках на вашем телефоне. Включите его в файл build.gradle:

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

Фатальные сбои регистрируются автоматически, не требуя ввода данных пользователем, и вы можете также регистрировать нефатальные сбои или другие события, например, так:

try
{

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

5

Есть эта андроид библиотека под названием Шерлок . Это дает вам полный отчет о сбое вместе с информацией об устройстве и приложении. Всякий раз, когда происходит сбой, он отображает уведомление в панели уведомлений и при щелчке уведомления открывает подробности сбоя. Вы также можете поделиться информацией о сбое с другими по электронной почте или с помощью других опций.

Установка

android {
    dataBinding {
      enabled = true
    }
}

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

демонстрация

введите описание изображения здесь


5

Хотя многие ответы на этой странице полезны, им легко устареть. Веб-сайт AppBrain собирает статистику, которая позволяет вам найти самое популярное на сегодняшний день решение для отчетов о сбоях:

Библиотеки отчетов об ошибках Android

сайт приложения мозг

Вы можете видеть, что на момент публикации этой картинки Crashlytics используется в 5,24% приложений и 12,38% установок.


4

Мы используем нашу доморощенную систему внутри компании, и она нам очень помогает. Это библиотека Android, которая отправляет отчеты о сбоях на сервер и сервер, который получает отчеты и выполняет аналитику. Сервер группирует исключения по имени исключения, трассировке стека, сообщению. Это помогает определить наиболее важные проблемы, которые необходимо исправить. Наш сервис находится в публичной бета-версии, так что каждый может попробовать его. Вы можете создать учетную запись на http://watchcat.co или просто посмотреть, как она работает, используя демонстрационный доступ http://watchcat.co/reports/index.php?demo .


3

Если вы хотите получить ответы сразу, вы можете использовать logcat

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

Если в вашем журнале слишком много мусора, попробуйте сначала очистить его.

$adb shell logcat -c

Затем попробуйте запустить приложение и снова войти в систему.


Разве это не требует подключения устройства к ПК (например, с помощью кабеля)?
Джерард

3

Я нашел еще одно отличное веб-приложение для отслеживания сообщений об ошибках.

https://mint.splunk.com/

Небольшое количество шагов для настройки.

  1. Войдите или зарегистрируйтесь и настройте по ссылке выше. Как только вы закончите создание приложения, они предоставят строку для настройки, как показано ниже.
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. Добавьте следующее в build.gradl приложения.
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. Добавьте код, который мы скопировали выше, и добавляйте его к каждому виду деятельности.

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

Вот и все. Вы авторизуетесь и заходите на панель приложения, вы получите все отчеты об ошибках.

Надеюсь, это кому-нибудь поможет.


Сколько это стоит?
user2966445

2

Чтобы узнать об альтернативных отчетах о сбоях / отслеживании исключений, просмотрите Raygun.io - у него есть куча приятной логики для обработки сбоев Android, включая приличный пользовательский интерфейс при подключении его к вашему приложению (две строки кода в основной активности и несколько строки XML, вставленные в AndroidManifest).

Когда ваше приложение аварийно завершает работу, оно автоматически извлекает трассировку стека, данные о среде для аппаратного / программного обеспечения, информацию об отслеживании пользователя, любые пользовательские данные, которые вы указываете и т. Д. Оно отправляет их в API асинхронно, поэтому не блокирует поток пользовательского интерфейса, и кэширует его на диск, если нет доступной сети.

Отказ от ответственности: я построил Android-провайдер :)


1

Просто начали использовать ACRA https://github.com/ACRA/acra, используя Google Forms в качестве бэкэнда, и его очень легко настроить и использовать, это по умолчанию.

НО отправка отчетов в формы Google устареет (затем будет удалена): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google -форма-Spreadsheet-использование

В любом случае можно определить своего собственного отправителя https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender, который вы можете попробовать отправить по электронной почте отправителю, например.

С минимальными усилиями можно отправлять отчеты на bugsense: http://www.bugsense.com/docs/android#acra

Внимание : бесплатный аккаунт на bugsense ограничен 500 отчетами в месяц


1

В конце вечеринки я поддерживаю и считаю, что ACRA - лучший вариант среди всех. Его легко установить и настроить. Я создал подробное руководство со входами со всех концов, чтобы получить отчет о сбое с помощью ACRA и отправить его на мой адрес электронной почты с помощью MandrillAp.

Ссылка на пост: https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

Ссылка на пример проекта на github: https://github.com/ayushhgoyal/AcraSample


1

Я один из основателей Bugsnag, который мы разработали именно для этой цели. Bugsnag автоматически фиксирует необработанные исключения в приложениях Android и отправляет их на нашу панель инструментов, где вы можете расставить приоритеты по исправлениям и погрузиться в диагностическую информацию.

Вот несколько важных моментов, которые следует учитывать при выборе или создании системы отчетов о сбоях, а также некоторые фрагменты кода:

  • Обнаруживает необработанные исключения автоматически ( пример кода )
  • Собирает диагностические данные, такие как использование памяти, информация об устройстве и т. Д. ( Пример кода )
  • Эффективно группирует сбои вместе по основной причине
  • Позволяет отслеживать действия, предпринятые пользователем перед каждым сбоем, чтобы помочь воспроизвести ( пример кода )

Если вы хотите ознакомиться с некоторыми лучшими практиками в области обработки аварий / отчетов об ошибках на Android, вы можете проверить полный исходный код библиотеки отчетов о сбоях Bugsnag с полностью открытым исходным кодом, не стесняйтесь разбирать ее на части и использовать в своих собственных приложениях!


0

Если ваше приложение загружается другими людьми и происходит сбой на удаленных устройствах, вы можете заглянуть в библиотеку отчетов об ошибках Android (упоминается в этом сообщении SO ). Если это только на вашем локальном устройстве, вы можете использовать LogCat. Даже если устройство не было подключено к хост-машине, когда произошел сбой, подключенное устройство и с помощью команды adb logcat загрузит всю историю logcat (по крайней мере, в той степени, в которой оно буферизовано, что обычно представляет собой загрузку данных журнала). просто не бесконечно). Ответят ли какие-либо из этих вариантов на ваш вопрос? Если нет, можете ли вы попытаться уточнить, что вы ищете немного больше?


0

Аналитика Flurry дает вам информацию о сбоях, модель оборудования, версию Android и статистику использования приложений в реальном времени. В новом SDK они предоставляют более подробную информацию о сбоях http://www.flurry.com/flurry-crash-analytics.html .


8
Flurry ограничен только таким количеством символов и не дает никаких номеров строк или аналогичных.
Брайан Денни

0

Google изменил, сколько отчетов о сбоях вы получаете. Ранее вы получали только ручные отчеты об ошибках.

Со времени последней конференции разработчиков и внедрения Android Vitals вы также получаете отчеты о сбоях от пользователей, которые имеют возможность обмениваться диагностическими данными.

Вы увидите все сбои, собранные на устройствах Android, пользователи которых включили автоматический обмен данными об использовании и диагностике. Данные доступны за предыдущие два месяца.

Просмотр сбоев и ошибок приложения (ANR)


logcat говорит, что в /data/user/0/com.<myappname>/cache/WebView/Crash Report / <GUUID> .dmp есть файл дампа аварийного дампа, но устройство не рутировано, и я не могу понять, узнать, как получить доступ к этому файлу!
Майкл

0

Вы можете сделать это прямо в Android Studio. Просто подключите телефон, запустите приложение, дайте ему упасть, и вы сможете просматривать трассировку стека прямо в Android Studio.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.