2012-01-23 29 views
7

Tôi có thể sử dụng Thư viện ACRA để quản lý lỗi gần bằng cách xử lý lỗi ngoại lệ chưa được xử lý. Báo cáo có thể gửi đến google doc., email và dịch vụ web tùy chỉnh thành công ..ACRA: Làm thế nào tôi có thể viết báo cáo ACRA để nộp (trong Thẻ SD)?

Nhưng những gì tôi muốn ..

  • Làm thế nào tôi có thể viết báo cáo để nộp [ví dụ. sdcard/myapp/myLog.txt]?

do tại sao tôi muốn điều này ..

  • sử dụng ứng dụng My có thể không có kết nối internet trong khi lực lượng gần xảy ra .. nếu như vậy thì tôi sẽ bỏ lỡ báo cáo, nếu tôi viết báo cáo để sau đó tôi có thể gửi đến máy chủ của mình khi có kết nối internet.

Trả lời

8

Tôi nghĩ rằng những gì bạn muốn đạt được đã được thực hiện bởi ACRA. Dưới đây là những gì tôi thấy trong abd logcat của mình:

01-23 12:15:28.056: D/ACRA(614): Writing crash report file. 
01-23 12:15:28.136: D/ACRA(614): Mark all pending reports as approved. 
01-23 12:15:28.136: D/ACRA(614): Looking for error files in /data/data/com.ybi/files 
01-23 12:15:28.136: V/ACRA(614): About to start ReportSenderWorker from #handleException 
01-23 12:15:28.146: D/ACRA(614): Add user comment to null 
01-23 12:15:28.146: D/ACRA(614): #checkAndSendReports - start 
01-23 12:15:28.146: D/ACRA(614): Looking for error files in /data/data/com.ybi/files 

Điều đầu tiên mà ACRA làm là tạo báo cáo về tệp trên bộ nhớ trong của ứng dụng của bạn. Sau đó, nếu bạn đang trực tuyến và trình báo cáo lỗi được khởi tạo chính xác, nó sẽ gửi báo cáo. Nếu không, các báo cáo được lưu giữ trong lưu trữ dữ liệu (để gửi sau).

Tôi không xem xét dữ liệu nhưng hiện tôi đang làm việc trên trình ghi nhật ký tùy chỉnh. Vì vậy, nếu bạn muốn làm những điều tương tự hơn ACRA, thật dễ dàng:

ACRA.init(this); 

    // a custom reporter for your very own purposes 
    ErrorReporter.getInstance().setReportSender(new LocalReportSender(this)); 

Và sau đó:

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Set; 

import org.acra.ACRA; 
import org.acra.CrashReportData; 
import org.acra.ReportField; 
import org.acra.sender.ReportSender; 
import org.acra.sender.ReportSenderException; 

import android.content.Context; 

import de.akquinet.android.androlog.Log; 

public class LocalReportSender implements ReportSender { 

private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>() ; 
private FileOutputStream crashReport = null; 

public LocalReportSender(Context ctx) { 
    // the destination 
    try { 
     crashReport = ctx.openFileOutput("crashReport", Context.MODE_WORLD_READABLE); 
    } catch (FileNotFoundException e) { 
     Log.e("TAG", "IO ERROR",e); 
    } 
} 

@Override 
public void send(CrashReportData report) throws ReportSenderException { 

    final Map<String, String> finalReport = remap(report); 

    try { 
     OutputStreamWriter osw = new OutputStreamWriter(crashReport); 

     Set set = finalReport.entrySet(); 
     Iterator i = set.iterator(); 

     while (i.hasNext()) { 
      Map.Entry<String,String> me = (Map.Entry) i.next(); 
      osw.write("[" + me.getKey() + "]=" + me.getValue()); 
     } 

     osw.flush(); 
     osw.close(); 
    } catch (IOException e) { 
     Log.e("TAG", "IO ERROR",e); 
    } 

} 

private static boolean isNull(String aString) { 
    return aString == null || ACRA.NULL_VALUE.equals(aString); 
} 

private Map<String, String> remap(Map<ReportField, String> report) { 

    ReportField[] fields = ACRA.getConfig().customReportContent(); 
    if (fields.length == 0) { 
     fields = ACRA.DEFAULT_REPORT_FIELDS; 
    } 

    final Map<String, String> finalReport = new HashMap<String, String>(
      report.size()); 
    for (ReportField field : fields) { 
     if (mMapping == null || mMapping.get(field) == null) { 
      finalReport.put(field.toString(), report.get(field)); 
     } else { 
      finalReport.put(mMapping.get(field), report.get(field)); 
     } 
    } 
    return finalReport; 
} 

} 

tôi không kiểm tra đầy đủ nó được nêu ra nhưng bạn sẽ có được ý tưởng. Hy vọng nó giúp.

+0

cảm ơn bạn rất nhiều user1102206, bạn có ý tưởng không, làm thế nào chúng tôi có thể gửi những bài hát được ghi trong tập tin để cắt bằng cách nhấn vào nút trong hoạt động sau khi khởi động lại [mở lại ứng dụng] ?. thay vì tự động gửi báo cáo. ** Req: sau khi bạn kiểm tra đầy đủ. xin vui lòng cập nhật câu trả lời. ** b'coz không có bài tốt được tìm thấy liên quan đến điều này .. vì vậy nó sẽ hữu ích hơn cho những người khác quá .. – Jayabal

