ACTUALIZACIÓN: consulte la solución "aceptada" a continuación
Cuando mi aplicación crea una excepción no controlada, en lugar de simplemente terminar, primero me gustaría darle al usuario la oportunidad de enviar un archivo de registro. Me doy cuenta de que hacer más trabajo después de obtener una excepción aleatoria es arriesgado pero, oye, lo peor es que la aplicación termina fallando y el archivo de registro no se envía. Esto está resultando ser más complicado de lo que esperaba :)
Qué funciona: (1) capturando la excepción no detectada, (2) extrayendo información de registro y escribiendo en un archivo.
Lo que todavía no funciona: (3) iniciar una actividad para enviar correo electrónico. En última instancia, tendré otra actividad más para pedir permiso al usuario. Si consigo que la actividad del correo electrónico funcione, no espero muchos problemas para el otro.
El quid del problema es que la excepción no controlada se detecta en mi clase de aplicación. Dado que no es una actividad, no es obvio cómo iniciar una actividad con Intent.ACTION_SEND. Es decir, normalmente para iniciar una actividad, se llama a startActivity y se reanuda con onActivityResult. Estos métodos son compatibles con Activity pero no con Application.
¿Alguna sugerencia sobre cómo hacer esto?
Aquí hay algunos recortes de código como guía de inicio:
public class MyApplication extends Application
{
defaultUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler();
public void onCreate ()
{
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
private void handleUncaughtException (Thread thread, Throwable e)
{
String fullFileName = extractLogToFile(); // code not shown
// The following shows what I'd like, though it won't work like this.
Intent intent = new Intent (Intent.ACTION_SEND);
intent.setType ("plain/text");
intent.putExtra (Intent.EXTRA_EMAIL, new String[] {"[email protected]"});
intent.putExtra (Intent.EXTRA_SUBJECT, "log file");
intent.putExtra (Intent.EXTRA_STREAM, Uri.parse ("file://" + fullFileName));
startActivityForResult (intent, ACTIVITY_REQUEST_SEND_LOG);
}
public void onActivityResult (int requestCode, int resultCode, Intent data)
{
if (requestCode == ACTIVITY_REQUEST_SEND_LOG)
System.exit(1);
}
}
fuente
Respuestas:
Aquí está la solución completa (casi: omití el diseño de la interfaz de usuario y el manejo de los botones), derivada de mucha experimentación y varias publicaciones de otros relacionados con problemas que surgieron en el camino.
Hay una serie de cosas que debe hacer:
Ahora, aquí están los detalles:
(1 y 2) Manejar uncaughtException, iniciar actividad de registro de envío:
(3) Extraer registro (puse esto en mi actividad SendLog):
(4) Inicie una aplicación de correo electrónico (también en mi Actividad de SendLog):
(3 y 4) Así es como se ve SendLog (aunque tendrá que agregar la interfaz de usuario):
(5) Manifiesto:
(6) Configuración de Proguard:
En project.properties, cambie la línea de configuración. Debe especificar "optimizar" o Proguard no eliminará las llamadas Log.v () y Log.d ().
En proguard-project.txt, agregue lo siguiente. Esto le dice a Proguard que asuma que Log.v y Log.d no tienen efectos secundarios (aunque los tienen desde que escriben en los registros) y, por lo tanto, se pueden eliminar durante la optimización:
¡Eso es! Si tiene alguna sugerencia para mejorar esto, hágamelo saber y puedo actualizarlo.
fuente
Hoy en día existen muchas herramientas de notificación de fallos que hacen esto fácilmente.
crashlytics : una herramienta de informes de fallos , gratuita, pero que ofrece informes básicos Ventajas: Gratis
Gryphonet : una herramienta de informes más avanzada que requiere algún tipo de tarifa. Ventajas: Fácil recreación de choques, ANR's, lentitud ...
Si eres un desarrollador privado, te sugeriría Crashlytics, pero si es una gran organización, elegiría Gryphonet.
¡Buena suerte!
fuente
En su lugar, intente usar ACRA: se encarga de enviar el seguimiento de la pila, así como toneladas de otra información de depuración útil a su backend o al documento de Google Docs que haya configurado.
https://github.com/ACRA/acra
fuente
La respuesta de @ PeriHartman funciona bien cuando el hilo de la interfaz de usuario arroja una excepción no detectada. Hice algunas mejoras para cuando la excepción no detectada es lanzada por un hilo que no es de UI.
fuente
Bien explicado. Pero una observación aquí, en lugar de escribir en un archivo usando File Writer y Streaming, hice uso de la opción logcat -f directamente. Aqui esta el codigo
Esto me ayudó a vaciar la última información del búfer. El uso de la transmisión de archivos me dio un problema: no estaba limpiando los últimos registros del búfer. Pero de todos modos, esta fue una guía realmente útil. Gracias.
fuente
Manejo de excepciones no detectadas : como explicó @gilm, simplemente haga esto, (kotlin):
Espero que ayude, funcionó para mí .. (: y). En mi caso, he usado la biblioteca 'com.microsoft.appcenter.crashes.Crashes' para el seguimiento de errores.
fuente
Puede manejar las excepciones no detectadas utilizando la biblioteca FireCrasher y realizar una recuperación de ella.
puede saber más sobre la biblioteca en este artículo mediano
fuente