Как получить данные об авариях из моего приложения Android?
Как я могу получить данные о сбоях (как минимум, трассировки стека) из моего приложения Android? По крайней мере, при работе на моем собственном устройстве, который извлекается по кабелю, но в идеале из любого экземпляра моего приложения, работающего на дикой природе, чтобы я мог улучшить его и сделать его более прочным.
Ответы
Ответ 1
Вы можете попробовать библиотеку ACRA (Application Crash Report for Android):
ACRA - это библиотека, позволяющая Android-приложения автоматически публиковать отчеты о сбоях в форме GoogleDoc. Он нацелен на разработчиков приложений Android, чтобы помочь им получить данные из своих приложений, когда они выходят из строя или ведут себя ошибочно.
Легко устанавливается в ваше приложение, настраивается и не требует, чтобы вы размещали сервер script где угодно... отчеты отправляются в электронную таблицу Google Doc!
Ответ 2
Для примеров приложений и отладки я использую простое решение, которое позволяет мне писать stacktrace на SD-карту устройства и/или загружать его на сервер. Это решение было основано на проекте android-remote-stacktrace (в частности, в компонентах save-to-device и upload-to-server), и я думаю, что он решает проблему, упомянутую 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");
?>
Ответ 3
Вы также можете попробовать BugSense. BugSense собирает и анализирует все отчеты о сбоях и дает вам осмысленные и визуальные отчеты. Он бесплатный, и для интеграции есть только 1 строка кода.
Отказ от ответственности: я являюсь соучредителем
Ответ 4
В Android 2.2 теперь можно автоматически получать отчеты о сбоях из приложений Android Market:
Новая функция сообщения об ошибках для Android Приложения на рынке позволяют разработчикам получать отчеты о сбоях и их пользователей. Отчеты будут доступны при входе в их учетной записи издателя.
http://developer.android.com/sdk/android-2.2-highlights.html
Ответ 5
Можно обрабатывать эти исключения с помощью 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, и это могло произойти, поэтому я отказался от него через некоторое время.
Ответ 6
Хорошо, я посмотрел на предоставленные образцы из rrainn и Soonil, и я нашел решение
что не испортит обработку ошибок.
Я изменил CustomExceptionHandler, поэтому он сохраняет исходный UncaughtExceptionHandler из Thread, который мы связываем с новым. В конце нового "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
у вас есть хорошая рабочая база для входа в поле на ваш веб-сервер или
сд-карта.
Ответ 7
Я использовал Crittercism для своих приложений для Android и iOS - слышал о них на techcrunch. Довольный ими до сих пор!
Ответ 8
Я вижу, что вопрос слишком стар, и надеюсь, что мой ответ будет полезен для других, имеющих ту же проблему...
Дайте Crashlytics. Это даст глубокое понимание всех сбоев на всех устройствах, имеющих ваше приложение, и отправит вам уведомление по электронной почте. И лучшая часть - это его полная свобода использования.
Ответ 9
Консоль Google Play Developers Console фактически предоставляет вам трассировки стека из тех приложений, которые разбились и отправили отчеты, а также очень хорошие диаграммы, которые помогут вам увидеть информацию, см. пример ниже:
Ответ 10
Я сделал свою собственную версию здесь:
http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html
Это в основном то же самое, но я использую почту, а не http-связь для отправки отчета, и, что более важно, я добавил некоторые данные, такие как версия приложения, версия ОС, модель телефона или доступная память для моего отчет...
Ответ 11
используйте это, чтобы просмотреть сведения об исключении:
String stackTrace = Log.getStackTraceString(exception);
сохранить это в базе данных и сохранить журнал.
Ответ 12
Вы также можете использовать для него целый (простой) сервис, а не только библиотеку. Наша компания только что выпустила сервис только для этого: http://apphance.com.
У него есть простая библиотека .jar(для Android), которую вы добавляете и интегрируете за 5 минут, а затем библиотека собирает не только информацию о сбоях, но также журналы из запущенного приложения, а также позволяет вашим тестировщикам сообщать о проблемах прямо с устройства - включая весь контекст (вращение устройства, подключено ли оно к Wi-Fi или нет). Вы можете просматривать журналы с помощью очень приятной и полезной веб-панели, где вы можете отслеживать сеансы с вашим приложением, сбои, журналы, статистику и многое другое.
Служба находится на закрытой стадии бета-тестирования, но вы можете запросить доступ, и мы дадим ее вам очень быстро.
Отказ от ответственности: я технический директор Polidea и соавтор сервиса.
Ответ 13
Спасибо, что ресурсы присутствуют в Stackoverflow
, помогая мне найти этот ответ.
Вы можете найти свои удаленные отчеты о сбоях Android непосредственно в свой адрес электронной почты. помните, что вы должны разместить свою электронную почту внутри класса CustomExceptionHandler.
public static String sendErrorLogsTo = "[email protected]" ;
Требуемые шаги:
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 = "[email protected]" ;
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();
}
}
Ответ 14
Это очень грубо, но можно запустить logcat в любом месте, поэтому быстрый и грязный взломать нужно добавить в любой блок catch getRuntime().exec("logcat >> /sdcard/logcat.log");
Ответ 15
Существует инструмент под названием fabric, это инструмент анализа сбоев, который позволит вам получать отчеты о сбоях, когда приложение развертывается в реальном времени и во время разработки.
Добавление этого инструмента в ваше приложение было простым.
Когда ваше приложение выйдет из строя, отчет о сбое можно просмотреть с панели инструментов fabric.io. thw отчет был уловлен автоматически. Он не будет запрашивать у пользователя разрешения. Хотите ли он отправить отчет об ошибке/сбое.
И это совершенно бесплатно...
https://get.fabric.io/
Ответ 16
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()));
}
Ответ 17
Мы используем нашу домашнюю систему внутри компании, и она нам очень помогает. Это андроидная библиотека, которая отправляет отчеты о сбоях на сервер и сервер, который получает отчеты и делает некоторые аналитики. Исключение групп серверов по имени исключения, stacktrace, message. Это помогает выявить наиболее важные проблемы, которые необходимо устранить.
Наш сервис находится в публичной бета-версии, поэтому каждый может попробовать. Вы можете создать учетную запись в http://watchcat.co или просто посмотреть, как она работает, используя демонстрационный доступ http://watchcat.co/reports/index.php?demo.
Ответ 18
Я нашел еще одно замечательное веб-приложение для отслеживания отчетов об ошибках.
https://mint.splunk.com/
Небольшое количество шагов для настройки.
- Войдите или зарегистрируйтесь и настройтесь, используя приведенную выше ссылку. После того, как вы создали приложение, они предоставят строку для настройки, как показано ниже.
Mint.initAndStartSession(YourActivity.this, "api_key");
- Добавьте в приложение build.gradl следующее.
android {
...
repositories {
maven { url "https://mint.splunk.com/gradle/"}
}
...
}
dependencies {
...
compile "com.splunk.mint:mint:4.4.0"
...
}
- Добавьте код, который мы скопировали выше, и добавим его в каждое действие.
Mint.initAndStartSession(YourActivity.this, "api_key" );
Что это. Вы входите в систему и переходите к панели приложений, вы получите все отчеты об ошибках.
Надеюсь, что это поможет кому-то.
Ответ 19
Существует эта андроидная библиотека, называемая Шерлок. Он дает вам полный отчет о сбоях, а также информацию об устройстве и приложении.
Всякий раз, когда происходит сбой, он отображает уведомление в панели уведомлений и при нажатии уведомления, он открывает детали сбоя. Вы также можете делиться деталями сбоев с другими пользователями по электронной почте или другим параметрам обмена.
Установка
android {
dataBinding {
enabled = true
}
}
compile('com.github.ajitsing:sherlock:[email protected]') {
transitive = true
}
Demo
Ответ 20
Хотя многие ответы на этой странице полезны, им легко устаревать. На веб-сайте AppBrain агрегируются статистические данные, которые позволяют найти наиболее популярное решение для отчетов о сбоях, которое является текущим:
Андроидальные отчеты об ошибках
Вы можете видеть, что во время публикации этого изображения Crashlytics используется в 5.24% приложений и 12.38% установок.
Ответ 21
Если вы хотите получить ответы сразу, вы можете использовать logcat
$adb shell logcat -f /sdcard/logoutput.txt *:E
Если в вашем журнале слишком много мусора, попробуйте сначала очистить его.
$adb shell logcat -c
Затем попробуйте запустить приложение, а затем снова запустите logcat.
Ответ 22
Для альтернативной службы отслеживания сбоев/отслеживания исключений проверьте Raygun.io - у нее есть куча приятной логики для обработки сбоев Android, в том числе достойный пользовательский интерфейс при подключении к вашему приложению (две строки кода в вашей основной деятельности и несколько строк XML, вставленных в AndroidManifest).
Когда ваше приложение выйдет из строя, оно автоматически захватит трассировку стека, данные о среде для жесткого/программного обеспечения, информацию о отслеживании пользователя, любые пользовательские данные, которые вы укажете и т.д. Он будет асинхронно размещать его в API, чтобы не блокировать поток пользовательского интерфейса, и кэширует его на диск, если нет сети.
Отказ от ответственности: я создал Android-провайдер:)
Ответ 23
Теперь отчеты Firebase Crash очень популярны и проще в использовании.
Для получения дополнительной информации см. Следующую ссылку:
Отчеты о сбоях Firebase
Надеюсь, это поможет вам.
Ответ 24
Просто начал использовать 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-Form-Spreadsheet-usage
В любом случае можно определить своего отправителя
https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender
вы можете попросить отправителя электронной почты, например.
С минимальными усилиями можно отправлять отчеты в bugsense:
http://www.bugsense.com/docs/android#acra
NB Бесплатная учетная запись bugsense ограничена 500 отчетами/месяцем
Ответ 25
Поздно к вечеринке я поддерживаю и верю, что 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
Ответ 26
Я один из основателей Bugsnag, который мы разработали именно для этой цели. Bugsnag автоматически фиксирует необработанные исключения в приложениях Android и отправляет их на нашу панель мониторинга, где вы можете определить приоритеты и погрузиться в диагностическую информацию.
Вот некоторые важные моменты, которые следует учитывать при выборе или создании системы отчетов о сбоях, а также некоторые фрагменты кода:
- Автоматически обнаруживает необработанные исключения (пример кода)
- Собирает диагностические данные, такие как использование памяти, информация об устройстве и т.д. (пример кода)
- Эффективно группируется вместе с помощью основной причины
- Позволяет отслеживать действия, предпринятые пользователем перед каждым сбоем, чтобы помочь воспроизвести (пример кода)
Если вы хотите увидеть некоторые рекомендации по обращению с ошибками/отчетности на Android, вы можете проверить полный исходный код для Bugsnag библиотека отчетов о сбоях который является полностью открытым исходным кодом, не стесняйтесь разлучать его и использовать в своих приложениях!
Ответ 27
Flurry analytics дает вам информацию о сбоях, аппаратную модель, версию Android и статистику использования в реальном времени. В новом SDK они, похоже, предоставляют более подробную информацию о сбоях http://www.flurry.com/flurry-crash-analytics.html.
Ответ 28
Если ваше приложение загружается другими людьми и сбой на удаленных устройствах, вы можете захотеть заглянуть в библиотеку отчетов об ошибках Android (ссылка на этот пост SO)., Если это просто на вашем собственном локальном устройстве, вы можете использовать LogCat. Даже если устройство не было подключено к главной машине, когда произошел сбой, подключенное устройство и выдача команды adb logcat загрузит всю историю журнала (по крайней мере, в той степени, в которой она буферизована, что обычно является loooot данных журнала, это просто не бесконечно). Может ли любой из этих вариантов ответить на ваш вопрос? Если вы не можете попытаться уточнить, что вы ищете немного больше?
Ответ 29
Google изменил количество отчетов о сбоях, которые вы действительно получили. Раньше вы получали только сообщения об ошибках, сообщаемые вручную.
Со времени последней конференции разработчиков и внедрения Android Vitals вы также получаете отчеты о сбоях от пользователей, которые предоставили возможность обмениваться данными диагностики.
Вы увидите все сбои, собранные с устройств Android, пользователи которых решили автоматически обмениваться данными об использовании и диагностике. Данные доступны за предыдущие два месяца.
Ошибки сбоев и приложений, не отвечающих (ANR)
Ответ 30
Вы можете сделать это прямо в Android Studio. Просто подключите свой телефон, запустите приложение, дайте ему потерпеть крах, и вы можете просмотреть стек прямо в Android Studio.