Jak uzyskać dane o awarii z mojej aplikacji na Androida?


737

Jak mogę uzyskać dane o awariach (przynajmniej stosy śladów) z mojej aplikacji na Androida? Przynajmniej podczas pracy na własnym urządzeniu pobieranym kablem, ale idealnie z dowolnego wystąpienia mojej aplikacji działającej na wolności, aby móc go ulepszyć i uczynić bardziej solidnym.



Widzę, że wysyła to raport do zdalnego serwera. Czy może również zapisać wyjątek do pliku lokalnego?

1
Raport o awarii aplikacji dla Androida code.google.com/p/acra
gdonald

Ten wydaje się być bardziej niezawodny, a jeśli raport nie zostanie przesłany po wszystkich próbach, to czy może następnie zarejestrować plik lub db sqlite db?
JPM

Odpowiedzi:


354

Możesz wypróbować bibliotekę ACRA (Application Crash Report for Android) :

ACRA to biblioteka umożliwiająca aplikacji na Androida automatyczne wysyłanie raportów o awariach do formularza GoogleDoc. Jest przeznaczony dla programistów aplikacji na Androida, aby pomóc im uzyskać dane z ich aplikacji, gdy ulegną awarii lub zachowają się błędnie.

Jest łatwy do zainstalowania w aplikacji, wysoce konfigurowalny i nie wymaga hostowania skryptu serwera w dowolnym miejscu ... raporty są wysyłane do arkusza kalkulacyjnego Google Doc!


8
Jest to łatwe do skonfigurowania i użycia. Zalecany do stosowania przed rynkiem, a nawet później.
mxcl

1
Zacząłem go używać i jest to niewspółmiernie lepsze niż zgłaszanie błędów we Flurry, które miałem wcześniej lub domowej roboty, od której zacząłem. Jak na razie jestem podekscytowany „acrą”.
Adrian Spinei

8
Dużą zaletą acry jest możliwość korzystania z interfejsów API Google do łatwej analizy i wizualizacji danych, zobacz jberkel.github.com/sms-backup-plus/acra-analysis, aby dowiedzieć się, jak to zrobić.
Jan Berkel

3
Wydaje mi się bardzo niestabilny. Sama ACRA uległa awarii i wysłała raport o awarii, a nie o powiązanej awarii aplikacji. -1
Sandor

19
Dokumenty Google jako backend nie są już obsługiwane
eliocs

305

Do przykładowych aplikacji i celów debugowania używam prostego rozwiązania, które pozwala mi zapisać stacktrace na karcie SD urządzenia i / lub przesłać go na serwer. To rozwiązanie zostało zainspirowane przez Project android-remote-stacktrace (w szczególności części do zapisywania na urządzeniu i przesyłania na serwer) i myślę, że rozwiązuje problem wspomniany przez Soonil. Nie jest optymalny, ale działa i możesz go ulepszyć, jeśli chcesz go używać w aplikacji produkcyjnej. Jeśli zdecydujesz się przesłać stos śledzenia na serwer, możesz użyć skryptu php ( index.php), aby je wyświetlić. Jeśli jesteś zainteresowany, możesz znaleźć wszystkie źródła poniżej - jedną klasę Java dla twojej aplikacji i dwa opcjonalne skrypty php dla serwera hostującego przesłane pliki śledzenia.

W kontekście (np. Głównym działaniu) zadzwoń

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
Myślę, że spowoduje to problemy prawne w niektórych stanach / krajach
setzamora,

5
UWAGA: HttpPost httpPost = new HttpPost(url);musi być teraz w zadaniu asynchronicznym (lub moduł obsługi ... osobny wątek), jeśli celujesz w plaster miodu lub nowszy
Bryan Denny,

4
@Joset, jakie problemy prawne i dlaczego?
varevarao

2
@varevarao Problemy prawne (być może), ponieważ wysyłasz poufne informacje o urządzeniu bez zgody użytkownika, korzystając z funkcji wysyłania na serwer tego kodu.
caw

