Làm cách nào để lấy dữ liệu sự cố từ ứng dụng Android của tôi?


737

Làm cách nào tôi có thể nhận dữ liệu sự cố (ít nhất là dấu vết ngăn xếp) từ ứng dụng Android của mình? Ít nhất là khi làm việc trên thiết bị của riêng tôi được truy xuất bằng cáp, nhưng lý tưởng nhất là từ bất kỳ ứng dụng nào của tôi chạy tự nhiên để tôi có thể cải thiện thiết bị và làm cho thiết bị chắc chắn hơn.



Tôi thấy rằng điều này sẽ gửi báo cáo đến một máy chủ từ xa. Nó cũng có thể đăng nhập ngoại lệ vào một tệp cục bộ?

1
Báo cáo sụp đổ ứng dụng dành cho Android code.google.com/p/acra
gdonald

Điều này có vẻ mạnh mẽ hơn, nếu báo cáo không tải lên sau tất cả các lần thử lại, thì nó có thể đăng nhập tệp hoặc sqlite db không?
JPM

Câu trả lời:


354

Bạn có thể thử thư viện ACRA (Báo cáo sự cố ứng dụng cho Android) :

ACRA là một thư viện cho phép Ứng dụng Android tự động đăng báo cáo sự cố của họ lên biểu mẫu GoogleDoc. Các nhà phát triển ứng dụng Android được nhắm mục tiêu để giúp họ lấy dữ liệu từ các ứng dụng của họ khi họ gặp sự cố hoặc hành xử sai.

Thật dễ dàng để cài đặt trong ứng dụng của bạn, có cấu hình cao và không yêu cầu bạn lưu trữ tập lệnh máy chủ ở bất cứ đâu ... báo cáo được gửi đến bảng tính Google Doc!


8
Điều này là dễ dàng để thiết lập và sử dụng. Đề xuất cho sử dụng địa điểm trước khi thị trường, và thậm chí có thể sau.
mxcl

1
Bắt đầu sử dụng nó và nó tốt hơn nhiều so với báo cáo lỗi trong Flurry mà tôi có trước đây hoặc lỗi tự chế mà tôi đã bắt đầu. Cho đến nay, tôi đang say mê "acra".
Adrian Spinei

8
Ưu điểm lớn của acra là khả năng sử dụng Google API để dễ dàng phân tích và trực quan hóa dữ liệu, xem jberkel.github.com/sms-backup-plus/acra-analysis để biết ví dụ về cách thực hiện việc này.
Jan Berkel

3
Có vẻ rất không ổn định đối với tôi. Bản thân ACRA đã gặp sự cố và gửi báo cáo sự cố về bản thân không phải là sự cố ứng dụng liên quan. -1
Sandor

19
Google Docs dưới dạng phụ trợ không còn được hỗ trợ nữa
eliocs

305

Đối với các ứng dụng mẫu và mục đích gỡ lỗi, tôi sử dụng một giải pháp đơn giản cho phép tôi ghi stacktrace vào thẻ sd của thiết bị và / hoặc tải nó lên máy chủ. Giải pháp này được lấy cảm hứng từ Project android-remote-stacktrace (cụ thể là các bộ phận lưu vào thiết bị và tải lên máy chủ) và tôi nghĩ rằng nó giải quyết được vấn đề được đề cập bởi Soonil. Nó không tối ưu, nhưng nó hoạt động và bạn có thể cải thiện nó nếu bạn muốn sử dụng nó trong một ứng dụng sản xuất. Nếu bạn quyết định tải stacktraces lên máy chủ, bạn có thể sử dụng tập lệnh php ( index.php) để xem chúng. Nếu bạn quan tâm, bạn có thể tìm thấy tất cả các nguồn bên dưới - một lớp java cho ứng dụng của bạn và hai tập lệnh php tùy chọn cho máy chủ lưu trữ stacktraces đã tải lên.

