【问题标题】:Android - Crash report notificationAndroid - 崩溃报告通知
【发布时间】:2013-04-20 10:27:40
【问题描述】:

如何显示应用程序崩溃(或服务崩溃)的通知,如果用户单击它,它会通过电子邮件发送 StackTrace?
我看到一些应用程序可以做到这一点。

【问题讨论】:

  • 您看到了一些应用程序吧?那么问题出在哪里?
  • 我自己怎么做呢?我看到的是我从市场上下载的应用程序,而不是它们的源代码......

标签: android exception bug-reporting


【解决方案1】:

通过扩展接口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();
    }
}

在 MainActivity 中将 CustomExceptionHandler 设置为 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;
    }
}

注意:

上面的示例代码发送了一封包含崩溃数据的电子邮件。您可以对其进行修改以满足您的需要。

【讨论】:

    【解决方案2】:

    您可以使用ACRA 库。来自文档

    Acra 捕获异常,检索大量上下文数据并发送它们 到 Google 电子表格...或您喜欢的任何后端。

    Crittercism。它支持

    1. 错误监控
    2. 应用监控

    【讨论】:

    • 我不喜欢使用外部库
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多