2
Wygląda na to, że defaultExceptionHandler utrzymuje się podczas odtwarzania aktywności. Zaktualizowałem odpowiedź, aby ustawić domyślną wartość, tylko jeśli niestandardowy moduł obsługi nie jest jeszcze ustawiony. Bez niego każdy przewodnik trzyma i wywołuje poprzedni, aż do oryginalnego. Powoduje to problemy z duplikowaniem rejestrowania, a także problemy z wyciekiem pamięci.
Dave McClelland,

57

Możesz także wypróbować [BugSense] Przyczyna: przekierowanie spamu do innego adresu URL . BugSense zbiera i analizuje wszystkie raporty o awariach oraz udostępnia sensowne i wizualne raporty. Jest bezpłatny i zawiera tylko 1 linię kodu w celu integracji.

Oświadczenie: Jestem współzałożycielem


4
Próbowałem BugSense i jego niesamowite. Prosty i świeży interfejs użytkownika, również bardzo szybki. Żadnych głupich wzdęć. Łatwo zobaczyć najczęstsze awarie, a także zagłębić się w ślad po stosie.
vidstige

Mamy ostatnio znacznie więcej niż tylko crash raportowania, ale to nie jest właściwe miejsce, aby porozmawiać nowe funkcje itp
PanosJee

Spróbował tego. Błędy działały, chociaż Stacktrace nie jest zbyt kompletne, dane o awariach w czasie rzeczywistym nie zostały dostarczone. Tryb debugowania nie działał. Przeszedłem jednak trasę inicjowania z klasy Application (co ma sens w większości przypadków). BugSense ma niesamowity pulpit nawigacyjny, taki wstyd, że z jakiegoś powodu raporty o awariach nie działają, a symbolizacja nie znajduje się w warstwie wolnej. Zainstalowanie GetSentry zajęło mi 5 minut i po prostu zadziałało z systemem Android dla tego klienta ogólnego przeznaczenia: github.com/joshdholtz/Sentry-Android
albertpeiro

3
BugSense jest prosty i łatwy do zintegrowania. Ale to zbyt drogie. Możemy osiągnąć te same funkcje wykrywania błędów za pomocą analizy Flurry i analizy składni. Oba są bezpłatne i łatwe do zintegrowania.
venkat

44

W systemie Android 2.2 można teraz automatycznie pobierać raporty o awariach z aplikacji Android Market:

Nowa funkcja zgłaszania błędów w aplikacjach Android Market umożliwia programistom otrzymywanie raportów o awariach i blokowaniu ich użytkowników. Raporty będą dostępne po zalogowaniu się na konto wydawcy.

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


Myślę, że to nie tylko 2.2, ale po prostu nowa funkcja rynkowa, jaką oferuje Google. Kilka dni temu dostałem raport o awarii i nie powinno być urządzenia froyo używającego mojej aplikacji.
Janusz

1
@Janusz Czy jesteś pewien? są już dostępne wydania Froyo na Nexusa One, nie licząc Googlerów, którzy od dawna zarządzają Froyo.
pupeno

Przynajmniej w wersji na telefonie musi być aktualizacja, nawet jej kolejna wersja, ale jak inaczej to powinno działać?
RoflcoptrException

Nie wiem, czy raporty były wcześniej wysyłane do Google. Raport jest nieco dziwny, ponieważ Google pokazuje interfejs użytkownika do wysyłania swoich filmów, a to musi być zmiana w systemie operacyjnym, a nie tylko na rynku. Ale mówi: Platformy 1 raporty raporty / tydzień i droid nie powinien być na froyo.
Janusz

1
Kod przycisku „Zgłoś” jest w AOSP już od jakiegoś czasu, a Romain Guy (niejasno) odpowiedział na pytanie na ten temat kilka miesięcy temu.
Christopher Orr,

30

Możliwe jest obsługiwanie tych wyjątków za pomocą Thread.setDefaultUncaughtExceptionHandler(), jednak wydaje się, że przeszkadza to w metodzie obsługi wyjątków przez system Android. Próbowałem użyć tego rodzaju procedury obsługi:

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

