package com.emato.ich.crash; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.Environment; import android.os.Looper; import com.emato.ich.utils.Log; import android.widget.Toast; import com.emato.ich.MainActivity; import com.emato.ich.message.ICHPublishClient; import com.emato.ich.message.ICHTopic; import com.emato.ich.utils.BaseUtils; import com.emato.ich.utils.LoggingUtils; import org.eclipse.paho.client.mqttv3.MqttMessage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Field; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHandler { private static final String TAG = UncaughtExceptionHandlerImpl.class.getName(); private static UncaughtExceptionHandlerImpl INSTANCE; private Thread.UncaughtExceptionHandler mDefaultHandler; private Context mContext; private Map infos = new HashMap(); @SuppressLint({"SimpleDateFormat"}) private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); private boolean mIsDebug; private boolean mIsRestartApp; private long mRestartTime; private Class mRestartActivity; private String mTips; private UncaughtExceptionHandlerImpl() { } public static UncaughtExceptionHandlerImpl getInstance() { if (INSTANCE == null) { INSTANCE = new UncaughtExceptionHandlerImpl(); } return INSTANCE; } public void init(Context context, boolean isDebug, boolean isRestartApp, long restartTime, Class restartActivity) { this.mIsRestartApp = isRestartApp; this.mRestartTime = restartTime; this.mRestartActivity = restartActivity; this.init(context, isDebug); } public void init(Context context, boolean isDebug) { this.mTips = "很抱歉,程序出现异常,即将退出..."; this.mIsDebug = isDebug; this.mContext = context; this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } @SuppressLint("WrongConstant") public void uncaughtException(Thread thread, Throwable ex) { LoggingUtils.sendErrorLog("系统异常: 崩溃异常! ", ex); if (!this.handleException(ex) && this.mDefaultHandler != null) { this.mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(1000L); } catch (InterruptedException var6) { Log.e(TAG, "error 出现未知异常: ", var6); LoggingUtils.sendErrorLog("系统异常: 线程中断异常! ", var6); } if (this.mIsRestartApp) { Intent intent = new Intent(this.mContext.getApplicationContext(), this.mRestartActivity); @SuppressLint("WrongConstant") AlarmManager mAlarmManager = (AlarmManager)this.mContext.getSystemService(Context.ALARM_SERVICE); @SuppressLint("WrongConstant") PendingIntent restartIntent = PendingIntent.getActivity(this.mContext.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + this.mRestartTime, restartIntent); } // android.os.Process.killProcess(android.os.Process.myPid()); ((CrashApplication)this.mContext.getApplicationContext()).removeAllActivity(); } } private boolean handleException(final Throwable ex) { if (ex == null) { return false; } else { (new Thread() { @SuppressLint("WrongConstant") public void run() { Looper.prepare(); // Toast.makeText(UncaughtExceptionHandlerImpl.this.mContext, UncaughtExceptionHandlerImpl.this.getTips(ex), 1).show(); Toast.makeText(UncaughtExceptionHandlerImpl.this.mContext, "很抱歉,程序出现异常,即将退出...", 1).show(); Looper.loop(); } }).start(); return true; } } private String getTips(Throwable ex) { if (ex instanceof SecurityException) { if (ex.getMessage().contains("android.permission.CAMERA")) { this.mTips = "请授予应用相机权限,程序出现异常,即将退出."; } else if (ex.getMessage().contains("android.permission.RECORD_AUDIO")) { this.mTips = "请授予应用麦克风权限,程序出现异常,即将退出。"; } else if (ex.getMessage().contains("android.permission.WRITE_EXTERNAL_STORAGE")) { this.mTips = "请授予应用存储权限,程序出现异常,即将退出。"; } else if (ex.getMessage().contains("android.permission.READ_PHONE_STATE")) { this.mTips = "请授予应用电话权限,程序出现异常,即将退出。"; } else if (!ex.getMessage().contains("android.permission.ACCESS_COARSE_LOCATION") && !ex.getMessage().contains("android.permission.ACCESS_FINE_LOCATION")) { this.mTips = "很抱歉,程序出现异常,即将退出,请检查应用权限设置。"; } else { this.mTips = "请授予应用位置信息权,很抱歉,程序出现异常,即将退出。"; } } return this.mTips; } public void collectDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); @SuppressLint("WrongConstant") PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), 1); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; this.infos.put("versionName", versionName); this.infos.put("versionCode", versionCode); } } catch (PackageManager.NameNotFoundException var9) { Log.e(TAG, "an error occured when collect package info", var9); LoggingUtils.sendErrorLog("业务异常: an error occured when collect package info! ", var9); } Field[] fields = Build.class.getDeclaredFields(); Field[] var11 = fields; int var12 = fields.length; for(int var13 = 0; var13 < var12; ++var13) { Field field = var11[var13]; try { field.setAccessible(true); this.infos.put(field.getName(), field.get((Object)null).toString()); Log.i(TAG, field.getName() + " : " + field.get((Object)null)); } catch (Exception var8) { Log.e(TAG, "an error occured when collect crash info", var8); LoggingUtils.sendErrorLog("业务异常: an error occured when collect crash info! ", var8); } } } private String saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); Iterator var3 = this.infos.entrySet().iterator(); String result; while(var3.hasNext()) { Map.Entry entry = (Map.Entry)var3.next(); String key = (String)entry.getKey(); result = (String)entry.getValue(); sb.append(key + "=" + result + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); for(Throwable cause = ex.getCause(); cause != null; cause = cause.getCause()) { cause.printStackTrace(printWriter); } printWriter.close(); result = writer.toString(); sb.append(result); try { long timestamp = System.currentTimeMillis(); String time = this.formatter.format(new Date()); String fileName = "crash-" + time + "-" + timestamp + ".log"; if (Environment.getExternalStorageState().equals("mounted")) { String path = "/sdcard/" + this.mContext.getPackageName() + "/crash/"; File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName); fos.write(sb.toString().getBytes()); fos.close(); } return fileName; } catch (Exception var14) { Log.e(TAG, "an error occured while writing file...", var14); LoggingUtils.sendErrorLog("业务异常: an error occured while writing file... ", var14); return null; } } }