package com.qmusic.common; import java.io.File; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Field; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Looper; import android.util.Log; import android.widget.Toast; import com.qmusic.MyApplication; import com.qmusic.uitls.BLog; public class BCrashHandler implements UncaughtExceptionHandler { public static final String TAG = "CrashHandler"; /** Default UncaughtException handler */ private Thread.UncaughtExceptionHandler mDefaultHandler; private static BCrashHandler INSTANCE; private Context mContext; private static final String CRASH_REPORTER_EXTENSION = ".txt"; private static String CRASHFILEPATH; private BCrashHandler() { } public static void init(Context ctx) { if (INSTANCE == null) { INSTANCE = new BCrashHandler(); } INSTANCE.mContext = ctx; INSTANCE.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(INSTANCE); File cacheDir = ctx.getExternalCacheDir(); if (cacheDir != null) { CRASHFILEPATH = cacheDir.toString(); } else { CRASHFILEPATH = ctx.getCacheDir().toString(); } } @Override public void uncaughtException(Thread arg0, Throwable arg1) { if (!handleException(arg1) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(arg0, arg1); } else { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); } } private boolean handleException(Throwable ex) { if (ex == null) { return true; } final String msg = ex.getLocalizedMessage(); new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(MyApplication.getContext(), msg, Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); saveCrashInfoToFile(ex); return true; } public static void sendCrashReportsToServer() { } public static String[] getCrashReportFiles() { File filesDir = new File(CRASHFILEPATH); FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(CRASH_REPORTER_EXTENSION); } }; String[] crFilesPath = filesDir.list(filter); for (int i = 0; i < crFilesPath.length; i++) { crFilesPath[i] = CRASHFILEPATH + crFilesPath[i]; BLog.i(TAG, "upload crash file :" + crFilesPath[i]); } return crFilesPath; } private String saveCrashInfoToFile(Throwable ex) { Writer info = new StringWriter(); PrintWriter printWriter = new PrintWriter(info); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } try { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { printWriter.append("\r\n" + pi.versionName); printWriter.append("\r\nversionCode=" + pi.versionCode); } } catch (NameNotFoundException e) { Log.e(TAG, "Error while collect package info", e); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); printWriter.append("\r\n" + field.getName() + ": " + field.get(null)); } catch (Exception e) { Log.e(TAG, "Error while collect crash info", e); } } String result = info.toString(); printWriter.close(); try { long timestamp = System.currentTimeMillis(); String fileName = CRASHFILEPATH + "crash-" + timestamp + CRASH_REPORTER_EXTENSION; FileWriter writer = new FileWriter(fileName, true); writer.write(result); writer.flush(); writer.close(); return fileName; } catch (Exception e) { Log.e(TAG, "an error occured while writing report file...", e); } return null; } }