Trong một bối cảnh (ví dụ: Hoạt động chính), hãy gọi

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
Tôi nghĩ rằng điều này sẽ gây ra các vấn đề pháp lý ở một số tiểu bang / quốc gia
setzamora

5
LƯU Ý: HttpPost httpPost = new HttpPost(url);phải ở trong tác vụ không đồng bộ (hoặc xử lý ... một luồng riêng) ngay bây giờ nếu bạn đang nhắm mục tiêu Honeycomb trở lên
Bryan Denny

4
@Joset, loại vấn đề pháp lý nào, và tại sao?
varevarao

2
@varevarao Các vấn đề pháp lý (có thể) vì bạn đang gửi thông tin thiết bị nhạy cảm mà không có sự đồng ý của người dùng bằng cách sử dụng tính năng Gửi đến máy chủ của mã này.
caw

2
DefaultExceptionHandler dường như vẫn tồn tại trong hoạt động giải trí. Tôi đã cập nhật câu trả lời để chỉ đặt mặc định nếu trình xử lý tùy chỉnh chưa được đặt. Không có nó, mỗi người xử lý giữ và gọi cái trước đó, tất cả các cách để cái ban đầu. Điều này gây ra các vấn đề với đăng nhập trùng lặp cũng như các vấn đề rò rỉ bộ nhớ.
Dave McClelland

57

Bạn cũng có thể thử [BugSense] Lý do: Spam Redirect sang một url khác . BugSense thu thập và phân tích tất cả các báo cáo sự cố và cung cấp cho bạn các báo cáo trực quan và có ý nghĩa. Nó miễn phí và chỉ có 1 dòng mã để tích hợp.

Tuyên bố miễn trừ trách nhiệm: Tôi là người đồng sáng lập


4
Tôi đã thử BugSense và nó tuyệt vời. Giao diện người dùng đơn giản và mới mẻ, rất nhanh chóng. Không có tính năng ngu ngốc phình to. Dễ dàng nhìn thấy các sự cố thường xuyên nhất và cũng để đào sâu vào stacktrace.
vidstige

Gần đây chúng tôi làm nhiều hơn là chỉ báo cáo sự cố nhưng đây không phải là nơi thích hợp để nói về các tính năng mới, v.v.
PanosJee

Thử nó. Lỗi hoạt động mặc dù stacktrace không quá đầy đủ, dữ liệu sự cố thời gian thực không xảy ra. Chế độ gỡ lỗi không hoạt động. Tôi đã đi xuống tuyến đường khởi tạo một lần từ lớp Ứng dụng (đó là điều có ý nghĩa đối với hầu hết các trường hợp). BugSense có một bảng điều khiển tuyệt vời, thật xấu hổ vì một số lý do báo cáo sự cố không hoạt động và biểu tượng không nằm trong tầng miễn phí. Mất 5 phút để cài đặt GetSentry và nó đã hoạt động tốt với Android với ứng dụng khách chung này: github.com/joshdholtz/Sentry-Android
albertpeiro

3
BugSense đơn giản và dễ tích hợp. NHƯNG NÓ LÀ MỞ RỘNG. Chúng ta có thể đạt được các chức năng cảm nhận lỗi tương tự bằng cách sử dụng phân tích Flurry và Parse. Cả hai đều miễn phí và dễ dàng tích hợp.
venkat 27/2/2015

44

Trong Android 2.2 giờ đây có thể tự động nhận Báo cáo sự cố từ Ứng dụng Android Market:

Tính năng báo cáo lỗi mới cho các ứng dụng Android Market cho phép các nhà phát triển nhận báo cáo sự cố và đóng băng từ người dùng của họ. Các báo cáo sẽ có sẵn khi họ đăng nhập vào tài khoản nhà xuất bản của họ.

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


Tôi nghĩ rằng nó không chỉ là 2.2 mà chỉ đơn giản là một tính năng thị trường mới mà Google cung cấp. Tôi đã gặp sự cố vài ngày trước và không nên có một thiết bị froyo ngoài đó bằng ứng dụng của tôi.
Janusz

