Android 애플리케이션에서 충돌 데이터를 얻으려면 어떻게합니까?


737

내 Android 애플리케이션에서 충돌 데이터 (적어도 스택 추적)를 얻으려면 어떻게해야합니까? 적어도 케이블로 검색되는 자체 장치에서 작업 할 때 이상적이지만 야생에서 실행중인 응용 프로그램의 모든 인스턴스에서 이상적으로 개선하여 더 견고하게 만들 수 있습니다.


10
이것을 확인하십시오 : github.com/tomquist/Android-Error-Reporter
Tom

보고서가 원격 서버로 전송되는 것을 알 수 있습니다. 예외를 로컬 파일에 기록 할 수도 있습니까?


이 방법이 더 강력 해 보입니다. 모든 재시도 후에보고가 업로드되지 않으면 파일 또는 sqlite db로 기록 할 수 있습니까?
JPM

답변:


354

ACRA (Android 용 응용 프로그램 충돌 보고서) 라이브러리 사용해 볼 수 있습니다 .

ACRA는 Android 애플리케이션이 충돌 보고서를 GoogleDoc 양식에 자동으로 게시 할 수있는 라이브러리입니다. 안드로이드 응용 프로그램 개발자는 응용 프로그램이 충돌하거나 잘못 작동 할 때 응용 프로그램에서 데이터를 가져올 수 있도록 도와줍니다.

앱에 설치하기 쉽고 구성하기 쉬우 며 어디에서나 서버 스크립트를 호스팅 할 필요가 없습니다. 보고서는 Google 문서 스프레드 시트로 전송됩니다!


8
설치 및 사용이 쉽습니다. 시판 전 장소 사용 및 이후에도 권장됩니다.
mxcl

1
그것을 사용하기 시작했고 그것은 전에 가지고 있었던 Flurry 또는 내가 만든 집에서 만든 Flurry의 오류보고보다 훨씬 낫습니다. 지금까지 나는 "아크라"에 푹 빠졌다.
Adrian Spinei

8
acra의 가장 큰 장점은 Google API를 사용하여 데이터를 쉽게 분석하고 시각화 할 수 있다는 것입니다.이를 수행하는 방법에 대한 예는 jberkel.github.com/sms-backup-plus/acra-analysis 를 참조하십시오 .
Jan Berkel

3
나에게는 매우 불안정한 것 같습니다. ACRA 자체가 충돌하여 관련 앱 충돌이 아닌 자체에 대한 충돌 보고서를 보냈습니다. -1
Sandor

19
Google 문서 도구 백엔드는 더 이상 지원되지 않으므로
eliocs

305

샘플 응용 프로그램 및 디버깅 목적으로 스택 추적을 장치의 sd 카드에 쓰거나 서버에 업로드 할 수있는 간단한 솔루션을 사용합니다. 이 솔루션은 Project android-remote-stacktrace (특히 장치에 저장 및 서버에 업로드 부분)에서 영감을 얻었으며 Soonil이 언급 한 문제를 해결한다고 생각합니다. 최적은 아니지만 작동하며 프로덕션 응용 프로그램에서 사용하려는 경우 향상시킬 수 있습니다. 스택 추적을 서버에 업로드하기로 결정한 경우 PHP 스크립트 ( index.php)를 사용하여 볼 수 있습니다. 관심이 있으시면 아래의 모든 소스를 찾을 수 있습니다-응용 프로그램을위한 하나의 Java 클래스와 업로드 된 스택 추적을 호스팅하는 서버를위한 두 개의 선택적 php scrips.

컨텍스트 (예 : 기본 활동)에서

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
이것이 일부 주 / 국가에서 법적 문제를 야기 할 것이라고 생각합니다.
setzamora

5
참고 : HttpPost httpPost = new HttpPost(url);Honeycomb 이상을 대상으로하는 경우 이제 비동기 작업 (또는 처리기 ... 별도의 스레드)에 있어야합니다
Bryan Denny

