一、什么是ACRA
ACRA全称: Application Crash Report for Android.
顾名思义, ACRA是一个优秀的Android异常日志收集的开源框架. 利用他可以轻松的实现Android APP 异常日志的收集.
下载地址: https://github.com/ACRA/acra
二、优点
A.异常报告的几种提交方式:
静默提交(默认)
土司提醒
状态栏+对话框提醒
对话框提醒( since 4.3.0b1)
B.可以在报告随意添加自己的内容
C.应用未崩溃的情况下, 也可以发送报告
D.如果没有网络,异常日志会暂时保存,连接网络后再发送
E.可以同 自托管报告接收脚本 一起使用
F.使用除静默提交外的任何一种提交方式, 系统自带的”强制关闭”对话框将不再弹出, 并且不会在要求发送异常报告.
G.允许发送报告到多种终端:
Google Docs spreadsheet(废弃)
服务器的HTTP POST脚本
各种终端
通过实现自己的report sender可以向更多的终端发送报告
通过右键发送
三、使用步骤
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,那么请继续往下看…
四、更多配置
1.报告提交方式的配置
上面讲的是静默提交方式的配置,我们再来说说其他几种方式
土司提醒:
@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>
2.提交终端的配置
提交到自己的服务器
fromUri也可以采用https方式
默认采用POST方式提交
从ACRA 4.4.0开始,如果发送报告的方式是通过自定义的SSL,需要设置ReportsCrashes.disableSSLCertValidation = true
@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
3.提交方式的配置
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
4.提交的数据的形式
默认采用from表单的方式提交
从4.5.0版本开始,可以以Json字符串方式提交: reportType = org.acra.sender.HttpSender.Type.JSON
5.配置超时时间
通过socketTimeout属性可以配置超时时间
6.配置自己的发送器
从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(): 移除所有发送器
7.配置发送报告的内容
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 }
8.添加 logcat, eventlog 或者 radiolog 到异常报告
这里以添加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" }
9.添加设备ID到异常报告
只需一个权限,(设备ID就是GSM手机的的IMEI 或者CMDA手机的 MEID或ESN)
<manifest ...> ... <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> </manifest>