1
@Janusz Bạn có chắc không? đã có bản phát hành Froyo cho Nexus One, mà không tính các nhân viên Google đã chạy Froyo được một thời gian.
Pupeno

Ít nhất phải có một bản cập nhật trong phiên bản trên điện thoại, thậm chí nó chỉ là một bản sửa đổi khác, nhưng làm thế nào để nó hoạt động theo cách khác?
RoflcoptrException

Tôi không biết nếu các báo cáo đã được gửi tới google trước đó. Báo cáo hơi lạ vì google hiển thị UI để gửi video của họ và đó phải là một sự thay đổi trong HĐH chứ không chỉ thị trường. Nhưng nó nói: Nền tảng 1 báo cáo báo cáo / tuần và droid không nên có trên froyo.
Janusz

1
Mã nút "Báo cáo" đã có trong AOSP được một thời gian và Romain Guy (mơ hồ) đã trả lời một câu hỏi về nó ở đây vài tháng trước.
Christopher Orr

30

Có thể xử lý các ngoại lệ này với Thread.setDefaultUncaughtExceptionHandler(), tuy nhiên điều này dường như gây rối với phương pháp xử lý ngoại lệ của Android. Tôi đã cố gắng sử dụng một trình xử lý có tính chất này:

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

Tuy nhiên, ngay cả khi lấy lại các ngoại lệ, tôi không thể có được hành vi mong muốn, tức là ghi lại ngoại lệ trong khi vẫn cho phép Android tắt thành phần mà nó đã xảy ra, vì vậy tôi đã từ bỏ nó sau một thời gian.


Tại sao bạn chỉ ném lại ngoại lệ không được kiểm tra? Dường như với tôi bạn nên ném lại tất cả các ngoại lệ.
MatrixFrog

Có vẻ như ai đó đã thành công với cách tiếp cận của bạn: jyro.blogspot.com/2009/09/crash-report-for-android-app.html
MatrixFrog

1
Mẹo nhỏ là lấy UncaughtExceptionHandler mặc định trước đó và xử lý ngoại lệ cho đối tượng đó sau khi bạn báo cáo xong ngoại lệ.
Tom

Constants.TAGmột phần của khung Android? Lần đầu tiên nhìn thấy nó. Dường như không thể tìm thấy nó.
Haroun Hajem

1
@HarounHajem Chúng ta cần xác định riêng của chúng tôi.
KYHSGeekCode

22

Tôi thấy rằng câu hỏi này quá cũ và hy vọng câu trả lời của tôi hữu ích cho những người khác có cùng vấn đề ...

Hãy dùng thử Crashlytics . Nó sẽ cung cấp cái nhìn sâu sắc sâu sắc về tất cả các sự cố trên tất cả các thiết bị có ứng dụng của bạn và gửi thông báo cho bạn qua email..Và phần tốt nhất là nó hoàn toàn miễn phí để sử dụng ..


21

Ok, tôi đã xem xét các mẫu được cung cấp từ rrainn và Soonil, và tôi đã tìm thấy một giải pháp không gây rối khi xử lý lỗi.

Tôi đã sửa đổi CustomExceptionHandler để nó lưu trữ UncaughtExceptionHandler ban đầu từ Chủ đề mà chúng tôi liên kết với cái mới. Ở phần cuối của "unsaughtException" mới - Phương thức tôi chỉ gọi hàm cũ bằng UncaughtExceptionHandler được lưu trữ.

Trong lớp DefaultExceptionHandler bạn cần sth. như thế này:

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

Với sửa đổi về mã tại http://code.google.com.vn/p/android-remote-stacktrace, bạn có một cơ sở hoạt động tốt để đăng nhập vào trường vào máy chủ web của bạn hoặc vào thẻ sd.


19

Bảng điều khiển dành cho nhà phát triển Google Play thực sự cung cấp cho bạn các dấu vết Stack từ các ứng dụng đã bị sập và đã gửi báo cáo, đây cũng là một biểu đồ rất tốt để giúp bạn xem thông tin, xem ví dụ bên dưới:

nhập mô tả hình ảnh ở đây


2
Làm thế nào để bạn có người dùng gửi báo cáo hoặc làm thế nào để nó hoạt động chính xác nếu ứng dụng của bạn không có trong cửa hàng chơi, bạn có thể làm điều đó cho mục đích thử nghiệm không?
Lion789

Bạn có biết rằng có bất kỳ dự án Android nguồn mở nào công khai các báo cáo sự cố của họ không?
Justin Civi

1
Xin lưu ý, điều này sẽ chỉ hiển thị các sự cố, ANR mà người dùng đã chọn báo cáo
sojin

Vâng, thực sự, dù sao khi bạn có một cơ sở người dùng lớn, bạn có rất nhiều khả năng tất cả các sự cố được báo cáo, và cả sự cố và ANR được báo cáo ở đây sẽ là những vấn đề quan trọng nhất, bởi vì mọi người sẽ báo cáo chúng nhiều lần hơn, vì vậy bạn có thể lọc và sửa chúng trong mức ưu tiên đó (nhiều báo cáo = lỗi quan trọng hơn) trong khi (không có báo cáo = không phải lỗi nghiêm trọng đó).
Eefret

18

Tôi đã sử dụng Crittercism cho các ứng dụng Android và iOS của mình - đã nghe về chúng trên techcrunch. Khá hạnh phúc với họ cho đến nay!


FYI: các báo cáo sự cố từ phía NDK không nằm trong kế hoạch cơ bản và nằm trong "Báo cáo sự cố mở rộng". Xem: crittercism.com/pricing
ahash

1
Tôi vừa thử nghiệm báo cáo NDK trên Fabric.io Crashlytics của Twitter ... khá tuyệt vời (vào ngày 1 sử dụng), nó yêu cầu thêm một bước khi tôi phát hành để đưa ánh xạ lên hệ thống của họ để các dấu vết ngăn xếp trông ổn, nhưng nó bị đóng đinh lỗi NDK mà tôi đã sử dụng để kiểm tra (thực hiện một cuộc gọi "hủy bỏ ();" một cách chiến lược trong toàn bộ c ++ và nó đã cung cấp một dấu vết ngăn xếp để thử nghiệm.
Hunter-Orionnoir


11

sử dụng để bắt các chi tiết ngoại lệ:

String stackTrace = Log.getStackTraceString(exception); 

lưu trữ này trong cơ sở dữ liệu và duy trì nhật ký.


Làm thế nào để truy cập cơ sở dữ liệu đó, bạn sẽ cho tôi bất kỳ ví dụ nào. xin vui lòng nếu bạn có thể. cảm ơn trong advacne
Rajendra Verma

8

Bạn cũng có thể sử dụng toàn bộ dịch vụ (đơn giản) cho nó chứ không chỉ thư viện. Công ty chúng tôi vừa phát hành một dịch vụ chỉ dành cho điều đó: http://apphance.com .

Nó có một thư viện .jar đơn giản (dành cho Android) mà bạn thêm và tích hợp trong 5 phút và sau đó thư viện tập hợp không chỉ thông tin sự cố mà còn đăng nhập từ ứng dụng đang chạy, cũng như cho phép người kiểm tra của bạn báo cáo vấn đề trực tiếp từ thiết bị - bao gồm cả toàn bộ bối cảnh (xoay thiết bị, cho dù nó có được kết nối với wifi hay không và hơn thế nữa). Bạn có thể xem nhật ký bằng bảng điều khiển web rất hay và hữu ích, nơi bạn có thể theo dõi các phiên với ứng dụng của mình, sự cố, nhật ký, số liệu thống kê và hơn thế nữa. Hiện tại dịch vụ đang trong giai đoạn thử nghiệm beta kín, nhưng bạn có thể yêu cầu quyền truy cập và chúng tôi cung cấp cho bạn rất nhanh.

Tuyên bố miễn trừ trách nhiệm: Tôi là CTO của Polidea, và đồng sáng lập dịch vụ.


7

Cảm ơn các nguồn lực có mặt trong Stackoverflowviệc giúp tôi tìm câu trả lời này.

Bạn có thể tìm thấy các báo cáo sự cố Android từ xa trực tiếp vào email của mình . Hãy nhớ rằng bạn phải đặt email của mình trong lớp CustomExceptionHandler .

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

Các bước cần thiết:

1) trong onCreate của hoạt động của bạn sử dụng phần này của mã của bạn.

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

