UncaughtExceptionHandlerImpl.java 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package com.emato.ich.crash;
  2. import android.annotation.SuppressLint;
  3. import android.app.AlarmManager;
  4. import android.app.PendingIntent;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.pm.PackageInfo;
  8. import android.content.pm.PackageManager;
  9. import android.os.Build;
  10. import android.os.Environment;
  11. import android.os.Looper;
  12. import android.util.Log;
  13. import android.widget.Toast;
  14. import java.io.File;
  15. import java.io.FileOutputStream;
  16. import java.io.PrintWriter;
  17. import java.io.StringWriter;
  18. import java.io.Writer;
  19. import java.lang.reflect.Field;
  20. import java.text.DateFormat;
  21. import java.text.SimpleDateFormat;
  22. import java.util.Date;
  23. import java.util.HashMap;
  24. import java.util.Iterator;
  25. import java.util.Map;
  26. public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHandler {
  27. private static final String TAG = UncaughtExceptionHandlerImpl.class.getName();
  28. private static UncaughtExceptionHandlerImpl INSTANCE;
  29. private Thread.UncaughtExceptionHandler mDefaultHandler;
  30. private Context mContext;
  31. private Map<String, String> infos = new HashMap();
  32. @SuppressLint({"SimpleDateFormat"})
  33. private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
  34. private boolean mIsDebug;
  35. private boolean mIsRestartApp;
  36. private long mRestartTime;
  37. private Class mRestartActivity;
  38. private String mTips;
  39. private UncaughtExceptionHandlerImpl() {
  40. }
  41. public static UncaughtExceptionHandlerImpl getInstance() {
  42. if (INSTANCE == null) {
  43. INSTANCE = new UncaughtExceptionHandlerImpl();
  44. }
  45. return INSTANCE;
  46. }
  47. public void init(Context context, boolean isDebug, boolean isRestartApp, long restartTime, Class restartActivity) {
  48. this.mIsRestartApp = isRestartApp;
  49. this.mRestartTime = restartTime;
  50. this.mRestartActivity = restartActivity;
  51. this.init(context, isDebug);
  52. }
  53. public void init(Context context, boolean isDebug) {
  54. this.mTips = "很抱歉,程序出现异常,即将退出...";
  55. this.mIsDebug = isDebug;
  56. this.mContext = context;
  57. this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  58. Thread.setDefaultUncaughtExceptionHandler(this);
  59. }
  60. @SuppressLint("WrongConstant")
  61. public void uncaughtException(Thread thread, Throwable ex) {
  62. if (!this.handleException(ex) && this.mDefaultHandler != null) {
  63. this.mDefaultHandler.uncaughtException(thread, ex);
  64. } else {
  65. try {
  66. Thread.sleep(2000L);
  67. } catch (InterruptedException var6) {
  68. Log.e(TAG, "error : ", var6);
  69. }
  70. if (this.mIsRestartApp) {
  71. Intent intent = new Intent(this.mContext.getApplicationContext(), this.mRestartActivity);
  72. @SuppressLint("WrongConstant") AlarmManager mAlarmManager = (AlarmManager)this.mContext.getSystemService(Context.ALARM_SERVICE);
  73. @SuppressLint("WrongConstant") PendingIntent restartIntent = PendingIntent.getActivity(this.mContext.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  74. mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + this.mRestartTime, restartIntent);
  75. }
  76. android.os.Process.killProcess(android.os.Process.myPid());
  77. // ((CrashApplication)this.mContext.getApplicationContext()).removeAllActivity();
  78. }
  79. }
  80. private boolean handleException(final Throwable ex) {
  81. if (ex == null) {
  82. return false;
  83. } else {
  84. (new Thread() {
  85. @SuppressLint("WrongConstant")
  86. public void run() {
  87. Looper.prepare();
  88. Toast.makeText(UncaughtExceptionHandlerImpl.this.mContext, UncaughtExceptionHandlerImpl.this.getTips(ex), 1).show();
  89. Looper.loop();
  90. }
  91. }).start();
  92. return true;
  93. }
  94. }
  95. private String getTips(Throwable ex) {
  96. if (ex instanceof SecurityException) {
  97. if (ex.getMessage().contains("android.permission.CAMERA")) {
  98. this.mTips = "请授予应用相机权限,程序出现异常,即将退出.";
  99. } else if (ex.getMessage().contains("android.permission.RECORD_AUDIO")) {
  100. this.mTips = "请授予应用麦克风权限,程序出现异常,即将退出。";
  101. } else if (ex.getMessage().contains("android.permission.WRITE_EXTERNAL_STORAGE")) {
  102. this.mTips = "请授予应用存储权限,程序出现异常,即将退出。";
  103. } else if (ex.getMessage().contains("android.permission.READ_PHONE_STATE")) {
  104. this.mTips = "请授予应用电话权限,程序出现异常,即将退出。";
  105. } else if (!ex.getMessage().contains("android.permission.ACCESS_COARSE_LOCATION") && !ex.getMessage().contains("android.permission.ACCESS_FINE_LOCATION")) {
  106. this.mTips = "很抱歉,程序出现异常,即将退出,请检查应用权限设置。";
  107. } else {
  108. this.mTips = "请授予应用位置信息权,很抱歉,程序出现异常,即将退出。";
  109. }
  110. }
  111. return this.mTips;
  112. }
  113. public void collectDeviceInfo(Context ctx) {
  114. try {
  115. PackageManager pm = ctx.getPackageManager();
  116. @SuppressLint("WrongConstant") PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), 1);
  117. if (pi != null) {
  118. String versionName = pi.versionName == null ? "null" : pi.versionName;
  119. String versionCode = pi.versionCode + "";
  120. this.infos.put("versionName", versionName);
  121. this.infos.put("versionCode", versionCode);
  122. }
  123. } catch (PackageManager.NameNotFoundException var9) {
  124. Log.e(TAG, "an error occured when collect package info", var9);
  125. }
  126. Field[] fields = Build.class.getDeclaredFields();
  127. Field[] var11 = fields;
  128. int var12 = fields.length;
  129. for(int var13 = 0; var13 < var12; ++var13) {
  130. Field field = var11[var13];
  131. try {
  132. field.setAccessible(true);
  133. this.infos.put(field.getName(), field.get((Object)null).toString());
  134. Log.d(TAG, field.getName() + " : " + field.get((Object)null));
  135. } catch (Exception var8) {
  136. Log.e(TAG, "an error occured when collect crash info", var8);
  137. }
  138. }
  139. }
  140. private String saveCrashInfo2File(Throwable ex) {
  141. StringBuffer sb = new StringBuffer();
  142. Iterator var3 = this.infos.entrySet().iterator();
  143. String result;
  144. while(var3.hasNext()) {
  145. Map.Entry<String, String> entry = (Map.Entry)var3.next();
  146. String key = (String)entry.getKey();
  147. result = (String)entry.getValue();
  148. sb.append(key + "=" + result + "\n");
  149. }
  150. Writer writer = new StringWriter();
  151. PrintWriter printWriter = new PrintWriter(writer);
  152. ex.printStackTrace(printWriter);
  153. for(Throwable cause = ex.getCause(); cause != null; cause = cause.getCause()) {
  154. cause.printStackTrace(printWriter);
  155. }
  156. printWriter.close();
  157. result = writer.toString();
  158. sb.append(result);
  159. try {
  160. long timestamp = System.currentTimeMillis();
  161. String time = this.formatter.format(new Date());
  162. String fileName = "crash-" + time + "-" + timestamp + ".log";
  163. if (Environment.getExternalStorageState().equals("mounted")) {
  164. String path = "/sdcard/" + this.mContext.getPackageName() + "/crash/";
  165. File dir = new File(path);
  166. if (!dir.exists()) {
  167. dir.mkdirs();
  168. }
  169. FileOutputStream fos = new FileOutputStream(path + fileName);
  170. fos.write(sb.toString().getBytes());
  171. fos.close();
  172. }
  173. return fileName;
  174. } catch (Exception var14) {
  175. Log.e(TAG, "an error occured while writing file...", var14);
  176. return null;
  177. }
  178. }
  179. }