您的位置:首页 > 移动开发 > Android开发

android程序异常检测并且上传服务器

2016-11-08 15:03 295 查看
参考至:http://blog.csdn.net/i_lovefish/article/details/17719081

public class CallerHandler implements Thread.UncaughtExceptionHandler {

//系统默认的UncaughtExceotionHandler处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
private static CallerHandler instance; //单一实例
private Context context;
//用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<String, String>();
//private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private boolean isRestart = true;

//单例模式
private CallerHandler(Context context) {
this.context = context;
//初始化系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置他为当前程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}

/**
* 如果当前对象为空的时候 创建一个实例  并且返回
*/
public static CallerHandler getInstance(Context context) {
if (instance == null) {
instance = new CallerHandler(context);
}
return instance;
}

/**
* 当发生UncaughtException异常时 会自动转入这个方法中进行处理
*
* @param thread
* @param ex
*/

@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handlerException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//程序异常退出之后强制重新启动
if (isRestart) {
isRestart = false;
Intent intent = new Intent(context, LoadingActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context.getApplicationContext(), 0, intent
, Intent.FLAG_ACTIVITY_NEW_TASK);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pendingIntent);
}
Process.killProcess(Process.myPid());
System.exit(1);
}
}

/**
* 自定义错误处理,收集错误信息  发送错误报告
*
* @param ex
* @return
*/
private boolean handlerException(Throwable ex) {
if (ex == null) {
return false;
}
//手机设备参数信息
collectDeviceInfo(context);
//告知用户程序出现异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, "很抱歉,程序出现异常,即将退出\n5秒后自动重启ERE。", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}.start();
//保存日志文件
savaCatchInfo2File(ex);
return true;
}

/**
* 收集当前设备的参数信息
*
* @param context
*/
private static final String TAG = "CallerHandler";

private void collectDeviceInfo(Context context) {
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.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 (PackageManager.NameNotFoundException e) {
Log.d(TAG, "collectDeviceInfo:收集到了一条错误信息。");
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
Log.d(TAG, "collectDeviceInfo: 方法名称=" + field.getName() + ":" + field.get(null));
} catch (IllegalAccessException e) {
Log.d(TAG, "collectDeviceInfo: 收集到了一条错误信息。");
}
}
}

/**
* 保存错误日志信息
*
* @param ex
*/
private String savaCatchInfo2File(Throwable ex) {
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");
}
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();
sb.append(result);
try {
long timestamp = System.currentTimeMillis();
//String time = format.format(new Date());
//String id = "0000";
String fileName = "";
if (Flags.userLogin != null) {
String id = Flags.userLogin.getCertificateNumber();
fileName = id + "_" + timestamp + ".log";
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/EREMIS/log/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream out = new FileOutputStream(path + fileName);
out.write(sb.toString().getBytes());
out.flush();
//发送给开发人员
sendCrashLog2PM(path + fileName);
out.close();
}

return fileName;
} catch (Exception e) {
Log.d(TAG, "savaCatchInfo2File: 收集到了一条错误信息。");
}
return null;
}

/**
* 把错误日志发送给开发人员
*
* @param fileName
*/
private void sendCrashLog2PM(String fileName) {
if (!new File(fileName).exists()) {
Toast.makeText(context, "未发现错误日志", Toast.LENGTH_SHORT).show();
return;
}
InputStream in = null;
BufferedReader reader = null;
String s = null;
try {
in = new FileInputStream(fileName);
reader = new BufferedReader(new InputStreamReader(in, "GBK"));
while (true) {
s = reader.readLine();
if (s == null) {
break;
}
// TODO: 2016/11/8 上传之后删除错误日志
Log.d(TAG, "sendCrashLog2PM: 错误日志=" + s.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息