2) sử dụng phiên bản ghi đè này của lớp CustomExceptionHandler của (rrainn), theo phpscript của tôi.

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

Điều này rất tàn bạo, nhưng có thể chạy logcat ở bất cứ đâu, vì vậy một cách nhanh chóng và bẩn thỉu là thêm vào bất kỳ khối bắt nào getRuntime().exec("logcat >> /sdcard/logcat.log");


Điều này sẽ cung cấp đầu ra nhật ký của tất cả các ứng dụng. Lọc theo tên thẻ Ứng dụng có thể ổn nhưng đừng nghĩ rằng đây sẽ là một cách hay để thực hiện vì các mục có thể bị giảm giá. Xóa đầu ra logcat sau mỗi lần ghi có thể giải quyết vấn đề đó.
bschandramohan

5

Có một công cụ gọi là vải, đây là một công cụ phân tích sự cố, cho phép bạn nhận báo cáo sự cố, khi ứng dụng được triển khai trực tiếp và trong quá trình phát triển. Việc thêm công cụ này vào ứng dụng của bạn cũng rất đơn giản .. Khi ứng dụng của bạn gặp sự cố, có thể xem báo cáo về sự cố từ bảng điều khiển Fabric.io của bạn. báo cáo thw đã được bắt tự động. Tôi sẽ không xin phép người dùng. Liệu anh ấy / cô ấy muốn gửi báo cáo lỗi / sự cố. Và điều này là hoàn toàn miễn phí ... https: // get.foven.io/


5

Google Firebase là cách mới nhất (2016) của Google để cung cấp cho bạn dữ liệu sự cố / lỗi trên điện thoại của bạn. Bao gồm nó trong tệp build.gradle của bạn:

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

Các sự cố nghiêm trọng được ghi lại tự động mà không yêu cầu người dùng nhập vào và bạn cũng có thể ghi lại các sự cố không nghiêm trọng hoặc các sự kiện khác như vậy:

try
{

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

5

Có thư viện android này tên là Sherlock . Nó cung cấp cho bạn báo cáo đầy đủ về sự cố cùng với thông tin về thiết bị và ứng dụng. Mỗi khi xảy ra sự cố, nó sẽ hiển thị thông báo trên thanh thông báo và khi nhấp vào thông báo, nó sẽ mở chi tiết sự cố. Bạn cũng có thể chia sẻ chi tiết sự cố với người khác qua email hoặc các tùy chọn chia sẻ khác.

Cài đặt

android {
    dataBinding {
      enabled = true
    }
}

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

Bản giới thiệu

nhập mô tả hình ảnh ở đây


5

Mặc dù nhiều câu trả lời trên trang này là hữu ích, nhưng rất dễ để chúng trở nên lỗi thời. Trang web AppBrain tổng hợp số liệu thống kê cho phép bạn tìm giải pháp báo cáo sự cố phổ biến nhất hiện tại:

Thư viện báo cáo sự cố Android

trang web ứng dụng não

Bạn có thể thấy rằng tại thời điểm đăng ảnh này, Crashlytics được sử dụng trong 5,24% ứng dụng và 12,38% số lượt cài đặt.


4

Chúng tôi sử dụng hệ thống trồng tại nhà của chúng tôi trong công ty và nó phục vụ chúng tôi rất tốt. Đó là một thư viện Android gửi báo cáo sự cố đến máy chủ và máy chủ nhận báo cáo và thực hiện một số phân tích. Nhóm máy chủ ngoại lệ theo tên ngoại lệ, stacktrace, tin nhắn. Nó giúp xác định hầu hết các vấn đề quan trọng cần được khắc phục. Dịch vụ của chúng tôi hiện đang ở giai đoạn thử nghiệm công khai để mọi người có thể dùng thử. Bạn có thể tạo tài khoản tại http://watchcat.co hoặc bạn có thể xem cách nó hoạt động bằng cách sử dụng quyền truy cập demo http://watchcat.co/reports/index.php?demo .


3

Nếu bạn muốn câu trả lời ngay lập tức, bạn có thể sử dụng logcat

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

Nếu có quá nhiều rác trong nhật ký của bạn ngay bây giờ, hãy thử xóa nó trước.

$adb shell logcat -c

Sau đó thử chạy ứng dụng của bạn sau đó đăng nhập lại.


Điều này vẫn không yêu cầu bạn kết nối thiết bị với PC (ví dụ như bằng cáp)?
Gerard

3

Tôi tìm thấy thêm một ứng dụng web tuyệt vời để theo dõi các báo cáo lỗi.

https://mint.splunk.com/

Số lượng nhỏ các bước để cấu hình.

  1. Đăng nhập hoặc đăng ký và cấu hình bằng liên kết trên. Khi bạn tạo xong một ứng dụng, họ sẽ cung cấp một dòng để cấu hình như bên dưới.
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. Thêm phần sau vào build.gradl của ứng dụng.
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. Thêm mã mà chúng tôi đã sao chép ở trên và thêm nó vào mọi hoạt động.

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

Đó là nó. Bạn đăng nhập và vào bảng điều khiển ứng dụng, bạn sẽ nhận được tất cả các báo cáo lỗi.

Hy vọng nó sẽ giúp được ai đó.


Cái này giá bao nhiêu?
dùng2966445

2

Để biết dịch vụ báo cáo sự cố / theo dõi ngoại lệ thay thế, hãy kiểm tra Raygun.io - nó có một loạt logic tốt để xử lý các sự cố Android, bao gồm trải nghiệm người dùng tốt khi cắm nó vào ứng dụng của bạn (hai dòng mã trong Hoạt động chính của bạn và một vài dòng các dòng của XML được dán vào AndroidManifest).

Khi ứng dụng của bạn gặp sự cố, nó sẽ tự động lấy theo dõi ngăn xếp, dữ liệu môi trường cho phần cứng / phần mềm, thông tin theo dõi người dùng, bất kỳ dữ liệu tùy chỉnh nào bạn chỉ định, v.v. Nó đăng nó lên API không đồng bộ để không chặn luồng UI và lưu trữ nó vào đĩa nếu không có mạng.

Tuyên bố miễn trừ trách nhiệm: Tôi đã xây dựng nhà cung cấp Android :)


1

Mới bắt đầu sử dụng ACRA https://github.com/ACRA/acra bằng Google Forms làm phụ trợ và rất dễ cài đặt & sử dụng, đó là mặc định.

NHƯNG Gửi báo cáo tới Google Forms sẽ không được chấp nhận (sau đó bị xóa): https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google -Form-Bảng tính sử dụng

Dù sao, bạn có thể xác định người gửi của riêng mình https://github.com/ACRA/acra/wiki/AdvifiedUsage#wiki-Imcellenceing_your_own_sender bạn có thể thử gửi email cho người gửi chẳng hạn.

Với nỗ lực tối thiểu, có thể gửi báo cáo tới bugense: http://www.bugsense.com/docs/android#acra

NB Tài khoản miễn phí bugense được giới hạn ở 500 báo cáo / tháng


1

Đến bữa tiệc muộn, tôi ủng hộ và tin rằng ACRA là lựa chọn tốt nhất trong số tất cả. Nó dễ dàng để thiết lập và cấu hình. Tôi đã tạo một hướng dẫn chi tiết với các đầu vào từ khắp nơi để tìm nạp báo cáo sự cố bằng ACRA và gửi thư tương tự đến địa chỉ email của tôi bằng MandrillAp.