Jednak nawet po ponownym zgłoszeniu wyjątków nie byłem w stanie uzyskać pożądanego zachowania, tj. Zarejestrować wyjątek, jednocześnie pozwalając systemowi Android na zamknięcie komponentu, w którym to się stało, więc po pewnym czasie zrezygnowałem z niego.


Dlaczego rzucasz tylko niesprawdzone wyjątki? Wydaje mi się, że powinieneś rzucić wszystkie wyjątki.
MatrixFrog

Wygląda na to, że ktoś osiągnął sukces dzięki twojemu podejściu: jyro.blogspot.com/2009/09/crash-report-for-android-app.html
MatrixFrog

1
Sztuką jest zdobycie poprzedniego domyślnego UncaughtExceptionHandler i obsłużenie wyjątku od tego obiektu po zakończeniu zgłaszania wyjątku.
Tom

Czy jest Constants.TAGczęścią systemu Android? Pierwszy raz to widzę. Nie mogę tego znaleźć.
Haroun Hajem,

1
@HarounHajem Musimy zdefiniować własne.
KYHSGeekCode,

22

Widzę, że pytanie jest za stare i mam nadzieję, że moja odpowiedź będzie pomocna dla innych osób mających ten sam problem ...

Wypróbuj Crashlytics . Zapewni to dokładny wgląd we wszystkie awarie na wszystkich urządzeniach z twoją aplikacją i wyśle ​​Ci powiadomienie e-mailem. A najlepsze jest to, że korzystanie z niego jest całkowicie bezpłatne.


21

Ok, dobrze spojrzałem na dostarczone próbki z Rrainn i Soonil i znalazłem rozwiązanie, które nie psuje obsługi błędów.

Zmodyfikowałem CustomExceptionHandler, aby przechowywał oryginalny UncaughtExceptionHandler z wątku, który kojarzymy z nowym. Na końcu nowego „uncaughtException” - Metoda Po prostu wywołuję starą funkcję za pomocą zapisanego UncaughtExceptionHandler.

W klasie DefaultExceptionHandler potrzebujesz czegoś. lubię to:

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

Dzięki tej modyfikacji w kodzie pod adresem http://code.google.com/p/android-remote-stacktrace masz dobrą bazę roboczą do logowania się w polu na swoim serwerze internetowym lub karcie SD.


19

Konsola programisty Google Play faktycznie udostępnia ślady stosu z aplikacji, które uległy awarii i wysłały raporty, ma też bardzo dobre wykresy, które pomagają zobaczyć informacje, patrz przykład poniżej:

wprowadź opis zdjęcia tutaj


2
W jaki sposób użytkownicy wysyłają raporty lub jak to działa dokładnie, jeśli Twojej aplikacji nie ma w sklepie Play, czy możesz to zrobić w celach testowych?
Lion789,

Czy wiesz, że istnieje projekt open source na Androida, który upublicznia swoje raporty o awariach?
Justin Civi

1
Pamiętaj, że pokażą tylko awarie ANR, które użytkownicy postanowili zgłosić
pobyt

Tak, rzeczywiście, w każdym razie, gdy masz dużą bazę użytkowników, masz wiele możliwości zgłaszania wszystkich awarii, a także awarii i zgłaszanych tutaj ANR będą najważniejsze, ponieważ ludzie będą je zgłaszać więcej razy, dzięki czemu możesz filtruj i napraw je w tym priorytecie (więcej raportów = ważniejszy błąd) podczas gdy (brak raportu = nie ten krytyczny błąd).
Eefret,

18

Używam Crittercism do moich aplikacji na Androida i iOS - słyszałem o nich na techcrunchu. Jak dotąd jestem z nich zadowolony!


Do Twojej wiadomości: raporty o awariach od strony NDK nie są częścią podstawowego planu i znajdują się w „Rozszerzonych raportach o awariach”. Zobacz: crittercism.com/pricing
ahash

