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

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

Solutions Collecting From Web of "Как получить данные об авариях из моего приложения Android?"

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

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

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

Для примеров приложений и отладки я использую простое решение, которое позволяет мне написать stacktrace на SD-карту устройства и / или загрузить его на сервер. Это решение было основано на http://code.google.com/p/android-remote-stacktrace (в частности, части с сохранением на устройстве и загрузке на сервер), и я думаю, что он решает проблему, упомянутую Soonil , Это не оптимально, но оно работает, и вы можете улучшить его, если хотите использовать его в производственном приложении. Если вы решите загрузить стоп-трассы на сервер, вы можете использовать PHP-скрипт (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"); ?> 

Вы также можете попробовать BugSense . BugSense собирает и анализирует все отчеты о сбоях и дает вам осмысленные и визуальные отчеты. Это бесплатно, и это всего лишь 1 строка кода для интеграции.

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

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

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

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

Эти исключения можно обрабатывать с помощью Thread.setDefaultUncaughtExceptionHandler() , однако это, похоже, 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 отключить компонент, с которым это произошло, поэтому я через некоторое время отказался от него.

Хорошо, я посмотрел предоставленные образцы из 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-карту.

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

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

Попробуйте Crashlytics . Это даст глубокое понимание всех сбоев на всех устройствах, имеющих ваше приложение, и отправит вам уведомление по электронной почте. И лучшая часть – это его полная свобода использования.

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

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

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

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

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

 String stackTrace = Log.getStackTraceString(exception); 

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

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

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

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

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

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

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

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

Требуемые шаги:

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

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

2nd) используйте эту переопределенную версию класса 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(); } } 

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

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

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

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

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

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

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

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

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

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

$adb shell logcat -c

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

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

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

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

Просто начал использовать 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 -форма-Spreadsheet-использование

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

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

NB Бесплатная учетная запись bugsense ограничена 500 отчетами / месяцами

Поздно к партии, я поддерживаю и верю, что 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

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

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

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

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

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

Монтаж

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

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

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

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

http://www.appbrain.com/stats/libraries/tag/crash-reporting/android-crash-reporting-libraries

Веб-сайт приложения

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

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

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

В настоящее время отчеты Firebase Crash очень популярны и проще в использовании. Для получения дополнительной информации см. Следующую ссылку: https://firebase.google.com/docs/crash/.

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

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

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

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

https://support.google.com/googleplay/android-developer/answer/6083203