4
@ 조셋, 어떤 종류의 법적인 문제, 왜?
varevarao

2
@varevarao이 코드의 서버로 전송 기능을 사용하여 사용자의 동의없이 민감한 장치 정보를 전송하기 때문에 법적 문제가있을 수 있습니다.
caw

2
defaultExceptionHandler는 Activity 레크리에이션에서 지속되는 것으로 보입니다. 사용자 지정 처리기가 아직 설정되어 있지 않은 경우에만 기본값을 설정하도록 답변을 업데이트했습니다. 이것이 없으면 각 처리기는 이전 처리기를 유지하여 원래 처리기로 끝까지 호출합니다. 이로 인해 중복 로깅 및 메모리 누수 문제가 발생합니다.
Dave McClelland

57

[BugSense] 이유 : 스팸 다른 URL로 리디렉션을 시도 할 수도 있습니다 . BugSense는 모든 충돌 보고서를 수집하고 분석하여 의미 있고 시각적 인 보고서를 제공합니다. 무료이며 통합하기 위해 단 한 줄의 코드입니다.

면책 조항 : 나는 공동 설립자입니다


4
나는 BugSense와 그 멋진 것을 시도했습니다. 간단하고 신선한 UI, 매우 빠릅니다. 어리석은 기능 팽창이 없습니다. 가장 빈번한 충돌을 확인하고 스택 추적을 쉽게 파헤칠 수 있습니다.
vidstige

최근 Crash보고 이상의 기능을 제공하지만 새로운 기능 등을 이야기하기에 적합한 곳은 아닙니다.
PanosJee

그것을 시도했다. stacktrace가 너무 완료되지 않았지만 실시간 충돌 데이터가 발생하지 않았지만 오류가 발생했습니다. 디버그 모드가 작동하지 않았습니다. 그래도 Application 클래스에서 initialize-once 경로를 내려갔습니다 (대부분의 경우 의미가 있습니다). BugSense에는 놀라운 대시 보드가 있습니다. 어떤 이유로 든 충돌 보고서가 작동하지 않고 상징화가 프리 티어에 있지 않습니다. GetSentry를 설치하는 데 5 분이 걸렸으며이 범용 클라이언트를 사용하여 Android 용으로 즉시 작동했습니다 : github.com/joshdholtz/Sentry-Android
albertpeiro 10

3
BugSense는 간단하고 통합하기 쉽습니다. 그러나 너무 비싸다. Flurry 분석 및 구문 분석을 사용하여 동일한 버그 감지 기능을 수행 할 수 있습니다. 둘 다 무료이며 쉽게 통합 할 수 있습니다.
venkat

44

Android 2.2에서는 이제 Android 마켓 애플리케이션에서 충돌 보고서를 자동으로 가져올 수 있습니다.

Android 마켓 앱을위한 새로운 버그보고 기능을 통해 개발자는 사용자로부터 충돌 보고서 및 정지 보고서를받을 수 있습니다. 게시자 계정에 로그인하면 보고서를 사용할 수 있습니다.

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


나는 그것이 2.2 일뿐 만 아니라 Google이 제공하는 새로운 시장 기능이라고 생각합니다. 며칠 전에 충돌 보고서가 표시되고 내 앱을 사용하여 froyo 장치가 없어야합니다.
Janusz

1
@Janusz 확실합니까? 한동안 Froyo를 실행 한 Google 직원을 제외하고 Nexus One 용 Froyo가 이미 출시되었습니다.
pupeno

최소한 전화 버전, 심지어 다른 개정판에 대한 업데이트가 있어야하지만 어떻게 다른 방식으로 작동해야합니까?
RoflcoptrException

이전에 보고서가 Google로 전송되었는지 알 수 없습니다. 구글은 비디오를 보내기위한 UI를 보여주기 때문에 다소 이상하다. 시장뿐만 아니라 OS의 변화이기도하다. 그러나 그것은 말합니다 : 플랫폼 1 보고서 / 주 보고서 및 드로이드가 얼어 붙지 않아야합니다.
Janusz

