Як я можу отримати дані про збої з програми Android?


737

Як я можу отримати дані про збої (принаймні сліди стека) з додатка Android? Принаймні, коли я працюю над власним пристроєм, який витягується за допомогою кабелю, але в ідеалі з будь-якого примірника моєї програми, що працює на природі, щоб я міг покращити його та зробити його більш міцним.



Я бачу, що це надсилає звіт на віддалений сервер. Чи може він також записати виняток у локальний файл?

1
Звіт про
збої в програмі

Цей вигляд виглядає більш надійним, а як бути, якщо звіт не вдасться завантажити після всіх повторних спроб, чи зможе він увійти у файл або sqlite db?
JPM

Відповіді:


354

Ви можете спробувати бібліотеку ACRA (Звіт про збої додатків для Android) :

ACRA - це бібліотека, яка дозволяє додатку Android автоматично розміщувати свої звіти про аварійне завершення у формі GoogleDoc. Він орієнтований на розробників програм для Android, щоб допомогти їм отримувати дані від своїх програм, коли вони виходять з ладу або поводяться помилково.

Це легко встановити у вашому додатку, легко настроюється і не вимагає розміщення сценарію сервера в будь-якому місці ... звіти надсилаються на електронну таблицю Google Doc!


8
Це легко встановити та використовувати. Рекомендовано для використання на місцях перед продажем, і навіть можливо після.
mxcl

1
Почав використовувати його, і це незрівнянно краще, ніж повідомлення про помилки в «Шкварі», які я мав раніше, або домашнє, з якого я почав. Поки що я начепився на "акрі".
Адріан Шпіней

8
Велика перевага ACRA є можливістю використовувати Google API , легко аналізувати і візуалізувати дані, см 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
Я думаю, це спричинить юридичні проблеми в деяких штатах / країнах
setzamora

5
ПРИМІТКА. HttpPost httpPost = new HttpPost(url);Якщо ви орієнтуєтесь на сотову версію або пізніше, ви повинні мати завдання з асинхронізацією (або обробником ... окремою темою)
Брайан Денні

4
@Joset, які юридичні питання і чому?
varevarao

2
@varevarao Юридичні проблеми (можливо), оскільки ви надсилаєте конфіденційну інформацію про пристрої без згоди користувача, використовуючи функцію "Надіслати на сервер" цього коду.
каре

2
Здається, за замовчуванням ExxceptionHandler зберігається в режимі відпочинку. Я оновив відповідь, щоб встановити типово лише те, якщо спеціальний обробник ще не встановлений. Без цього кожен обробник утримує та дзвонить попередньому, аж до оригіналу. Це спричиняє проблеми із дублюванням журналу, а також проблеми з витоком пам'яті.
Дейв МакКлелленд

57

Ви також можете спробувати [BugSense] Причина: Переадресація спаму на інший URL . BugSense збирає та аналізує всі звіти про збої та надає змістовні та наочні звіти. Це безкоштовно і це лише 1 рядок коду для інтеграції.

Відмова: Я є співзасновником


4
Я спробував BugSense і його приголомшливий. Простий і свіжий інтерфейс, дуже швидкий. Немає дурної риси здуття. Легко побачити найчастіші збої, а також зануритись у стек.
vidstige

Останнім часом ми робимо набагато більше, ніж просто звітування про
збої,

Спробував це. Помилки працювали, хоча стек-трасування не надто повне, дані про аварії в реальному часі не надходили. Режим налагодження не працював. Хоча я пішов шляхом ініціалізації одного разу з класу Application (що є сенсом для більшості випадків). BugSense має дивовижну інформаційну панель, така ганьба, що з певних причин звіти про збої не працюють, а символізація не є у вільному рівні. Щоб встановити GetSentry, у мене вийшло 5 хвилин, і він просто вийшов з коробки для Android із цим клієнтом загального призначення: github.com/joshdholtz/Sentry-Android
albertpeiro

3
BugSense простий і простий в інтеграції. АЛЕ ВІД ТЕХНІЧНО. Ми можемо досягти однакових функцій відчуття помилок, використовуючи Flurry analytics та 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, не рахуючи Googleрсів, які певний час керували Froyo.
pupeno

Принаймні, у телефоні повинно бути оновлення версії, навіть її лише чергова редакція, але як це має працювати інакше?
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 тут будуть найважливішими, адже люди повідомлятимуть про них більше разів, так що ви можете фільтруйте та виправляйте їх у цьому пріоритеті (більше звітів = більш важлива помилка), поки (немає звіту = не той критичний помилка)
Ефрет

18