Liên kết đến bài đăng: https://androidician.wordpress.com/2015/03/29/seinating-crash-reports-with-acra-over-email-USE-mandrill/

Liên kết đến dự án mẫu trên github: https://github.com/ayushhgidel/AcraSample


1

Tôi là một trong những người sáng lập Bugsnag mà chúng tôi thiết kế cho mục đích này. Bugsnag tự động nắm bắt các ngoại lệ chưa được xử lý trong các ứng dụng Android và gửi chúng đến bảng điều khiển của chúng tôi, nơi bạn có thể ưu tiên sửa lỗi và đi sâu vào thông tin chẩn đoán.

Dưới đây là một số điều quan trọng cần xem xét khi chọn hoặc xây dựng hệ thống báo cáo sự cố, cùng với một số đoạn mã:

  • Tự động phát hiện các ngoại lệ chưa được xử lý ( mã ví dụ )
  • Thu thập dữ liệu chẩn đoán như sử dụng bộ nhớ, thông tin thiết bị, v.v ( mã ví dụ )
  • Hiệu quả các nhóm sự cố với nhau do nguyên nhân gốc
  • Cho phép bạn theo dõi các hành động mà người dùng đã thực hiện trước mỗi sự cố để giúp sao chép ( mã ví dụ )

Nếu bạn muốn xem một số thực tiễn tốt nhất về xử lý sự cố / báo cáo sự cố trên Android, bạn có thể kiểm tra mã nguồn đầy đủ cho thư viện báo cáo sự cố của Bugsnag là nguồn mở hoàn toàn, vui lòng xé nó ra và sử dụng nó trong các ứng dụng của riêng bạn!


0

Nếu ứng dụng của bạn đang được người khác tải xuống và gặp sự cố trên các thiết bị từ xa, bạn có thể muốn xem xét thư viện báo cáo lỗi Android (được tham khảo trong bài đăng SO này ). Nếu nó chỉ trên thiết bị cục bộ của riêng bạn, bạn có thể sử dụng LogCat. Ngay cả khi thiết bị không được kết nối với máy chủ khi xảy ra sự cố, kết nối thiết bị và ban hành lệnh logcat adb sẽ tải xuống toàn bộ lịch sử logcat (ít nhất là trong phạm vi mà nó được đệm thường là dữ liệu nhật ký , nó chỉ không phải là vô hạn). Có một trong những lựa chọn trả lời câu hỏi của bạn? Nếu không bạn có thể cố gắng làm rõ những gì bạn đang tìm kiếm thêm một chút?



0

Google đã thay đổi số lượng báo cáo sự cố bạn thực sự nhận được. Trước đây bạn chỉ nhận được báo cáo lỗi thủ công.

Kể từ hội nghị nhà phát triển cuối cùng và giới thiệu Android Vitals, bạn cũng nhận được báo cáo sự cố từ người dùng đã kích hoạt để chia sẻ dữ liệu chẩn đoán.

Bạn sẽ thấy tất cả các sự cố được thu thập từ các thiết bị Android có người dùng đã chọn tham gia để tự động chia sẻ dữ liệu chẩn đoán và sử dụng. Dữ liệu có sẵn trong hai tháng trước.

Xem lỗi và ứng dụng không phản hồi (ANR)


logcat đang nói rằng có một tệp kết xuất sự cố đầu ra trong /data/user/0/com.<myappname>/cache/WebView/Crash Báo cáo / <GUUID> .dmp, nhưng thiết bị không được root và tôi không thể tìm ra ra làm thế nào để truy cập tập tin này!
Michael

0

Bạn có thể làm điều này trực tiếp trong Android Studio. Chỉ cần kết nối điện thoại của bạn, chạy ứng dụng, để nó bị sập và bạn có thể xem stacktrace trực tiếp trong Android Studio.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.