如何显示应用程序崩溃(或服务崩溃)的通知,如果用户点击它,它会通过电子邮件发送StackTrace?
我看到了一些应用程序。
答案 0 :(得分:11)
通过扩展界面UncaughtExceptionHandler
public class UnCaughtException implements UncaughtExceptionHandler
{
private Context context;
private static Context context1;
public UnCaughtException(Context ctx)
{
context = ctx;
context1 = ctx;
}
private StatFs getStatFs()
{
File path = Environment.getDataDirectory();
return new StatFs(path.getPath());
}
private long getAvailableInternalMemorySize(StatFs stat)
{
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
private long getTotalInternalMemorySize(StatFs stat)
{
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
}
private void addInformation(StringBuilder message)
{
message.append("Locale: ").append(Locale.getDefault()).append('\n');
try
{
PackageManager pm = context.getPackageManager();
PackageInfo pi;
pi = pm.getPackageInfo(context.getPackageName(), 0);
message.append("Version: ").append(pi.versionName).append('\n');
message.append("Package: ").append(pi.packageName).append('\n');
}
catch ( Exception e )
{
Log.e("CustomExceptionHandler", "Error", e);
message.append("Could not get Version information for ").append(context.getPackageName());
}
message.append("Phone Model: ").append(android.os.Build.MODEL).append('\n');
message.append("Android Version: ").append(android.os.Build.VERSION.RELEASE).append('\n');
message.append("Board: ").append(android.os.Build.BOARD).append('\n');
message.append("Brand: ").append(android.os.Build.BRAND).append('\n');
message.append("Device: ").append(android.os.Build.DEVICE).append('\n');
message.append("Host: ").append(android.os.Build.HOST).append('\n');
message.append("ID: ").append(android.os.Build.ID).append('\n');
message.append("Model: ").append(android.os.Build.MODEL).append('\n');
message.append("Product: ").append(android.os.Build.PRODUCT).append('\n');
message.append("Type: ").append(android.os.Build.TYPE).append('\n');
StatFs stat = getStatFs();
message.append("Total Internal memory: ").append(getTotalInternalMemorySize(stat)).append('\n');
message.append("Available Internal memory: ").append(getAvailableInternalMemorySize(stat)).append('\n');
}
@Override
public void uncaughtException(Thread t, Throwable e)
{
try
{
StringBuilder report = new StringBuilder();
Date curDate = new Date();
report.append("Error Report collected on : ").append(curDate.toString()).append('\n').append('\n');
report.append("Informations :").append('\n');
addInformation(report);
report.append('\n').append('\n');
report.append("Stack:\n");
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
report.append(result.toString());
printWriter.close();
report.append('\n');
report.append("**** End of current Report ***");
Log.e(UnCaughtException.class.getName(), "Error while sendErrorMail" + report);
sendErrorMail(report);
}
catch ( Throwable ignore )
{
Log.e(UnCaughtException.class.getName(), "Error while sending error e-mail", ignore);
}
}
/**
* This method for call alert dialog when application crashed!
*/
public void sendErrorMail(final StringBuilder errorContent)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
new Thread()
{
@Override
public void run()
{
Looper.prepare();
builder.setTitle("Sorry...!");
builder.create();
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
System.exit(0);
}
});
builder.setPositiveButton("Report", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
Intent sendIntent = new Intent(Intent.ACTION_SEND);
String subject = "Your App crashed! Fix it!";
StringBuilder body = new StringBuilder("Yoddle");
body.append('\n').append('\n');
body.append(errorContent).append('\n').append('\n');
// sendIntent.setType("text/plain");
sendIntent.setType("message/rfc822");
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "yourmail@domain.com" });
sendIntent.putExtra(Intent.EXTRA_TEXT, body.toString());
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sendIntent.setType("message/rfc822");
context1.startActivity(sendIntent);
System.exit(0);
}
});
builder.setMessage("Oops,Your application has crashed");
builder.show();
Looper.loop();
}
}.start();
}
}
将CustomExceptionHandler设置为MainActivity中的DefaultExceptionHandler
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtException(MainActivity.this));
int y = 5 / 0;
}
}
注意:
以上示例代码发送包含崩溃数据的电子邮件。您可以对其进行修改以满足您的需求。
答案 1 :(得分:1)
您可以使用ACRA库。来自doc
Acra捕获异常,检索大量上下文数据并发送它们 到Google电子表格......或者您喜欢的任何后端。
或Crittercism。它支持
- 错误监控
- App Monitoring
醇>