我可以使用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