package com.android.pc.util; import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Field; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; /** * <h3>错误拦截类</h3> * * @author Administrator 2012-12-2 上午1:58:37 */ public class ExceptionHandler implements UncaughtExceptionHandler { private static final String TAG = ExceptionHandler.class.getSimpleName(); private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); private static ExceptionHandler INSTANCE; private Context context; // 用来存储设备信息和异常信息 private Map<String, String> infos = new HashMap<String, String>(); private boolean isSave = false; private String filename; private String fileDirs; private Handler handler = null; private HashMap<String, String> exceptionBean; /** * 获取拦截器的对象 * * @author Administrator 2012-12-2 上午1:58:57 * @param context * @return * @return ExceptionHandler */ public static ExceptionHandler getInstance(Context context) { if (INSTANCE == null) { INSTANCE = new ExceptionHandler(context); } return INSTANCE; } /** * 如果需要在异常以后处理什么信息 请传入handler * * @author gdpancheng@gmail.com 2013-3-13 下午6:07:19 * @param handler * @return void */ public void SetHandler(Handler handler) { this.handler = handler; } /** * 设置是否保存日志文件 默认不保存 记得设置sd卡读取权限 * * @author pancheng 2012-10-23 下午9:53:37 * @param isSave * @return void */ public void setSave(boolean isSave) { this.isSave = isSave; } /** * 当保存文件的前提下 设置文件名称 文件(名称-时间-毫秒数.log) * * @author pancheng 2012-10-23 下午9:54:04 * @param filename * @return void */ public void setFilename(String filename) { this.filename = filename; } /** * 当保存文件的前提下 设置保存目录 如/sdcard/logs/ * * @author pancheng 2012-10-23 下午9:55:12 * @param fileDirs * @return void */ public void setFileDirs(String fileDirs) { this.fileDirs = fileDirs; } public ExceptionHandler(Context context) { // 设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); this.context = context; } @Override public void uncaughtException(Thread thread, Throwable ex) { final String msg = collectDeviceInfo(context, ex); // Intent localIntent = new Intent(context, ExceptionActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // localIntent.putExtra("projectName", exceptionBean.get("projectName")); // // localIntent.putExtra("versionName", exceptionBean.get("versionName")); // localIntent.putExtra("versionCode", exceptionBean.get("versionCode")); // localIntent.putExtra("devInfo", exceptionBean.get("devInfo")); // // localIntent.putExtra("exceptionMsg", exceptionBean.get("exceptionMsg")); // context.startActivity(localIntent); if (handler != null) { Message message = new Message(); message.obj = msg; handler.sendMessage(message); } System.out.println("错误:" + msg); if (isSave && filename != null && fileDirs != null) { new Thread(new Runnable() { @Override public void run() { saveCrashInfoToFile(msg); } }).start(); } // ex.printStackTrace(); // android.os.Process.killProcess(android.os.Process.myPid()); } /** * 收集设备参数信息 * * @param ctx */ private String collectDeviceInfo(Context ctx, Throwable ex) { exceptionBean = new HashMap<String, String>(); exceptionBean.put("projectName", ctx.getApplicationInfo().loadLabel(ctx.getPackageManager()).toString()); try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; exceptionBean.put("versionName", versionName); exceptionBean.put("versionCode", versionCode); } } catch (NameNotFoundException e) { } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString()); } catch (Exception e) { } } StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } exceptionBean.put("devInfo", sb.toString()); Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); exceptionBean.put("exceptionMsg", result); return sb.toString(); } /** * 保存错误信息到文件中 * * @param ex * @return 返回文件名称,便于将文件传送到服务器 */ private String saveCrashInfoToFile(String msg) { try { long timestamp = System.currentTimeMillis(); String time = formatter.format(new Date()); String fileName = filename + "-" + time + "-" + timestamp + ".log"; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { String path = fileDirs; if (!path.startsWith("/") || !path.endsWith("/")) { Log.e(TAG, "the file path is err"); return null; } File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName); fos.write(msg.getBytes()); fos.close(); } return fileName; } catch (Exception e) { Log.e(TAG, "an error occured while writing file...", e); } return null; } }