From 87aac90d58f876794270322234b60be56deb0c31 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 19 Apr 2024 12:51:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=AA=E6=8D=95=E8=8E=B7=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E5=90=AFapp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xypower/common/MicroPhotoContext.java | 16 ++ mpmaster/build.gradle | 1 + mpmaster/src/main/AndroidManifest.xml | 1 + .../com/xypower/mpmaster/CrashHandler.java | 176 ++++++++++++++++++ .../com/xypower/mpmaster/MainActivity.java | 2 +- .../xypower/mpmaster/MpMstApplication.java | 23 +++ mpmaster/src/main/res/values/strings.xml | 2 +- 7 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/CrashHandler.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/MpMstApplication.java diff --git a/common/src/main/java/com/xypower/common/MicroPhotoContext.java b/common/src/main/java/com/xypower/common/MicroPhotoContext.java index 79e28d82..6dc3fdbf 100644 --- a/common/src/main/java/com/xypower/common/MicroPhotoContext.java +++ b/common/src/main/java/com/xypower/common/MicroPhotoContext.java @@ -180,6 +180,22 @@ public class MicroPhotoContext { return path; } + public static String buildMasterAppDir(Context contxt) { + + String path = Environment.getExternalStorageDirectory().getAbsolutePath(); + if (!path.endsWith(File.separator)) { + path += File.separator; + } + + path += PACKAGE_NAME_MPMASTER + File.separator; + File pathFile = new File(path); + if (!pathFile.exists() && !pathFile.mkdirs()) { + return null; + } + + return path; + } + public static AppConfig getMpAppConfig(Context context) { AppConfig appConfig = new AppConfig(); diff --git a/mpmaster/build.gradle b/mpmaster/build.gradle index 351144b6..f5d5eb19 100644 --- a/mpmaster/build.gradle +++ b/mpmaster/build.gradle @@ -104,5 +104,6 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + implementation 'com.orhanobut:logger:2.2.0' implementation files('libs/devapi.aar') } \ No newline at end of file diff --git a/mpmaster/src/main/AndroidManifest.xml b/mpmaster/src/main/AndroidManifest.xml index 1ce06ef8..4889cf59 100644 --- a/mpmaster/src/main/AndroidManifest.xml +++ b/mpmaster/src/main/AndroidManifest.xml @@ -68,6 +68,7 @@ tools:ignore="ProtectedPermissions" /> mInfos = new HashMap(); + + private DateFormat mFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); + + public CrashHandler() { + } + + public static CrashHandler getInstance() { + return INSTANCE; + } + + public void init() { + // 获取系统默认的UncaughtException处理器 + mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + // 设置该CrashHandler为程序的默认处理器 + Thread.setDefaultUncaughtExceptionHandler(this); + } + + /** + * @描述: 当UncaughtException发生时会转入该函数来处理 + */ + @Override + public void uncaughtException(Thread thread, Throwable ex) { + if (!handleException(ex) && mDefaultHandler != null) { + // 如果用户没有处理则让系统默认的异常处理器来处理 + mDefaultHandler.uncaughtException(thread, ex); + } else { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + Log.e(this.getClass().toString(), e == null ? "" : e.toString()); + } + + // 重新启动应用 + Intent intent = new Intent(MpMstApplication.getContext(), MainActivity.class); + PendingIntent restartIntent = PendingIntent.getActivity(MpMstApplication.getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + AlarmManager mgr = (AlarmManager) MpMstApplication.getContext().getSystemService(Context.ALARM_SERVICE); + // 1秒钟后重启应用 + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); + // todo:退出程序 + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + } + } + + /** + * @return true:如果处理了该异常信息;否则返回false. + * @throws + * @描述:自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. + */ + private boolean handleException(Throwable ex) { + if (null == ex) { + return false; + } + + // 收集设备参数信息 + collectDeviceInfo(MpMstApplication.getContext()); + // 保存日志文件 + saveCrashInfo2File(ex); + return true; + } + + /** + * @描述:收集设备参数信息 + */ + 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 + ""; + mInfos.put("versionName", versionName); + mInfos.put("versionCode", versionCode); + } + } catch (PackageManager.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); + mInfos.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); + } + } + } + + /** + * @throws + * @描述:保存错误信息到文件中 目录/sdcard/qfangadtv/crash/ + * @返回类型 void 返回文件名称,便于将文件传送到服务器 + */ + private String saveCrashInfo2File(Throwable ex) { + + StringBuffer sb = new StringBuffer(); + for (Map.Entry entry : mInfos.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 = mFormatter.format(new Date()); + String fileName = "crash-" + time + ".log"; + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String path = MicroPhotoContext.buildMasterAppDir(MpMstApplication.getContext()) + "logs/"; + 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 e) { + Log.e(TAG, "an error occured while writing file...", e); + } + return null; + } + +} diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java b/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java index d997104b..9a191ef9 100644 --- a/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java +++ b/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java @@ -49,7 +49,7 @@ public class MainActivity extends AppCompatActivity { // String buildTime = BuildConfig.BUILD_ Date date = new Date(BuildConfig.BUILD_TIMESTAMP); // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm"); actionBar.setTitle(actionBar.getTitle().toString() + " v" + MicroPhotoContext.getVersionName(getApplicationContext()) + " " + sdf.format(date)); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/MpMstApplication.java b/mpmaster/src/main/java/com/xypower/mpmaster/MpMstApplication.java new file mode 100644 index 00000000..f27da635 --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/MpMstApplication.java @@ -0,0 +1,23 @@ +package com.xypower.mpmaster; + +import android.app.Application; +import android.content.Context; + +public class MpMstApplication extends Application { + + private static Context context; + + @Override + public void onCreate() { + super.onCreate(); + context = getApplicationContext(); + + //初始化-异常捕获(设置该CrashHandler为程序的默认处理器) + CrashHandler unCeHandler = new CrashHandler(); + Thread.setDefaultUncaughtExceptionHandler(unCeHandler); + } + + public static Context getContext() { + return context; + } +} diff --git a/mpmaster/src/main/res/values/strings.xml b/mpmaster/src/main/res/values/strings.xml index e68d2c7a..1e9a0657 100644 --- a/mpmaster/src/main/res/values/strings.xml +++ b/mpmaster/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - MpMaster + 运维APP Notification Name \ No newline at end of file