1
"Report"버튼 코드는 AOSP에서 한동안 사용되어 왔으며 Romain Guy (아마도)는 몇 개월 전에 여기에서 이에 대한 질문에 대답했습니다.
Christopher Orr

30

로 이러한 예외를 처리 할 수는 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에서 여전히 발생한 구성 요소를 종료하도록 허용하면서 예외를 기록했기 때문에 잠시 후 포기했습니다.


확인되지 않은 예외 만 다시 던지는 이유는 무엇입니까? 모든 예외를 다시 던져야한다고 생각합니다.
MatrixFrog

사람처럼 보인다는 당신의 접근 방식을 성공 : jyro.blogspot.com/2009/09/crash-report-for-android-app.html
MatrixFrog

1
트릭은 이전 기본 UncaughtExceptionHandler를 가져오고 예외보고를 완료 한 후 해당 오브젝트에 대한 예외를 처리하는 것입니다.
Tom

Constants.TAG안드로이드 프레임 워크의 일부? 처음 보았습니다. 찾을 수없는 것 같습니다.
Haroun Hajem

1
@HarounHajem 우리는 우리 자신을 정의해야합니다.
KYHSGeekCode

22

질문이 너무 오래되어서 같은 문제를 가진 다른 사람들에게 도움이되기를 바랍니다.

부여 Crashlytics을 시도합니다. 응용 프로그램이있는 모든 장치의 모든 충돌에 대한 심층적 인 통찰력을 제공하고 전자 메일을 통해 알림을 보냅니다 .. 가장 중요한 부분은 완전히 무료입니다.


21

좋아, rrainn과 Soonil에서 제공된 샘플을 보았고 오류 처리를 엉망으로 만들지 않는 솔루션을 찾았습니다.

CustomExceptionHandler를 수정하여 새 UncaughtExceptionHandler를 새 스레드와 연관시키는 스레드에서 저장합니다. 새로운 "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 의 코드에서 수정 하면 필드에 웹 서버 또는 sd-card에 로그인하기위한 좋은 작업 기반이 있습니다.


19

Google Play 개발자 콘솔은 실제로 충돌이 발생하여 보고서를 보낸 앱의 스택 추적을 제공하며, 정보를 볼 수있는 매우 유용한 차트도 있습니다 (아래 예 참조).

여기에 이미지 설명을 입력하십시오


2
사용자가 보고서를 보내도록하거나 앱이 Play 스토어에없는 경우 어떻게 작동하는지 테스트 목적으로 할 수 있습니까?
Lion789

충돌 보고서를 공개하는 오픈 소스 Android 프로젝트가 있다는 것을 알고 있습니까?
저스틴 Civi

1
이 단지 충돌 표시됩니다 유의하시기 바랍니다 ANR은 사용자가보고 선택했다는
소진

예, 실제로 사용자 규모가 크면 모든 충돌이 발생할 가능성이 많으며 여기에 충돌이 발생하고 여기에보고 된 ANR이 가장 중요합니다. 사람들이 더 많은 시간을보고 할 수 있기 때문입니다. 우선 순위 (더 많은 보고서 = 더 중요한 버그)로 필터링하고 수정합니다 (보고서 없음 = 중요 버그 아님).
Eefret

18

저는 Android 및 iOS 앱에 Crittercism 을 사용 하고 있습니다. 지금까지 그들에게 매우 만족합니다!


참고 : NDK 측의 충돌 보고서는 기본 계획의 일부가 아니며 "확장 충돌보고"에 속합니다. 참조 : crittercism.com/pricing
ahash