1
Właśnie przetestowałem raportowanie NDK na Twitterze Fabric.io Crashlytics ... całkiem świetnie (pierwszego dnia użytkowania), wymagałem dodatkowego kroku, kiedy wypuszczam mapowanie do ich systemu, aby ślady stosu wyglądały dobrze, ale przybiły błąd NDK, który testowałem (wykonałem „abort ();” wywołanie strategiczne w całym c ++ i zapewniło ślad stosu do testowania.
Hunter-Orionnoir


11

użyj tego, aby złapać szczegóły wyjątku:

String stackTrace = Log.getStackTraceString(exception); 

przechowuj to w bazie danych i prowadź dziennik.


Jak uzyskać dostęp do tej bazy danych, czy podasz mi jakiś przykład. proszę jeśli możesz. dzięki w advacne
Rajendra Verma

8

Możesz także użyć do tego całej (prostej) usługi, a nie tylko biblioteki. Nasza firma właśnie wydała usługę tylko dla tego: http://apphance.com .

Ma prostą bibliotekę .jar (dla Androida), którą dodajesz i integrujesz w 5 minut, a następnie biblioteka gromadzi nie tylko informacje o awarii, ale także dzienniki z uruchomionej aplikacji, a także pozwala testerom zgłaszać problemy bezpośrednio z urządzenia - w tym cały kontekst (obrót urządzenia, niezależnie od tego, czy jest on podłączony do Wi-Fi czy nie i więcej). Możesz przeglądać dzienniki za pomocą bardzo ładnego i przydatnego panelu internetowego, w którym możesz śledzić sesje z aplikacją, awarie, dzienniki, statystyki i więcej. Usługa jest teraz w zamkniętej fazie testów beta, ale możesz poprosić o dostęp, a my damy ci ją bardzo szybko.

Oświadczenie: Jestem CTO Polidei i współtwórcą serwisu.


7

Dziękuję Stackoverflowza pomoc w znalezieniu tej odpowiedzi.

Możesz znaleźć swoje zdalne raporty o awariach Androida bezpośrednio na swój e-mail . pamiętaj, że musisz umieścić swój e-mail w klasie CustomExceptionHandler .

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

Wymagane kroki:

1st) w onCreate swojej aktywności użyj tej sekcji kodu.

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

2.) użyj tej przesłoniętej wersji klasy CustomExceptionHandler (rrainn), zgodnie z moim 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();

    }
}


5

Jest to bardzo brutalne, ale można uruchomić logcat w dowolnym miejscu, więc szybki i brudny hack polega na dodaniu do dowolnego bloku catch getRuntime().exec("logcat >> /sdcard/logcat.log");


Dałoby to wynik dziennika wszystkich aplikacji. Filtrowanie według zmiennej aplikacji może być w porządku, ale nie sądzę, że byłby to dobry sposób, ponieważ wpisy mogą być kumulatywne. Wyczyszczenie danych wyjściowych logcat po każdym zapisie może jednak rozwiązać ten problem.
bschandramohan

5

Istnieje narzędzie zwane tkaniną, jest to narzędzie analityczne po awarii, które pozwoli ci otrzymywać raporty o awariach podczas wdrażania aplikacji na żywo i podczas programowania. Dodanie tego narzędzia do aplikacji było również proste. Gdy awaria Twojej aplikacji, raport o awarii może być wyświetlony z pulpitu Fabric.io. raport został złapany automatycznie. nie poprosi użytkownika o zgodę. Czy chce wysłać raport o błędzie / awarii. A to jest całkowicie bezpłatne ... https://get.fabric.io/


5

Google Firebase to najnowszy sposób Google (2016), aby zapewnić ci dane o awariach / błędach w telefonie. Uwzględnij go w pliku build.gradle:

compile 'com.google.firebase:firebase-crash:9.0.0'

Krytyczne awarie są rejestrowane automatycznie, bez konieczności wprowadzania danych przez użytkownika. Możesz także rejestrować niekrytyczne awarie lub inne zdarzenia, takie jak:

try
{

}
catch(Exception ex)
{
    FirebaseCrash.report(new Exception(ex.toString()));
}

5

Istnieje biblioteka Androida o nazwie Sherlock . Daje pełny raport o awarii wraz z informacjami o urządzeniu i aplikacji. Ilekroć nastąpi awaria, wyświetla powiadomienie na pasku powiadomień, a po kliknięciu powiadomienia otwiera szczegóły awarii. Możesz także udostępniać innym osobom szczegóły awarii w wiadomości e-mail lub za pomocą innych opcji udostępniania.