+1

Cảm ơn baya. Về câu hỏi ban đầu của bạn về ACRA, điểm đầu tiên trả lời câu hỏi của bạn: nếu ứng dụng của bạn gặp sự cố, ACRA sẽ tự giải quyết vấn đề kết nối internet, không cần phải làm điều đó bằng tay. Về việc gửi báo cáo, có một số điều có sẵn trong trang web acra (tại đây: http://code.google.com/p/acra/source/browse/trunk/acra/src/main/java/org/acra/sender /). Đoạn mã trên được lấy cảm hứng từ một lớp. Những gì tôi có ý nghĩa khi tôi nói đầy đủ các trường hợp cận biên: không có khoảng trống trên thiết bị để báo cáo, không có quyền ghi trên sdcard, cấu hình acra không được đặt đúng cách, v.v. – Gomoku7

+0

Giải pháp không được chấp nhận, vui lòng xem câu trả lời @ user2302510 – dayanruben

0

Tôi đã sử dụng ACRA nhưng không ở dạng này (được sử dụng để gửi nhật ký đến máy chủ của riêng mình), vì vậy tôi không chắc chắn cách thực hiện việc này.
Nhưng trong trường hợp này bạn không thể có được toàn bộ nhật ký hệ thống (đó sẽ là một mã nguồn chi tiết) bằng cách sử dụng các libs/apis khác và ghi nó vào một tệp.

HOẶC, những gì bạn có thể làm là sử dụng mã zip của ACRA và sửa đổi một chút ví dụ: Sử dụng tệp "CrashReportData.java" hoặc "CrashReporterDialog.java" trong gói của nó và tìm nạp nội dung từ đó và lưu nó vào tập tin của bạn.

Tôi đang nói về phiên bản 4.2.3.

+0

cảm ơn bạn akkilis, tôi sẽ đi qua các tập tin để thực hiện thay đổi .. – Jayabal

6

Tôi đoán câu trả lời từ @ Gomoku7 chứa một số mã bị phản đối vì vậy tôi sẽ chỉ gửi những giải pháp mà tôi đã sử dụng:

Gọi này trong onCreate():

ACRA.init(this); 
ACRA.getErrorReporter().setReportSender(new LocalReportSender(this)); 

Ở đây tôi đã về cơ bản đã thay đổi mã để sử dụng BufferedWriter để tôi có thể viết trực tiếp vào thẻ SD mà không thể với openFileOutput(). Do đó chỉ có phương pháp send() và hàm tạo LocalReportSender() được thay đổi một chút.

Lưu ý: Hãy nhận biết rằng logfile phát triển khá nhanh chóng vì vậy hãy chắc chắn rằng bạn không mất MBS không gian của SDcard của người dùng của bạn vì một tập tin đăng nhập :)

private class LocalReportSender implements ReportSender { 

    private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>(); 
    private FileWriter crashReport = null; 

    public LocalReportSender(Context ctx) { 
     // the destination 
     File logFile = new File(Environment.getExternalStorageDirectory(), "log.txt"); 

     try { 
      crashReport = new FileWriter(logFile, true); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void send(CrashReportData report) throws ReportSenderException { 
     final Map<String, String> finalReport = remap(report); 

     try { 
      BufferedWriter buf = new BufferedWriter(crashReport); 

      Set<Entry<String, String>> set = finalReport.entrySet(); 
      Iterator<Entry<String, String>> i = set.iterator(); 

      while (i.hasNext()) { 
       Map.Entry<String, String> me = (Entry<String, String>) i.next(); 
       buf.append("[" + me.getKey() + "]=" + me.getValue()); 
      } 

      buf.flush(); 
      buf.close(); 
     } catch (IOException e) { 
      Log.e("TAG", "IO ERROR", e); 
     } 
    } 

    private boolean isNull(String aString) { 
     return aString == null || ACRAConstants.NULL_VALUE.equals(aString); 
    } 

    private Map<String, String> remap(Map<ReportField, String> report) { 

     ReportField[] fields = ACRA.getConfig().customReportContent(); 
     if (fields.length == 0) { 
      fields = ACRAConstants.DEFAULT_REPORT_FIELDS; 
     } 

     final Map<String, String> finalReport = new HashMap<String, String>(
       report.size()); 
     for (ReportField field : fields) { 
      if (mMapping == null || mMapping.get(field) == null) { 
       finalReport.put(field.toString(), report.get(field)); 
      } else { 
       finalReport.put(mMapping.get(field), report.get(field)); 
      } 
     } 
     return finalReport; 
    } 

} 
+0

Cảm ơn! Điều này làm việc cho tôi, với một bản sao khối từ đây, và với nhật thực sửa chữa các hàng nhập khẩu bị mất tích. Các tập tin bằng văn bản đi vào thư mục gốc của sdcard, và là 27k. Rat khuyen khich! –

0

giải pháp trên hoạt động hoàn hảo. Có lẽ chỉ có một điều, Nếu tập tin là không nhìn thấy được sử dụng tập tin thám hiểm, cố gắng thêm quảng bá ý định Intent.ACTION_MEDIA_SCANNER_SCAN_FILE

check this link

Các vấn đề liên quan