1
방금 Twitter의 Fabric.io Crashlytics에서 NDK보고를 테스트했습니다 ... 사용 1 일에 아주 훌륭합니다. 매크로 추적 추적을 위해 시스템에 매핑을 배치하기 위해 릴리스 할 때 추가 단계가 필요했지만 못 박았습니다. 테스트에 사용한 NDK 오류 (c ++에서 전략적으로 "abort ();"호출을했으며 테스트를위한 스택 추적을 제공했습니다.
Hunter-Orionnoir


11

이를 사용하여 예외 세부 사항을 포착하십시오.

String stackTrace = Log.getStackTraceString(exception); 

이것을 데이터베이스에 저장하고 로그를 유지하십시오.


해당 데이터베이스에 액세스하는 방법을 알려주세요. 할 수 있다면 제발 advacne에 감사
Rajendra Verma

8

라이브러리 만이 아니라 전체 (간단한) 서비스를 사용할 수도 있습니다. 우리 회사는 방금 다음과 같은 서비스를 출시했습니다 : http://apphance.com .

간단한 .jar 라이브러리 (Android 용)를 사용하면 5 분 안에 추가하고 통합 한 다음 라이브러리가 충돌 정보뿐만 아니라 실행중인 응용 프로그램의 로그를 수집 할뿐만 아니라 테스터가 장치에서 직접 문제를보고 할 수 있습니다 전체 컨텍스트 (Wi-Fi에 연결되어 있는지 여부 등) 응용 프로그램과의 세션, 충돌, 로그, 통계 등을 추적 할 수있는 매우 훌륭하고 유용한 웹 패널을 사용하여 로그를 볼 수 있습니다. 서비스는 현재 비공개 베타 테스트 단계이지만 액세스를 요청할 수 있으며 매우 신속하게 서비스를 제공 할 수 있습니다.

면책 조항 : 저는 Polidea의 CTO이며 공동 서비스 작성자입니다.


7

Stackoverflow이 답변을 찾는 데 도움 이되는 감사 리소스가 있습니다.

당신은 당신의 이메일에 직접 원격 안드로이드 충돌 보고서를 찾을 수 있습니다 . 반드시 이메일을 CustomExceptionHandler 클래스 안에 넣어야합니다 .

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

필요한 단계 :

1) onCreate 활동 에서이 섹션의 코드를 사용하십시오.

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

2) 내 phpscript에 따라이 재정의 된 CustomExceptionHandler 클래스 (rrainn)를 사용하십시오.

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

    }
}

6

현재 Firebase 충돌 보고서는 매우 인기 있고 사용하기 쉽습니다. 자세한 내용은 다음 링크를 참조하십시오. Firebase 충돌보고

그것이 도움이되기를 바랍니다.


5

이것은 매우 무례하지만 어디서나 logcat을 실행할 수 있으므로 빠르고 더러운 핵은 모든 catch 블록에 추가하는 것입니다 getRuntime().exec("logcat >> /sdcard/logcat.log");


이것은 모든 앱의 로그 출력을 제공합니다. 앱 태그 이름으로 필터링해도 문제가 없지만 항목이 누적 될 수 있으므로 이것이 좋은 방법이라고 생각하지 않습니다. 각 쓰기 후에 logcat 출력을 지우면 해당 문제가 해결 될 수 있습니다.
bschandramohan 2016 년

5

패브릭이라는 도구가 있습니다.이 도구는 충돌 분석 도구입니다.이 도구를 사용하면 응용 프로그램을 실시간으로 배포하고 개발하는 동안 충돌 보고서를 얻을 수 있습니다. 응용 프로그램에이 도구를 추가하는 것도 간단합니다. 응용 프로그램이 충돌 할 때 충돌 보고서를 fabric.io 대시 보드에서 볼 수 있습니다. thw 보고서가 자동으로 포착되었습니다. 사용자에게 권한을 요청하지 않습니다. 버그 / 충돌 보고서를 보낼지 여부. 그리고 이것은 완전 무료입니다 ... https://get.fabric.io/


5

Google Firebase 는 휴대 전화에서 충돌 / 오류 데이터를 제공하는 Google의 최신 (2016) 방법입니다. build.gradle 파일에 포함하십시오.

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