Instalacja

android {
    dataBinding {
      enabled = true
    }
}

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

Próbny

wprowadź opis zdjęcia tutaj


5

Chociaż wiele odpowiedzi na tej stronie jest przydatnych, łatwo jest im przestać być aktualne. Witryna AppBrain gromadzi statystyki, które pozwalają znaleźć najpopularniejsze aktualne rozwiązanie raportowania awarii:

Biblioteki raportowania awarii Androida

strona aplikacji mózgu

Widać, że w momencie publikowania tego obrazu Crashlytics jest używany w 5,24% aplikacji i 12,38% instalacji.


4

Używamy naszego domowego systemu wewnątrz firmy i bardzo nam to służy. Jest to biblioteka Androida, która wysyła raporty o awariach do serwera i serwera, który odbiera raporty i dokonuje analizy. Serwer grupuje wyjątki według nazwy wyjątku, śledzenia stosu, komunikatu. Pomaga zidentyfikować najbardziej krytyczne problemy, które należy naprawić. Nasz serwis jest obecnie w publicznej wersji beta, więc każdy może go wypróbować. Możesz założyć konto na http://watchcat.co lub po prostu zobaczyć, jak to działa, korzystając z dostępu do wersji demo http://watchcat.co/reports/index.php?demo .


3

Jeśli chcesz natychmiast uzyskać odpowiedzi, możesz użyć logcat

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

Jeśli w twoim dzienniku jest obecnie zbyt wiele śmieci, spróbuj je najpierw usunąć.

$adb shell logcat -c

Następnie spróbuj uruchomić aplikację, a następnie zaloguj się ponownie.


Czy nadal nie wymaga to podłączenia urządzenia do komputera (np. Za pomocą kabla)?
Gerard

3

Znalazłem jeszcze jedną świetną aplikację internetową do śledzenia raportów błędów.

https://mint.splunk.com/

Mała liczba kroków do skonfigurowania.

  1. Zaloguj się lub zarejestruj i skonfiguruj za pomocą powyższego linku. Po zakończeniu tworzenia aplikacji udostępnią wiersz do skonfigurowania, jak poniżej.
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. Dodaj następujące polecenie w build.gradl aplikacji.
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. Dodaj kod, który skopiowaliśmy powyżej i dodaj go do każdej aktywności.

    Mint.initAndStartSession (YourActivity.this, „api_key”);

Otóż ​​to. Zaloguj się i przejdź do pulpitu aplikacji, otrzymasz wszystkie raporty błędów.

Mam nadzieję, że to komuś pomoże.


Ile to kosztuje?
user2966445

2

Alternatywna usługa raportowania awarii / śledzenia wyjątków znajduje się na stronie Raygun.io - ma ona sporo fajnej logiki do obsługi awarii systemu Android, w tym przyzwoitą wygodę użytkownika podczas podłączania jej do aplikacji (dwie linie kodu w głównej aktywności i kilka wiersze XML wklejone w AndroidManifest).

Gdy aplikacja ulega awarii, automatycznie pobiera dane śledzenia stosu, dane środowiska dla sprzętu / oprogramowania, informacje o śledzeniu użytkownika, wszelkie określone dane niestandardowe itp. Wysyła je do interfejsu API asynchronicznie, więc nie blokuje wątku interfejsu użytkownika i buforuje je na dysk, jeśli nie ma dostępnej sieci.

Oświadczenie: Zbudowałem dostawcę Androida :)


1

Właśnie zacząłem używać ACRA https://github.com/ACRA/acra przy użyciu Formularzy Google jako zaplecza i jest bardzo łatwy w konfiguracji i obsłudze, jest to domyślny.

ALE Wysyłanie raportów do Formularzy Google będzie przestarzałe (a następnie usunięte): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google -Form-Arkusz kalkulacyjny-użycie

W każdym razie można zdefiniować własnego nadawcę https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender , na przykład możesz spróbować wysłać wiadomość e-mail do nadawcy.

