packagecom.cquni.app;importjava.io.File;importjava.io.FileOutputStream;importjava.io.PrintWriter;importjava.io.StringWriter;importjava.io.Writer;importjava.lang.Thread.UncaughtExceptionHandler;importjava.lang.reflect.Field;importjava.text.DateFormat;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Date;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importandroid.content.Context;importandroid.content.pm.PackageInfo;importandroid.content.pm.PackageManager;importandroid.content.pm.PackageManager.NameNotFoundException;importandroid.os.AsyncTask;importandroid.os.Build;importandroid.os.Environment;importandroid.os.Looper;importandroid.util.Log;importandroid.widget.Toast;importcom.cquni.dto.WebApiResultMessage;importcom.cquni.utils.JSONHttpClient;importorg.apache.http.NameValuePair;importorg.apache.http.message.BasicNameValuePair;/*** UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
*
*@authoruser
**/
public class CrashHandler implementsUncaughtExceptionHandler {public static final String TAG = "CrashHandler";//系统默认的UncaughtException处理类
privateThread.UncaughtExceptionHandler mDefaultHandler;//CrashHandler实例
private static CrashHandler INSTANCE = newCrashHandler();//程序的Context对象
privateContext mContext;//用来存储设备信息和异常信息
private Map infos = new HashMap();//用于格式化日期,作为日志文件名的一部分
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");/**保证只有一个CrashHandler实例*/
privateCrashHandler() {
}/**获取CrashHandler实例 ,单例模式*/
public staticCrashHandler getInstance() {returnINSTANCE;
}/*** 初始化
*
*@paramcontext*/
public voidinit(Context context) {
mContext=context;//获取系统默认的UncaughtException处理器
mDefaultHandler =Thread.getDefaultUncaughtExceptionHandler();//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}/*** 当UncaughtException发生时会转入该函数来处理*/@Overridepublic voiduncaughtException(Thread thread, Throwable ex) {if (!handleException(ex) && mDefaultHandler != null) {//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
}else{try{
Thread.sleep(3000);
}catch(InterruptedException e) {
Log.e(TAG,"error : ", e);
}finally{//退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
}/*** 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*
*@paramex
*@returntrue:如果处理了该异常信息;否则返回false.*/
private booleanhandleException(Throwable ex) {if (ex == null) {return false;
}//收集设备参数信息
collectDeviceInfo(mContext);//保存日志文件
saveCrashInfo2File(ex);return true;
}/*** 收集设备参数信息
*
*@paramctx*/
public voidcollectDeviceInfo(Context ctx) {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 + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
}catch(NameNotFoundException e) {
Log.e(TAG,"an error occured when collect package info", e);
}
Field[] fields= Build.class.getDeclaredFields();for(Field field : fields) {try{
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
Log.d(TAG, field.getName()+ " : " + field.get(null));
}catch(Exception e) {
Log.e(TAG,"an error occured when collect crash info", e);
}
}
}/*** 保存错误信息到文件中
*
*@paramex
*@return返回文件名称,便于将文件传送到服务器*/
privateString saveCrashInfo2File(Throwable ex) {
StringBuffer sb= newStringBuffer();for (Map.Entryentry : infos.entrySet()) {
String key=entry.getKey();
String value=entry.getValue();
sb.append(key+ "=" + value + "\n");
}
Writer writer= newStringWriter();
PrintWriter printWriter= newPrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause=ex.getCause();while (cause != null) {
cause.printStackTrace(printWriter);
cause=cause.getCause();
}
printWriter.close();
String result=writer.toString();
sb.append(result);try{long timestamp =System.currentTimeMillis();
String time= formatter.format(newDate());
String fileName= "crash-" + time + "-" + timestamp + ".log";
String path= Environment.getExternalStorageDirectory()+"/wcs_log";
File dir= newFile(path);if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos= new FileOutputStream(path +"/"+fileName);
fos.write(sb.toString().getBytes());
fos.flush();
fos.close();returnfileName;
}catch(Exception e) {
Log.e(TAG,"an error occured while writing file...", e);
}//上传到服务器
newPostErrorLoggerTask().execute(sb.toString());return null;
}/*** 提交错误日志到服务器*/
class PostErrorLoggerTask extends AsyncTask{
@OverrideprotectedWebApiResultMessage doInBackground(String... messageText) {
WebApiResultMessage rs= newWebApiResultMessage();
rs.setMessage("");
rs.setResult(null);
rs.setSuccess(false);
JSONHttpClient jsonHttpClient= newJSONHttpClient();
List params = newArrayList();
params.add(new BasicNameValuePair("errorMessage", messageText[0]));
params.add(new BasicNameValuePair("logType", "Error"));
String url= "http://192.168.122.5:5990/SmartWCS/UpLoadPDA_Logger";try{return jsonHttpClient.PostJsonObject(url, "{}", params);
}catch(Exception e) {
e.printStackTrace();
rs.setMessage(e.getMessage());
}returnrs;
}
}
}