치명적인 충돌은 사용자 입력없이 자동으로 기록되며 치명적이지 않은 충돌 또는 다음과 같은 다른 이벤트도 기록 할 수 있습니다.

try
{

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

5

Sherlock 이라는이 안드로이드 라이브러리가 있습니다 . 장치 및 응용 프로그램 정보와 함께 충돌에 대한 전체 보고서를 제공합니다. 충돌이 발생할 때마다 알림 표시 줄에 알림이 표시되고 알림을 클릭하면 충돌 세부 정보가 열립니다. 이메일 또는 다른 공유 옵션을 통해 충돌 세부 정보를 다른 사람과 공유 할 수도 있습니다.

설치

android {
    dataBinding {
      enabled = true
    }
}

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

데모

여기에 이미지 설명을 입력하십시오


5

이 페이지의 많은 답변이 유용하지만 구식이되기 쉽습니다. AppBrain 웹 사이트는 통계를 집계하여 현재 가장 인기있는 충돌보고 솔루션을 찾을 수 있습니다.

Android 충돌보고 라이브러리

앱 뇌 웹 사이트

이 사진을 게시 할 때 Crashlytics는 앱의 5.24 % 및 설치의 12.38 %에서 사용됩니다.


4

우리는 회사 내부에서 자체 개발 한 시스템을 사용하며 우리에게 매우 잘 서비스합니다. 보고서를 수신하고 일부 분석을 수행하는 서버 및 서버로 충돌 보고서를 보내는 Android 라이브러리입니다. 서버는 예외 이름, 스택 추적, 메시지별로 예외를 그룹화합니다. 해결해야 할 가장 중요한 문제를 식별하는 데 도움이됩니다. 우리의 서비스는 현재 공개 베타 버전이므로 모든 사람들이 사용해 볼 수 있습니다. http://watchcat.co 에서 계정을 만들 거나 데모 액세스 http://watchcat.co/reports/index.php?demo를 사용하여 계정 작동 방식을 살펴볼 수 있습니다 .


3

즉시 답변을 원한다면 logcat 을 사용할 수 있습니다

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

지금 로그에 정크가 너무 많으면 먼저 지우십시오.

$adb shell logcat -c

그런 다음 앱을 실행 한 다음 logcat을 다시 시도하십시오.


그래도 장치를 PC에 연결하지 않아도 되나요 (예 : 케이블 사용)?
Gerard

3

오류 보고서를 추적하는 훌륭한 웹 응용 프로그램이 하나 더 있습니다.

https://mint.splunk.com/

구성 단계가 적습니다.

  1. 위의 링크를 사용하여 로그인 또는 가입하고 구성하십시오. 응용 프로그램 작성을 마치면 아래와 같이 구성 할 수있는 라인이 제공됩니다.
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. 애플리케이션의 build.gradl에 다음을 추가하십시오.
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. 위에서 복사 한 코드를 추가하고 모든 활동에 추가하십시오.

    Mint.initAndStartSession (YourActivity.this, "api_key");

그게 다야. 로그인하여 응용 프로그램 대시 보드로 이동하면 모든 오류 보고서가 표시됩니다.

그것이 누군가를 돕기를 바랍니다.


이 얼마예요?
user2966445

2

대체 충돌보고 / 예외 추적 서비스의 경우 Raygun.io를 확인하십시오 .Android 충돌을 처리하기위한 훌륭한 논리가 있습니다. 여기에는 앱에 연결할 때 적절한 사용자 경험 (주 활동에 두 줄의 코드와 몇 가지 코드 포함)이 있습니다. AndroidManifest에 붙여 넣은 XML 줄).

앱이 충돌하면 스택 추적, 하드 / 소프트웨어 환경 데이터, 사용자 추적 정보, 지정한 사용자 지정 데이터 등을 자동으로 가져옵니다. API에 비동기 적으로 게시하여 UI 스레드를 차단하지 않고 캐시합니다. 사용 가능한 네트워크가없는 경우 디스크에.