Я використовував Crittercism для моїх додатків для Android та iOS - чув про них у techcrunch. Досить задоволений ними поки що!


FYI: звіти про збої з боку NDK не є частиною основного плану, і вони підпадають під "Розширене звітування про збої". Дивіться: krittercism.com/pricing
ахаш

1
Я щойно перевірив звітність про NDK на Twitter Fabric.io Crashlytics ... досить чудово (на 1 день використання), мені потрібен додатковий крок, коли я відпускаю, щоб помістити картографування в їхню систему, щоб сліди стека виглядали добре, але це прибито помилка NDK я використовував для тесту (зроблена «Перервати ();" виклик стратегічно по всій C ++ і при умови трасування стека для тестування.
Хантер-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 хвилин, а потім бібліотека збирає не тільки інформацію про збої, але й журнали запущеного додатку, а також дозволяє тестерам повідомляти про проблеми безпосередньо з пристрою - включаючи весь контекст (обертання пристрою, незалежно від того, підключено він до wifi чи ні та багато іншого). Ви можете переглянути журнали за допомогою дуже приємної та корисної веб-панелі, де ви можете відстежувати сеанси за допомогою програми, збої, журнали, статистику тощо. Послуга зараз знаходиться у закритій стадії тестування бета-версії, але ви можете надіслати запит на доступ, і ми дамо вам це дуже швидко.

Відмова: Я є представником організації "Полідея" і є співавтором служби.


7

Дякую ресурсам, які Stackoverflowдопомагають мені знайти цю відповідь.

Ви можете знайти свої віддалені звіти про аварії Android безпосередньо у своєму електронному листі . пам’ятайте, що вам потрібно помістити електронну пошту в клас CustomExceptionHandler .

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

Необхідні кроки:

По-перше) у 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 де завгодно, тому швидкий і брудний злом - це додавання до будь-якого блоку лову getRuntime().exec("logcat >> /sdcard/logcat.log");


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

5

Існує інструмент під назвою тканина, це інструмент аналітики аварійних збоїв, який дозволить вам отримувати звіти про збої, коли програма розгорнута в прямому ефірі та під час розробки. Додавання цього інструменту до вашої програми було також простим. Коли ви завершите роботу програми, цей звіт про збій можна переглянути з вашої інформаційної панелі 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

Ми використовуємо нашу систему, яка вирощується вдома, всередині компанії, і вона нам дуже добре служить. Це андроїд-бібліотека, яка надсилає звіти про збої на сервер та сервер, який отримує звіти та робить певну аналітику. Сервери групують винятки за назвою винятку, стеком, повідомленням. Це допомагає виявити найважливіші проблеми, які потрібно виправити. Наш сервіс зараз знаходиться у відкритій бета-версії, тому кожен може спробувати його. Ви можете створити обліковий запис на веб- сайті 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");

Це воно. Ви увійдете в систему і перейдете на панель інструментів програми, ви отримаєте всі повідомлення про помилки.

Сподіваюся, це комусь допоможе.


Скільки це коштує?
користувач2966445

2

Служба альтернативного звітування про аварійну ситуацію / відстеження винятків перевіряйте Raygun.io - це купа приємної логіки поводження з аваріями на Android, включаючи пристойний досвід роботи користувачів під час підключення до програми (два рядки коду в основній діяльності та кілька рядки XML, вставлені в AndroidManifest).

Коли ваша програма вийде з ладу, вона автоматично захопить слід стека, дані про середовище для жорсткого / програмного забезпечення, інформацію про відстеження користувача, будь-які спеціальні дані, які ви вказуєте і т.д. на диск, якщо немає мережі.

Відмова: Я створив провайдера Android :)


1

Щойно почав використовувати ACRA https://github.com/ACRA/acra, використовуючи Google Forms як бекенд, і це дуже просто в налаштуванні та використанні, це за замовчуванням.

АЛЕ надсилання звітів у Google Forms буде застаріле (потім видалено): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google -Форм-використання електронних таблиць

У будь-якому разі можна визначити власного відправника 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 (принаймні, настільки, наскільки вона буферизована, як правило, це loooot даних журналу , це просто не безмежно). Чи відповідає один із цих варіантів на ваше запитання? Якщо ви не можете спробувати уточнити, що ви хочете трохи більше?


0

Штучна аналітика дає інформацію про збої, апаратну модель, версію Android та статистику використання додатків у реальному часі. У новому SDK вони, мабуть, надають більш детальну інформацію про збої http://www.flurry.com/flurry-crash-analytics.html .


8
Шквал обмежений лише такою кількістю символів і не дає номерів рядків чи подібних.
Брайан Денні

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.