Pregunta ¿Cómo obtengo los datos de fallas de mi aplicación Android?


¿Cómo puedo obtener datos de bloqueo (al menos, rastros de pila) de mi aplicación Android? Al menos cuando trabajo en mi propio dispositivo que se recupera por cable, pero idealmente desde cualquier instancia de mi aplicación que se ejecute en la naturaleza para que pueda mejorarla y hacerla más sólida.


684
2018-05-18 08:52


origen


Respuestas:


Puede probar el ACRA (informe de bloqueo de aplicaciones para Android) biblioteca:

ACRA es una biblioteca que permite a la aplicación de Android publicar automáticamente sus informes de fallos en un formulario de GoogleDoc. Está dirigido a los desarrolladores de aplicaciones de Android para ayudarlos a obtener datos de sus aplicaciones cuando fallan o se comportan de manera errónea.

Es fácil de instalar en su aplicación, altamente configurable y no requiere que usted aloje un script de servidor en cualquier lugar ... ¡los informes se envían a una hoja de cálculo de Google Docs!


341
2018-04-16 08:00



Para las aplicaciones de muestra y para la depuración, uso una solución simple que me permite escribir el stacktrace en la tarjeta sd del dispositivo y / o subirlo a un servidor. Esta solución ha sido inspirada por Project android-remote-stacktrace (específicamente, las partes para guardar en el dispositivo y subir al servidor) y creo que resuelve el problema mencionado por Soonil. No es óptimo, pero funciona y puede mejorarlo si desea usarlo en una aplicación de producción. Si decide subir las stacktraces al servidor, puede usar un script php (index.php) para verlos. Si está interesado, puede encontrar todas las fuentes a continuación: una clase Java para su aplicación y dos scripts PHP para el servidor que aloja las stacktraces cargadas.

En un contexto (por ejemplo, la actividad principal), llame

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

283
2018-05-28 10:34



También puedes probar BugSense. BugSense recopila y analiza todos los informes de fallas y le brinda informes significativos y visuales. Es gratis y solo tiene 1 línea de código para integrarse.

Descargo de responsabilidad: soy cofundador


54
2018-03-18 17:24



En Android 2.2 ahora es posible obtener informes Crash automáticamente desde las aplicaciones de Android Market:

Nueva función de informe de errores para Android   Las aplicaciones de mercado permiten a los desarrolladores   recibir informes de bloqueo y congelamiento de   sus usuarios. Los informes serán   disponible cuando inician sesión en su   cuenta del editor

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


42
2018-05-13 21:51



Es posible manejar estas excepciones con Thread.setDefaultUncaughtExceptionHandler()Sin embargo, esto parece interferir con el método de Android para manejar excepciones. Intenté usar un controlador de esta naturaleza:

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

Sin embargo, incluso al volver a lanzar las excepciones, no pude obtener el comportamiento deseado, es decir, registrar la excepción al tiempo que permitía que Android apagara el componente que le había sucedido, así que me rendí después de un tiempo.


24
2017-12-15 00:25



Ok, bueno miré las muestras provistas de rrainn y Soonil, y encontré una solución eso no estropea el manejo de errores.

Modifiqué CustomExceptionHandler para que almacene el UncaughtExceptionHandler original del subproceso que asociamos al nuevo. Al final de la nueva "uncaughtException" - Método. Solo llamo a la función anterior usando el UncaughtExceptionHandler almacenado.

En la clase DefaultExceptionHandler necesitas algo. Me gusta esto:

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

Con esa modificación en el código en http://code.google.com/p/android-remote-stacktrace tiene una buena base de trabajo para iniciar sesión en el campo de su servidor web o para tarjeta SD.


19
2017-08-02 07:47



He estado usando Crittercismo para mis aplicaciones de Android e iOS: me enteré de ellas en Techcrunch. ¡Muy feliz con ellos hasta ahora!


18



Veo que la pregunta es demasiado antigua y espero que mi respuesta sea útil para que otros tengan el mismo problema ...

Dar Crashlytics un intento. Le dará una visión más profunda de todos los fallos en todos los dispositivos que tienen su aplicación y le enviará una notificación por correo electrónico. Y la mejor parte es que es completamente gratis.


18



La Consola de Desarrolladores de Google Play en realidad le da los rastreos de Apilamiento de aquellas aplicaciones que se han bloqueado y ha enviado los informes, también tiene muy buenos cuadros para ayudarlo a ver la información, vea el ejemplo a continuación:

enter image description here


17



Hice mi propia versión aquí: http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html

Básicamente es lo mismo, pero estoy usando un correo en lugar de una conexión http para enviar el informe, y, más importante, agregué algunas informaciones como la versión de la aplicación, la versión del sistema operativo, el modelo del teléfono o la memoria disponible en mi informe. .


13



use esto para captar los detalles de la excepción:

String stackTrace = Log.getStackTraceString(exception); 

almacene esto en la base de datos y mantenga el registro.


11