package com.door43.tools.reporting; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; /** * This class write exceptions to a file on disk before killing the app * This allows you to retrieve them later for debugging. * http://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application */ public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler { private static final String STACKTRACE_EXT = "stacktrace"; private Thread.UncaughtExceptionHandler defaultUEH; private final String mStracktraceDir; /** * if any of the parameters is null, the respective functionality * will not be used * @param stacktraceDir */ public GlobalExceptionHandler(File stacktraceDir) { if(!stacktraceDir.exists()) { stacktraceDir.mkdirs(); } this.mStracktraceDir = stacktraceDir.getAbsolutePath(); this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); } /** * Registers the exception handler as the global exception handler for the app * @param stacktraceDirectory the directory where the stacktrace files will be stored */ public static void register(File stacktraceDirectory) { if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof GlobalExceptionHandler)) { Thread.setDefaultUncaughtExceptionHandler(new GlobalExceptionHandler(stacktraceDirectory)); } } /** * Returns a list of stacktrace files found in the directory * @param stacktraceDir * @return */ public static String[] getStacktraces(File stacktraceDir) { String[] files = stacktraceDir.list(new FilenameFilter() { @Override public boolean accept(File dir, String filename) { String pieces[] = filename.split("\\."); String ext = pieces[pieces.length - 1]; return new File(dir, filename).isFile() && ext.equals(STACKTRACE_EXT); } }); // build full path String[] stacktraces = new String[files.length]; for(int i = 0; i < files.length; i ++) { stacktraces[i] = new File(stacktraceDir, files[i]).getAbsolutePath(); } return stacktraces; } /** * Handles the uncaught exception * @param t * @param e */ public void uncaughtException(Thread t, Throwable e) { Long tsLong = System.currentTimeMillis(); String timestamp = tsLong.toString(); final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); e.printStackTrace(printWriter); String stacktrace = result.toString(); printWriter.close(); String filename = timestamp + "." + STACKTRACE_EXT; if (mStracktraceDir != null) { writeToFile(stacktrace, filename); } defaultUEH.uncaughtException(t, e); } /** * Writes the stacktrace to the log directory * @param stacktrace * @param filename */ public void writeToFile(String stacktrace, String filename) { try { BufferedWriter bos = new BufferedWriter(new FileWriter( mStracktraceDir + "/" + filename)); bos.write(stacktrace); bos.flush(); bos.close(); } catch (Exception e) { e.printStackTrace(); } } }