면책 조항 : 나는 안드로이드 공급자를 만들었습니다 :)


1

Google Forms를 백엔드로 사용하여 ACRA https://github.com/ACRA/acra 를 사용하기 시작했으며 설정 및 사용이 매우 쉽고 기본값입니다.

그러나 Google 설문지에 보고서를 보내는 것은 더 이상 사용되지 않으며 제거됩니다 ( https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google 양식 스프레드 시트 사용법

어쨌든 자신의 발신자를 정의 할 수 있습니다 https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender 예를 들어 발신자에게 이메일을 보내려고 시도 할 수 있습니다.

최소한의 노력으로 bugsense에 보고서를 보낼 수 있습니다 : http://www.bugsense.com/docs/android#acra

NB bugsense free 계정은 월 500보고로 제한됩니다


1

파티에 늦게, 나는 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


1

저는 우리가 정확히이 목적을 위해 디자인 한 Bugsnag 의 창립자 중 한 사람입니다 . Bugsnag는 Android 앱에서 처리되지 않은 예외를 자동으로 캡처하여이를 대시 보드로 전송하여 수정 사항의 우선 순위를 정하고 진단 정보를 확인할 수 있습니다.

다음은 일부 코드 스 니펫과 함께 충돌보고 시스템을 선택하거나 구축 할 때 고려해야 할 중요한 사항입니다.

  • 처리되지 않은 예외를 자동으로 감지합니다 ( 예제 코드 ).
  • 메모리 사용량, 장치 정보 등과 같은 진단 데이터를 수집합니다 ( 예제 코드 ).
  • 근본 원인별로 충돌을 효과적으로 그룹화
  • 각 충돌 전에 사용자가 수행 한 작업을 추적하여 재생산에 도움을줍니다 ( 예제 코드 ).

Android에서 충돌 처리 /보고에 대한 모범 사례를 보려면 완전히 공개 된 Bugsnag의 충돌보고 라이브러리에 대한 전체 소스 코드를 확인하십시오 .


0

다른 사람이 앱을 다운로드하고 원격 장치에서 충돌하는 경우 Android 오류보고 라이브러리 ( 이 SO post 에서 참조)를 살펴볼 수 있습니다 . 자신의 로컬 장치에만있는 경우 LogCat을 사용할 수 있습니다. 충돌이 발생했을 때 장치가 호스트 시스템에 연결되지 않은 경우에도 장치를 연결하고 adb logcat 명령을 실행하면 전체 logcat 기록이 다운로드됩니다 (최소한 로그 데이터 인 버퍼링 된 정도까지). , 그것은 단지 무한하지 않습니다). 이러한 옵션 중 하나가 귀하의 질문에 대답합니까? 그렇지 않다면 조금 더 찾고있는 것을 명확히 할 수 있습니까?



0

Google은 실제로받는 충돌 보고서의 양을 변경했습니다. 이전에는 수동으로보고 된 버그 보고서 만 받았습니다.

마지막 개발자 회의와 Android Vitals 가 소개 된 후 진단 데이터를 공유 할 수있는 사용자로부터 충돌 보고서가 표시됩니다.

사용자가 사용 및 진단 데이터를 자동으로 공유하도록 선택한 Android 기기에서 수집 된 모든 충돌이 표시됩니다. 지난 2 개월 동안 데이터를 사용할 수 있습니다.

보기 충돌 및 응용 프로그램 응답 없음 (ANR) 오류


logcat이 /data/user/0/com.<myappname>/cache/WebView/Crash Report / <GUUID> .dmp에 출력 크래시 덤프 파일이 있다고 말했지만 장치가 루팅되지 않아 그림을 볼 수 없습니다 이 파일에 액세스하는 방법!
Michael

0

Android Studio에서 직접 수행 할 수 있습니다. 휴대 전화를 연결하고 앱을 실행 한 후 충돌하면 Android Studio에서 직접 스택 추적을 볼 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.