UncaughtExceptionHandlerImpl.java 8.1 KB

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