我可以使用ACRA庫通過處理未捕獲的異常來管理強制關閉錯誤。該報告可以發送到谷歌文檔,電子郵件和成功的自定義Web服務..ACRA:如何將ACRA報告寫入文件(在SD卡中)?
但我想要的東西..
- 我怎麼能寫報告到文件[前。 sdcard/myapp/myLog.txt]?
爲什麼我想這個..
- 我的應用程序的用戶而強制關閉時可能沒有互聯網連接..如果這樣的話,我會懷念這份報告,如果我寫報告文件然後我可以發送到我的服務器時,互聯網連接可用。
我可以使用ACRA庫通過處理未捕獲的異常來管理強制關閉錯誤。該報告可以發送到谷歌文檔,電子郵件和成功的自定義Web服務..ACRA:如何將ACRA報告寫入文件(在SD卡中)?
但我想要的東西..
爲什麼我想這個..
我認爲你想達到的目標已經由ACRA完成。下面是我在ABD logcat中看到:
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
是ACRA並正在對你的應用程序的內部存儲的文件的報告的第一件事。 然後,如果您在線並且錯誤報告器已正確初始化,它將發送報告。 否則,報告將保存在數據存儲器中(以供稍後發送)。
我沒有查看數據,但我目前正在處理自定義記錄器。所以,如果你想要做的比ACRA同樣的事情,很容易:
ACRA.init(this);
// a custom reporter for your very own purposes
ErrorReporter.getInstance().setReportSender(new LocalReportSender(this));
然後:
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;
}
}
我沒有完全測試它尚未但你的想法。希望能幫助到你。
我已經使用ACRA,但不是在這種形式(用於發送日誌到我自己的服務器),所以我不知道如何做到這一點。
但是,在這種情況下,不能使用其他libs/apis將整個系統日誌作爲一個整體(這將是一個詳細的課程)並將其寫入文件。
或者,你可以做的是,使用ACRA zip的代碼並修改它,例如使用它的包中的文件「CrashReportData.java」或「CrashReporterDialog.java」,並從那裏獲取內容並保存它到你的文件。
我在說它的版本4.2.3。
謝謝akkilis,我將通過這些文件進行更改.. – Jayabal
我想從@ Gomoku7答案包含了一些過時代碼,所以我就張貼我使用的解決方案:
稱這種現象的onCreate():
ACRA.init(this);
ACRA.getErrorReporter().setReportSender(new LocalReportSender(this));
在這裏,我已經基本上改變使用BufferedWriter的代碼,以便我可以直接寫入SD卡,這是openFileOutput()
所不可能的。因此只有方法send()
和構造函數LocalReportSender()
稍有改變。
注:請注意,日誌文件相當迅速成長,所以要確保你不會佔用用戶的SD卡空間的MB,因爲日誌文件的:)
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;
}
}
謝謝!這對我來說很有效,在這裏有一個塊拷貝,用eclipse修復缺少的導入。寫入的文件到達SD卡的根目錄,並且是27k。強烈推薦! –
上述解決方案完美的作品。有可能是隻有一件事, 如果文件使用文件管理器是不可見的,儘量意圖廣播添加到Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
非常感謝user1102206,你有沒有想法,在重啓[重新打開應用程序]之後,如何通過點擊活動中的按鈕,我們可以將那些寫在文件中的軌道發送到中斷?而不是自動發送報告。 **需求:經過充分測試。請更新答案。** b'coz沒有好的後發現關於此..所以它會更有幫助其他人.. – Jayabal
謝謝巴亞。關於您在ACRA的最初問題,第一點回答您的問題:如果您的應用崩潰,ACRA將自行處理互聯網連接可用性,無需手動完成。關於發送報告,acra網站上提供了一些內容(http://code.google.com/p/acra/source/browse/trunk/acra/src/main/java/org/acra/sender /)。上面的代碼受到一個班級的啓發。我說的完全測試的意思是邊緣情況:設備上沒有留下空間用於報告,無權在SD卡上寫入,未正確設置acra配置等。 – Gomoku7
不贊成使用解決方案,請參閱@ user2302510回答 – dayanruben