An interesting post..
Everytime you write an app, it may or may not crash and we often see the “Force Close” Dialog.
But what if we can customize the “Force Close” Dialog itself.
This is done using “UncaughtExceptionHandler” class.
This post explains this.
here I am knowingly crashing the application like this
int y = 5/0;
Now this is my MainActivity that is going to crash.
package com.coderzheaven.forceclosecustomize; import android.app.Activity; import android.os.Bundle; 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; } }
And this is the Class that captures the Force Close Dialog and shows our CustomDialog.
UnCaughtException.java
package com.coderzheaven.forceclosecustomize; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; import java.util.Date; import java.util.Locale; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Environment; import android.os.Looper; import android.os.StatFs; import android.util.Log; 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'); } 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[] { "coderzheaven@gmail.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(); } }
Very good, but this way the app won’t close…
Sorry, it works pretty well… I just forgot the System.exit
Hi,Nice work…but I wan’t to ask whether we can replace email part with actual error reporting mechanism of google
Hi, if not clicking cancel or Report and clicking back button .that time application not responsing please wait or close pop up got.
Pingback: Android: Catch Error “Unfortunately 'app' has stopped working” [closed] - Tutorial Guruji
Pingback: Android: Catch Error "Unfortunately 'app' has stopped working"