Przy minimalnym wysiłku możliwe jest wysyłanie raportów do bugsense: http://www.bugsense.com/docs/android#acra

Uwaga : Konto wolne od błędów jest ograniczone do 500 raportów / miesiąc


1

Późno na imprezę popieram i uważam, że ACRA jest najlepszą opcją ze wszystkich. Jest łatwy w konfiguracji i konfiguracji. Stworzyłem szczegółowy przewodnik z danymi wejściowymi z całego świata, aby pobrać raport o awarii za pomocą ACRA i wysłać to samo na mój adres e-mail za pomocą MandrillAp.

Link do posta: https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

Link do przykładowego projektu na github: https://github.com/ayushhgoyal/AcraSample


1

Jestem jednym z założycieli Bugsnag, który zaprojektowaliśmy właśnie do tego celu. Bugsnag automatycznie przechwytuje nieobsługiwane wyjątki w aplikacjach na Androida i wysyła je do naszego pulpitu nawigacyjnego, gdzie można priorytetyzować poprawki i zagłębiać się w informacje diagnostyczne.

Oto kilka ważnych rzeczy, które należy wziąć pod uwagę przy wyborze lub tworzeniu systemu raportowania awarii, wraz z niektórymi fragmentami kodu:

  • Automatycznie wykrywa nieobsługiwane wyjątki ( przykładowy kod )
  • Zbiera dane diagnostyczne, takie jak wykorzystanie pamięci, informacje o urządzeniu itp. ( Przykładowy kod )
  • Skutecznie grupuje awarie razem według przyczyny źródłowej
  • Umożliwia śledzenie działań podjętych przez użytkownika przed każdą awarią, aby pomóc w reprodukcji ( przykładowy kod )

Jeśli chcesz zapoznać się z najlepszymi praktykami związanymi z obsługą / raportowaniem awarii na Androidzie, możesz sprawdzić pełny kod źródłowy biblioteki raportowania awarii Bugsnag, która jest w pełni open source, możesz ją rozerwać i używać we własnych aplikacjach!


0

Jeśli Twoja aplikacja jest pobierana przez inne osoby i ulega awarii na zdalnych urządzeniach, możesz zajrzeć do biblioteki raportów błędów Androida (o której mowa w tym poście SO ). Jeśli jest to tylko na twoim lokalnym urządzeniu, możesz użyć LogCat. Nawet jeśli urządzenie nie było podłączone do komputera hosta w momencie awarii, podłączono urządzenie i wydając polecenie adb logcat pobierze całą historię logcat (przynajmniej w zakresie, w jakim jest buforowany, co zwykle stanowi przeładowanie danych dziennika , to po prostu nieskończone). Czy którakolwiek z tych opcji odpowiada na twoje pytanie? Jeśli nie, możesz spróbować wyjaśnić, czego szukasz?



0

Google zmieniło, ile faktycznie otrzymujesz raportów o awariach. Wcześniej otrzymywałeś tylko ręczne zgłoszenia błędów.

Od ostatniej konferencji programistów i wprowadzenia systemu Android Vitals otrzymujesz również raporty o awariach od użytkowników, którzy umożliwili udostępnianie danych diagnostycznych.

Zobaczysz wszystkie awarie zebrane z urządzeń z Androidem, których użytkownicy wybrali opcję automatycznego udostępniania danych o użytkowaniu i diagnostyce. Dane są dostępne za poprzednie dwa miesiące.

Zobacz awarie i błędy aplikacji nie odpowiada (ANR)


logcat mówi, że w pliku /data/user/0/com znajduje się plik zrzutu awaryjnego. <nazwa_aplikacji>/cache/WebView/Crash Report / <GUUID> .dmp, ale urządzenie nie jest zrootowane i nie mogę zrozumieć jak uzyskać dostęp do tego pliku!
Michael

0

Możesz to zrobić bezpośrednio w Android Studio. Po prostu podłącz telefon, uruchom aplikację, pozwól jej się zawiesić, a będziesz mógł przeglądać stacktrace bezpośrednio w Android Studio.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.