ACRA全称: Application Crash Report for Android.
顾名思义, ACRA是一个优秀的Android异常日志收集的开源框架. 利用他可以轻松的实现Android APP 异常日志的收集.
下载地址: https://github.com/ACRA/acra
A.异常报告的几种提交方式:
B.可以在报告随意添加自己的内容
C.应用未崩溃的情况下, 也可以发送报告
D.如果没有网络,异常日志会暂时保存,连接网络后再发送
E.可以同 自托管报告接收脚本 一起使用
F.使用除静默提交外的任何一种提交方式, 系统自带的”强制关闭”对话框将不再弹出, 并且不会在要求发送异常报告.
G.允许发送报告到多种终端:
1.将ACRA的jar包添加到工程中
2.建立一个Application的子类,这里以BaseApplication为例
注意要在AndroidMainfest.xml的Application节点中配置name属性, 还要给APP添加网络权限
<application
android:name="BaseApplication"
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
3.在BaseApplication中添加如下代码:
import org.acra.*;
import org.acra.annotation.*;
@ReportsCrashes(
formKey = "", // This is required for backward compatibility but not used
formUri = "http://www.backendofyourchoice.com/reportpath"
)
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化ACRA
ACRA.init(this);
}
}
4.大功告成,异常日志已经可以提交到你的服务器了,很简单,有木有!
当然,如果你想配置更完美的ACRA,那么请继续往下看…
@ReportsCrashes(formKey="dGVacG0ydVHnaNHjRjVTUTEtb3FPWGc6MQ",
mode = ReportingInteractionMode.TOAST,
forceCloseDialogAfterToast = false, // optional, default false
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
...
在strings.xml中配置土司弹出的内容
<string name="crash_toast_text">Ooooops ! I crashed, but a report has been sent to my developer to help fix the issue !</string>
@ReportsCrashes(formKey="dGVacG0ydVHnaNHjRjVTUTEtb3FPWGc6MQ",
mode = ReportingInteractionMode.DIALOG,
resToastText = R.string.crash_toast_text, // 可选,在数据收集完毕之前弹出一个土司
resDialogText = R.string.crash_dialog_text,//对话框内容
resDialogIcon = android.R.drawable.ic_dialog_info, //可选, 对话框的图片
resDialogTitle = R.string.crash_dialog_title, // 可选,对话框的标题
resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, //可选,提示用户输入异常产生的原因等
resDialogEmailPrompt = R.string.crash_user_email_label, // optional. When defined, adds a user email text entry with this text resource as label. The email address will be populated from SharedPreferences and will be provided as an ACRA field if configured.
resDialogOkToast = R.string.crash_dialog_ok_toast // 可选,提交后弹出土司
)
public class MyApplication extends Application {
...
在strings.xml:
<string name="crash_toast_text">Ooooops ! I crashed, but a report has been sent to my developer to help fix the issue !</string>
<string name="crash_dialog_title">CrashTest has crashed</string>
<string name="crash_dialog_text">An unexpected error occurred forcing the
application to stop. Please help us fix this by sending us error data,
all you have to do is click OK.</string>
<string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string>
<string name="crash_dialog_ok_toast">Thank you !</string>
在 AndroidManifest.xml:
<application ...>
....
<activity android:name="org.acra.CrashReportDialog"
android:theme="@style/Theme.Dialog"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true" />
....
</application>
在 res/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
....
<style name="Theme.Dialog" parent="@android:style/Theme.Dialog" />
</resources>
在 res/values-v14/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
....
<style name="Theme.Dialog" parent="@android:style/Theme.DeviceDefault.Dialog" />
</resources>
- @ReportsCrashes(
resNotifTickerText = R.string.crash_notif_ticker_text,
resNotifTitle = R.string.crash_notif_title,
resNotifText = R.string.crash_notif_text,
resNotifIcon = android.R.drawable.stat_notify_error // optional. default is a warning sign
)
public class MyApplication extends Application {
...
在 strings.xml:
<!--Strings from Dialog section of wiki go here!-->
<string name="crash_notif_ticker_text">Unexpected error, please send a report...</string>
<string name="crash_notif_title">CrashTest has crashed...</string>
<string name="crash_notif_text">Please click here to help fix the issue.</string>
@ReportsCrashes(formKey = "", // will not be used
formUri = "http://yourserver.com/yourscript",
formUriBasicAuthLogin = "yourlogin", // 可选
formUriBasicAuthPassword = "y0uRpa$$w0rd", // 可选
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
...
@ReportsCrashes(formKey = "", // will not be used
mailTo = "reports@yourdomain.com",
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
...
因为数据长度的原因,提交到邮箱可能需要配置customReportContent参数:
@ReportsCrashes(formKey = "", // will not be used
mailTo = "reports@yourdomain.com",
customReportContent = { ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT },
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
...
customReportContent参数可选值有:
ReportField.USER_COMMENT
ReportField.ANDROID_VERSION
ReportField.APP_VERSION_NAME
ReportField.BRAND
ReportField.PHONE_MODEL
ReportField.CUSTOM_DATA
ReportField.STACK_TRACE
httpMethod = org.acra.sender.HttpSender.Method.POST
或者
httpMethod = org.acra.sender.HttpSender.Method.PUT (从4.5.0版本开始)
如果采用PUT方式提交,那么在提交的时候会在fromUri后拼接一段由ACRA生成的唯一的标识符,比如:
http://yourserver.com/yourscript/fe24835f-8117-4639-bfea-f57c77205771. fe24835f-8117-4639-bfea-f57c77205771
默认采用from表单的方式提交
从4.5.0版本开始,可以以Json字符串方式提交: reportType = org.acra.sender.HttpSender.Type.JSON
通过socketTimeout属性可以配置超时时间
从4.0开始,就可以配置自己的发送器了
public class YourOwnSender implements ReportSender {
public YourOwnSender(... your params ...){
// initialize your sender with needed parameters
}
@Override
public void send(CrashReportData report) throws ReportSenderException {
// Iterate over the CrashReportData instance and do whatever
// you need with each pair of ReportField key / String value
}
}
ACRA已经实现了3种发送器
GoogleFormSender: 通过HTTP POST方式发送报告到 Google Form through HTTP POST
HttpSender: 如果配置了formUri就会使用这个发送器,可以选择POST或PUT方式,数据可以采用FROM或者Json
EmailIntentSender: 选择一下字段,把他们放到Intent里,通过另一个应用来发送
配置完毕,你还需要在ACRA初始化完成后做如下操作
@Override
public void onCreate() {
ACRA.init(this);
YourOwnSender yourSender = new YourOwnSender(whatever, parameters, needed);
ACRA.getErrorReporter().setReportSender(yourSender);
super.onCreate();
}
ACRA提供了一下几种可以管理发送器的方法
setReportSender(ReportSender): 设置一个新的发送器作为唯一活动的发送器
addReportSender(ReportSender): 向发送器列表中添加一个发送器
removeReportSender(ReportSender):移除一个发送器
removeReportSenders(Class): 移除实现某个接口的所有发送器
removeAllReportSenders(): 移除所有发送器
ACRA的发送报告中提供了大量的有关设备和应用状态的信息,你可以选择发送自己所需要的信息, 也可以额外添加信息.
配置自己需要的variables或者traces
ACRA.getErrorReporter().putCustomData("myKey", "myValue");
可以使用getCustomData(“myVariable”) 或者 removeCustomData(“myVariable”) 来获得或者移除某个信息
如果想让异常报告中的日志按时间顺序显示, 那么需要做如下配置
public static void trackBreadcrumb(String event) {
ACRA.getErrorReporter().putCustomData("Event at " + System.currentTimeMillis(), event);
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
trackBreadcrumb("MyActivity.onCreate()");
...
}
如果只想选择需要的异常日志,这样配置:@ReportsCrashes(customReportContent = { 需要的字段 })
比如:
customReportContent = { APP_VERSION, ANDROID_VERSION, PHONE_MODEL, CUSTOM_DATA, STACK_TRACE, LOGCAT }
这里以添加logcat日志为例:
你只需要添加如下权限
<manifest ...>
...
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
</manifest>
这个权限默认执行命令:
adb logcat -t 200 -v time
这条命令操作, 会将 200行logcat日志(包含时间, 优先级或者tag, PID)存入异常报告
当然,你也可以配置自己的命令.比如,需要配置一条命令:
adb logcat -t 100 -v long ActivityManager:I MyApp:D *:S
那你只需在 {@ReportsCrashes}中做如下配置(其实就是把命令拆分成字符串):
logcatArguments = { "-t", "100", "-v", "long", "ActivityManager:I", "MyApp:D", "*:S" }
只需一个权限,(设备ID就是GSM手机的的IMEI 或者CMDA手机的 MEID或ESN)
<manifest ...>
...
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</manifest>