Pages

April 16, 2014

Android Custom Crash Reporting Dialog & Reporting Data


MainApplication
package com.yourpkg;

import android.app.Application;
import android.content.Intent;
import android.util.Log;

public class MainApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Thread.setDefaultUncaughtExceptionHandler(new TopExceptionHandler(this));
    }

    public class TopExceptionHandler implements Thread.UncaughtExceptionHandler {

        private Application app = null;
        
        public TopExceptionHandler(Application app) {
            Thread.setDefaultUncaughtExceptionHandler(this);
            this.app = app;
        }

        public void uncaughtException(Thread t, Throwable e) {
            
            Log.v("tagas","uncaught exception ");
            
            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";

            // If the exception was thrown in a background thread inside
            // AsyncTask, then the actual exception can be found with getCause
            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";

            final String reportText=report;

            Log.d("atag","report["+report+"]");

            notifyDialog(reportText);
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
           
        }
        
        void notifyDialog(String reportText) {
            try {
                Log.d("atg", "Creating Dialog for " + reportText);
                Intent dialogIntent = new Intent(app.getApplicationContext(), CrashReportDialog.class);
                dialogIntent.putExtra("CRASH_LOG", reportText);
                dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                app.getApplicationContext().startActivity(dialogIntent);
                
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}


CrashReportDialog

package com.example.exceptionhandlr;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class CrashReportDialog extends Activity implements OnClickListener {

    String VersionName;
    String PackageName;
    String FilePath;
    String PhoneModel;
    String AndroidVersion;
    String Board;
    String Brand;
    String Device;
    String Display;
    String FingerPrint;
    String Host;
    String ID;
    String Manufacturer;
    String Model;
    String Product;
    String Tags;
    long Time;
    String Type;
    String User;
    
    Context mContext;
    String crashLog="TEXT";
    private Button buttonSubmitReport;
    private Button buttonSubmitCancle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.crashreport_activity);

        mContext = this;

        if (getIntent().getStringExtra("CRASH_LOG") != null) {
            crashLog = getIntent().getStringExtra("CRASH_LOG");
        }
        // showDialog(text);
        crashLog += CreateInformationString();

        ((TextView) findViewById(R.id.text1)).setText(crashLog);
        buttonSubmitReport = (Button) findViewById(R.id.buttonSumbmitReport);
        buttonSubmitCancle = (Button) findViewById(R.id.buttonCancleReport);
        buttonSubmitReport.setOnClickListener(this);
        buttonSubmitCancle.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.buttonSumbmitReport:
            sendEmailErrorReport(crashLog);
            break;

        case R.id.buttonCancleReport:
            restartApp();
            break;

        default:
            break;
        }
    }

    public void sendEmailErrorReport(String bodyContent) {

        final Intent emailIntent = new Intent(
                android.content.Intent.ACTION_SEND);

        // open with email supported apps
        emailIntent.setType("message/rfc822");

        // support mail from string.xml
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                new String[] { getString(R.string.support_email) });

        // AppName + Subject text from string.xml
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
                getString(R.string.app_name)+getString(R.string.support_crash_subj));

        // Inital body text from string.xml + crash log 
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
                getString(R.string.support_crash_body) + bodyContent);

        finish();
        
        startActivity(Intent.createChooser(emailIntent, "Send Report"));

        // restart app
        // restartApp();
        
    }

    public void restartApp() {
        Intent i = getBaseContext().getPackageManager()
                .getLaunchIntentForPackage(getBaseContext().getPackageName());
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        
        finish();
        startActivity(i);
    }
    

    void RecoltInformations(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi;
            // Version
            pi = pm.getPackageInfo(context.getPackageName(), 0);
            VersionName = pi.versionName;
            // Package name
            PackageName = pi.packageName;
            // Device model
            PhoneModel = android.os.Build.MODEL;
            // Android version
            AndroidVersion = android.os.Build.VERSION.RELEASE;

            Board = android.os.Build.BOARD;
            Brand = android.os.Build.BRAND;
            Device = android.os.Build.DEVICE;
            Display = android.os.Build.DISPLAY;
            FingerPrint = android.os.Build.FINGERPRINT;
            Host = android.os.Build.HOST;
            ID = android.os.Build.ID;
            Model = android.os.Build.MODEL;
            Product = android.os.Build.PRODUCT;
            Tags = android.os.Build.TAGS;
            Time = android.os.Build.TIME;
            Type = android.os.Build.TYPE;
            User = android.os.Build.USER;

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String CreateInformationString() {
        RecoltInformations(mContext);

        String ReturnVal = "";
        ReturnVal += "Version : " + VersionName;
        ReturnVal += "\n";
        ReturnVal += "Package : " + PackageName;
        ReturnVal += "\n";
        ReturnVal += "FilePath : " + FilePath;
        ReturnVal += "\n";
        ReturnVal += "Phone Model" + PhoneModel;
        ReturnVal += "\n";
        ReturnVal += "Android Version : " + AndroidVersion;
        ReturnVal += "\n";
        ReturnVal += "Board : " + Board;
        ReturnVal += "\n";
        ReturnVal += "Brand : " + Brand;
        ReturnVal += "\n";
        ReturnVal += "Device : " + Device;
        ReturnVal += "\n";
        ReturnVal += "Display : " + Display;
        ReturnVal += "\n";
        ReturnVal += "Finger Print : " + FingerPrint;
        ReturnVal += "\n";
        ReturnVal += "Host : " + Host;
        ReturnVal += "\n";
        ReturnVal += "ID : " + ID;
        ReturnVal += "\n";
        ReturnVal += "Model : " + Model;
        ReturnVal += "\n";
        ReturnVal += "Product : " + Product;
        ReturnVal += "\n";
        ReturnVal += "Tags : " + Tags;
        ReturnVal += "\n";
        ReturnVal += "Time : " + Time;
        ReturnVal += "\n";
        ReturnVal += "Type : " + Type;
        ReturnVal += "\n";
        ReturnVal += "User : " + User;
        ReturnVal += "\n";
        // ReturnVal += "Total Internal memory : " +
        // getTotalInternalMemorySize();
        // ReturnVal += "\n";
        // ReturnVal += "Available Internal memory : "
        // + getAvailableInternalMemorySize();
        ReturnVal += "\n";

        return ReturnVal;
    }

}


MainActivity

package com.example.exceptionhandlr;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        
        findViewById(R.id.buttonCreateCrash).setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {

                // DIVIDE by ZERO Error
                // THIS LINE CAUSE EXCEPTION
                int i=55/0;
            }
        });
        
    }
}