754 votes

Comment obtenir les données de crash de mon application Android ?

Comment puis-je obtenir les données de crash (au moins les traces de pile) de mon application Android ? Au moins lorsque je travaille sur mon propre appareil en étant récupéré par câble, mais idéalement à partir de n'importe quelle instance de mon application fonctionnant sur le sauvage afin que je puisse l'améliorer et la rendre plus solide.

10 votes

0 votes

Je vois que cela envoie le rapport à un serveur distant. Peut-il également enregistrer l'exception dans un fichier local ?

1 votes

Rapport de crash d'application pour Android code.google.com/p/acra

357voto

Kevin Gaudin Points 6395

Vous pouvez essayer le ACRA (Application Crash Report pour Android) bibliothèque :

ACRA est une bibliothèque permettant aux applications Android de publier automatiquement leurs rapports d'accident dans un formulaire GoogleDoc. Elle est destinée aux développeurs d'applications Android pour les aider à obtenir des données de leurs applications lorsqu'elles se plantent ou se comportent de manière erronée.

Il est facile à installer dans votre application, hautement configurable et ne nécessite pas d'héberger un serveur script quelque part... les rapports sont envoyés à une feuille de calcul Google Doc !

8 votes

Il est facile à installer et à utiliser. Recommandé pour une utilisation avant la mise sur le marché, et même éventuellement après.

1 votes

J'ai commencé à l'utiliser et il est incommensurablement meilleur que le rapport d'erreur de Flurry que j'avais avant ou que le rapport fait maison avec lequel j'ai commencé. Jusqu'à présent, je suis très satisfait de "acra".

8 votes

Le grand avantage d'acra est la possibilité d'utiliser les API de Google pour analyser et visualiser facilement les données. jberkel.github.com/sms-backup-plus/acra-analysis pour un exemple de la manière de procéder.

309voto

rrainn Points 1778

Pour les applications d'exemple et à des fins de débogage, j'utilise une solution simple qui me permet d'écrire le stacktrace sur la carte sd de l'appareil et/ou de le télécharger sur un serveur. Cette solution a été inspirée par le projet Android-remote-stacktrace (spécifiquement, la partie sauvegarde vers l'appareil et téléchargement vers le serveur) et je pense que cela résout le problème mentionné par Soonil. Ce n'est pas optimal, mais cela fonctionne et vous pouvez l'améliorer si vous voulez l'utiliser dans une application de production. Si vous décidez de télécharger les stacktraces sur le serveur, vous pouvez utiliser un script php script ( index.php ) pour les visualiser. Si vous êtes intéressé, vous pouvez trouver toutes les sources ci-dessous - une classe java pour votre application et deux scripts php optionnels pour le serveur hébergeant les stacktraces téléchargés.

Dans un Contexte (par exemple l'Activité principale), appelez

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 votes

Je pense que cela causera des problèmes juridiques dans certains États / pays.

5 votes

NOTA: HttpPost httpPost = new HttpPost(url); doit être dans une tâche asynchrone (ou un gestionnaire... un thread séparé) maintenant si vous visez Honeycomb ou plus tard

4 votes

@Joset, quel genre de problèmes juridiques, et pourquoi ?

59voto

PanosJee Points 1871

Vous pouvez également essayer [BugSense] Raison : Spam Redirection vers une autre url . BugSense collecte et analyse tous les rapports de collision et vous donne des rapports significatifs et visuels. C'est gratuit et il suffit d'une ligne de code pour l'intégrer.

Clause de non-responsabilité : je suis cofondateur

4 votes

J'ai essayé BugSense et c'est génial. Une interface simple et fraîche, très rapide aussi. Pas de fonctionnalités stupides. Facile de voir les crashs les plus fréquents et aussi de creuser dans le stacktrace.

0 votes

Ces derniers temps, nous faisons bien plus que de simples rapports sur le Crash, mais ce n'est pas le bon endroit pour parler de nouvelles fonctionnalités, etc.

0 votes

Je l'ai essayé. Les erreurs ont fonctionné bien que la trace de la pile ne soit pas très complète, les données de crash en temps réel ne sont pas parvenues. Le mode débogage n'a pas fonctionné. J'ai suivi la route initialize-once de la classe Application (ce qui est logique dans la plupart des cas). BugSense a un tableau de bord incroyable, c'est une honte que pour une raison quelconque les rapports de crash ne fonctionnent pas et que la symbolisation ne soit pas dans le volet gratuit. Il m'a fallu 5 minutes pour installer GetSentry et ça a marché tout de suite pour Android avec ce client général : github.com/joshdholtz/Sentry-Android

45voto

RoflcoptrException Points 22111

Dans Android 2.2, il est désormais possible d'obtenir automatiquement les rapports de collision des applications Android Market :

Nouvelle fonction de signalement des bogues pour Android Market permet aux développeurs de de recevoir des rapports de crash et de gel de la part leurs utilisateurs. Ces rapports seront disponibles lorsqu'ils se connectent à leur compte d'éditeur.

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

0 votes

Je pense que ce n'est pas seulement la 2.2 mais simplement une nouvelle fonctionnalité de marché que google propose. J'ai reçu un rapport de collision il y a quelques jours et il ne devrait pas y avoir un appareil Froyo qui utilise mon application.

1 votes

@Janusz Êtes-vous sûr ? il y a déjà des versions de Froyo pour le Nexus One, sans compter les Googlers qui utilisent Froyo depuis un moment.

0 votes

Au moins, il doit y avoir eu une mise à jour de la version sur le téléphone, même si c'est juste une autre révision, mais comment cela devrait-il fonctionner autrement ?

18voto

Julie Points 553

J'ai utilisé Crittercisme pour mes applications Android et iOS. J'en ai entendu parler sur Techcrunch. J'en suis très satisfait jusqu'à présent !

0 votes

Pour info : les rapports d'accident du côté de NDK ne font pas partie du plan de base, et se trouvent dans la rubrique "Extended Crash Reporting". Voir : crittercism.com/prix

1 votes

Je viens de tester le reporting NDK sur le Crashlytics Fabric.io de Twitter... plutôt bien (au premier jour d'utilisation), il a nécessité une étape supplémentaire lors de la sortie pour mettre le mapping dans leur système afin que les traces de pile soient bonnes, mais il a cloué l'erreur NDK que j'ai utilisée pour tester (fait un appel "abort() ;" stratégiquement tout au long du c++ et il a fourni une trace de pile pour le test.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X