这里是关于如何设置自己的崩溃报告的完整说明,当您的应用程序再次启动并要求用户通过电子邮件发送日志时,它将向用户显示如下对话框:
![enter image description here](https://istack.dev59.com/xEEit.webp)
1- 创建一个名为UnexpectedCrashSaver的类:
public class UnexpectedCrashSaver implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler defaultUEH;
private Context app = null;
public UnexpectedCrashSaver(Context app) {
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
this.app = app;
}
public void uncaughtException(Thread t, Throwable e) {
StackTraceElement[] arr = e.getStackTrace();
String report = e.toString()+"\n\n";
report += "--------- Stack trace ---------\n\n";
for (int i=0; i<arr.length; i++) {
report += " "+arr[i].toString()+"\n";
}
report += "-------------------------------\n\n";
App.instance().toastShort("saving!");
report += "--------- Cause ---------\n\n";
Throwable cause = e.getCause();
if(cause != null) {
report += cause.toString() + "\n\n";
arr = cause.getStackTrace();
for (int i=0; i<arr.length; i++) {
report += " "+arr[i].toString()+"\n";
}
}
report += "-------------------------------\n\n";
try {
FileOutputStream trace = app.openFileOutput("stack.trace",
Context.MODE_PRIVATE);
trace.write(report.getBytes());
trace.close();
} catch(IOException ioe) {
}
defaultUEH.uncaughtException(t, e);
}
}
2- 在Application类的onCreate()方法中添加以下代码:
Thread.setDefaultUncaughtExceptionHandler(new UnexpectedCrashSaver(this))
如果您没有应用程序类,请将以下代码添加到所有活动的onCreate()方法中:(如果您有BaseActivity,请将其放在BaseActivity的onCreate()方法中)
Thread.setDefaultUncaughtExceptionHandler(new UnexpectedCrashSaver(ActivityName.this))
3- 创建一个名为checkbox.xml的布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<CheckBox
android:id="@+id/checkbox"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp" />
</FrameLayout>
4- 将以下方法添加到你的 MainActivity 类中:
private void checkForCrash()
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean crash_never_ask_again = preferences.getBoolean("crash_never_ask_again", false);
if(crash_never_ask_again)
return;
String dialog_message = "In the last run, the program encountered an error, we apologize for this, you can kindly send us the error information to fix this error in future updates.";
String button_positive_text = "Send";
String button_negative_text = "Close";
String checkbox_text = "Never ask again";
String email = "crashreport@example.com";
String line;
String trace="";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(MainActivity.this.openFileInput("stack.trace")));
while((line = reader.readLine()) != null) {
trace += line+"\n";
}
} catch(FileNotFoundException fnfe) {
} catch(IOException ioe) {
}
if(trace.length() < 10)
return;
View checkBoxView = View.inflate(this, R.layout.checkbox, null);
CheckBox checkBox = checkBoxView.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("checkbox_checked",true);
editor.apply();
}
});
checkBox.setText(checkbox_text);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setMessage(dialog_message);
builder.setView(checkBoxView);
builder.setCancelable(false);
String finalTrace = trace;
builder.setPositiveButton(button_positive_text, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent sendIntent = new Intent(Intent.ACTION_SEND);
String subject = "Error report";
String body = "Mail this to appdeveloper@gmail.com: " + "\n" + finalTrace + "\n";
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {email});
sendIntent.putExtra(Intent.EXTRA_TEXT, body);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sendIntent.setType("message/rfc822");
MainActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));
MainActivity.this.deleteFile("stack.trace");
}
});
builder.setNegativeButton(button_negative_text, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MainActivity.this.deleteFile("stack.trace");
boolean checkbox_checked = preferences.getBoolean("checkbox_checked", false);
if(checkbox_checked)
{
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("crash_never_ask_again",true);
editor.apply();
}
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
5- 在MainActivity的onCreate方法中调用第4步创建的方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkForCrash();
setContentView(R.layout.activity_main);
这就是全部啦!