From 02d5cf2141fc67afe3bc5b4b46677fc191c1b232 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Wed, 1 Jun 2022 04:04:27 +0800 Subject: [PATCH] Added crossTime and dateTime in AppErrorsInfoBean --- .../bean/AppErrorsInfoBean.kt | 54 +++++++++++++++++-- .../hook/entity/FrameworkHooker.kt | 27 +--------- .../apperrorstracking/locale/LocaleString.kt | 42 +++++++++++++++ .../errors/AppErrorsDetailActivity.kt | 2 +- .../errors/AppErrorsRecordActivity.kt | 2 +- .../utils/factory/FunctionFactory.kt | 28 ++++++++++ app/src/main/res/values-ja/strings.xml | 7 +++ app/src/main/res/values-zh-rCN/strings.xml | 7 +++ app/src/main/res/values-zh-rHK/strings.xml | 7 +++ app/src/main/res/values-zh-rMO/strings.xml | 7 +++ app/src/main/res/values-zh-rTW/strings.xml | 7 +++ app/src/main/res/values/strings.xml | 7 +++ 12 files changed, 167 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/fankes/apperrorstracking/bean/AppErrorsInfoBean.kt b/app/src/main/java/com/fankes/apperrorstracking/bean/AppErrorsInfoBean.kt index c82af91..9c15d11 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/bean/AppErrorsInfoBean.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/bean/AppErrorsInfoBean.kt @@ -21,7 +21,10 @@ */ package com.fankes.apperrorstracking.bean +import android.app.ApplicationErrorReport import android.os.Build +import com.fankes.apperrorstracking.locale.LocaleString +import com.fankes.apperrorstracking.utils.factory.difference import java.io.Serializable import java.text.SimpleDateFormat import java.util.* @@ -52,11 +55,56 @@ data class AppErrorsInfoBean( var timestamp: Long, ) : Serializable { + companion object { + + /** + * 从 [ApplicationErrorReport.CrashInfo] 克隆 + * @param packageName APP 包名 + * @param crashInfo [ApplicationErrorReport.CrashInfo] + * @return [AppErrorsInfoBean] + */ + fun clone(packageName: String?, crashInfo: ApplicationErrorReport.CrashInfo?) = + (crashInfo?.exceptionClassName?.lowercase() == "native crash").let { isNativeCrash -> + AppErrorsInfoBean( + packageName = packageName ?: "null", + isNativeCrash = isNativeCrash, + exceptionClassName = crashInfo?.exceptionClassName ?: "null", + exceptionMessage = if (isNativeCrash) crashInfo?.stackTrace.let { + if (it?.contains(other = "Abort message: '") == true) + runCatching { it.split("Abort message: '")[1].split("'")[0] }.getOrNull() + ?: crashInfo?.exceptionMessage ?: "null" + else crashInfo?.exceptionMessage ?: "null" + } else crashInfo?.exceptionMessage ?: "null", + throwFileName = crashInfo?.throwFileName ?: "null", + throwClassName = crashInfo?.throwClassName ?: "null", + throwMethodName = crashInfo?.throwMethodName ?: "null", + throwLineNumber = crashInfo?.throwLineNumber ?: -1, + stackTrace = crashInfo?.stackTrace?.trim() ?: "null", + timestamp = System.currentTimeMillis() + ) + } + } + /** - * 获取异常本地化时间 + * 获取异常本地化经过时间 * @return [String] */ - val time get() = SimpleDateFormat.getDateTimeInstance().format(Date(timestamp)) ?: "" + val crossTime + get() = timestamp.difference( + now = LocaleString.momentAgo, + second = LocaleString.secondAgo, + minute = LocaleString.minuteAgo, + hour = LocaleString.hourAgo, + day = LocaleString.dayAgo, + month = LocaleString.monthAgo, + year = LocaleString.yearAgo + ) + + /** + * 获取异常本地化量化时间 + * @return [String] + */ + val dateTime get() = SimpleDateFormat.getDateTimeInstance().format(Date(timestamp)) ?: "DateTime not found" /** * 获取异常堆栈模板 @@ -74,7 +122,7 @@ data class AppErrorsInfoBean( "[API Version]: ${Build.VERSION.SDK_INT}\n" + "[Package Name]: $packageName\n" + "[Error Type]: ${if (isNativeCrash) "Native" else "Jvm"}\n" + - "[Crash Time]: $time\n" + + "[Crash Time]: $dateTime\n" + "[Stack Trace]:\n" + stackTrace } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt b/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt index 4e1b7b2..07aa4a3 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/hook/entity/FrameworkHooker.kt @@ -23,7 +23,6 @@ package com.fankes.apperrorstracking.hook.entity -import android.app.ApplicationErrorReport import android.content.Context import android.content.Intent import android.content.pm.ApplicationInfo @@ -187,30 +186,8 @@ object FrameworkHooker : YukiBaseHooker() { afterHook { /** 当前 APP 信息 */ val appInfo = ProcessRecordClass.clazz.field { name = "info" }.get(args().first().any()).cast() - /** 当前异常信息 */ - args().last().cast()?.also { crashInfo -> - /** 添加到第一位 */ - (crashInfo.exceptionClassName.lowercase() == "native crash").also { isNativeCrash -> - appErrorsRecords.add( - 0, AppErrorsInfoBean( - packageName = appInfo?.packageName ?: "null", - isNativeCrash = isNativeCrash, - exceptionClassName = crashInfo.exceptionClassName ?: "null", - exceptionMessage = if (isNativeCrash) crashInfo.stackTrace.let { - if (it.contains(other = "Abort message: '")) - runCatching { it.split("Abort message: '")[1].split("'")[0] }.getOrNull() - ?: crashInfo.exceptionMessage ?: "" else crashInfo.exceptionMessage ?: "null" - } else crashInfo.exceptionMessage ?: "null", - throwFileName = crashInfo.throwFileName ?: "null", - throwClassName = crashInfo.throwClassName ?: "null", - throwMethodName = crashInfo.throwMethodName ?: "null", - throwLineNumber = crashInfo.throwLineNumber, - stackTrace = crashInfo.stackTrace?.trim() ?: "null", - timestamp = System.currentTimeMillis() - ) - ) - } - } + /** 添加当前异常信息到第一位 */ + appErrorsRecords.add(0, AppErrorsInfoBean.clone(appInfo?.packageName, args().last().cast())) } } } diff --git a/app/src/main/java/com/fankes/apperrorstracking/locale/LocaleString.kt b/app/src/main/java/com/fankes/apperrorstracking/locale/LocaleString.kt index ce49a45..1cf3bd9 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/locale/LocaleString.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/locale/LocaleString.kt @@ -286,4 +286,46 @@ object LocaleString { /** @string Automatic generated */ fun moduleNotFullyActivated(vararg objArrs: Any) = R.string.module_not_fully_activated.bind(*objArrs) + + /** @string Automatic generated */ + val momentAgo get() = momentAgo() + + /** @string Automatic generated */ + fun momentAgo(vararg objArrs: Any) = R.string.moment_ago.bind(*objArrs) + + /** @string Automatic generated */ + val secondAgo get() = secondAgo() + + /** @string Automatic generated */ + fun secondAgo(vararg objArrs: Any) = R.string.second_ago.bind(*objArrs) + + /** @string Automatic generated */ + val minuteAgo get() = minuteAgo() + + /** @string Automatic generated */ + fun minuteAgo(vararg objArrs: Any) = R.string.minute_ago.bind(*objArrs) + + /** @string Automatic generated */ + val hourAgo get() = hourAgo() + + /** @string Automatic generated */ + fun hourAgo(vararg objArrs: Any) = R.string.hour_ago.bind(*objArrs) + + /** @string Automatic generated */ + val dayAgo get() = dayAgo() + + /** @string Automatic generated */ + fun dayAgo(vararg objArrs: Any) = R.string.day_ago.bind(*objArrs) + + /** @string Automatic generated */ + val monthAgo get() = monthAgo() + + /** @string Automatic generated */ + fun monthAgo(vararg objArrs: Any) = R.string.month_ago.bind(*objArrs) + + /** @string Automatic generated */ + val yearAgo get() = yearAgo() + + /** @string Automatic generated */ + fun yearAgo(vararg objArrs: Any) = R.string.year_ago.bind(*objArrs) } \ No newline at end of file diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDetailActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDetailActivity.kt index 30c0c65..b47e386 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDetailActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDetailActivity.kt @@ -89,7 +89,7 @@ class AppErrorsDetailActivity : BaseActivity() { binding.errorThrowClassText.text = appErrorsInfo.throwClassName binding.errorThrowMethodText.text = appErrorsInfo.throwMethodName binding.errorLineNumberText.text = appErrorsInfo.throwLineNumber.toString() - binding.errorRecordTimeText.text = appErrorsInfo.time + binding.errorRecordTimeText.text = appErrorsInfo.dateTime binding.errorStackText.text = appErrorsInfo.stackTrace binding.appPanelScrollView.setOnScrollChangeListener { _, _, y, _, _ -> binding.detailTitleText.text = if (y >= 30.dp(context = this)) appName(appErrorsInfo.packageName) else LocaleString.appName diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt index d5f0f31..94be4c2 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsRecordActivity.kt @@ -102,7 +102,7 @@ class AppErrorsRecordActivity : BaseActivity() { getItem(position).also { holder.appIcon.setImageDrawable(appIcon(it.packageName)) holder.appNameText.text = appName(it.packageName) - holder.errorsTimeText.text = it.time + holder.errorsTimeText.text = it.crossTime holder.errorTypeIcon.setImageResource(if (it.isNativeCrash) R.drawable.ic_cpp else R.drawable.ic_java) holder.errorTypeText.text = if (it.isNativeCrash) "Native crash" else it.exceptionClassName.let { text -> if (text.contains(other = ".")) text.split(".").let { e -> e[e.lastIndex] } else text diff --git a/app/src/main/java/com/fankes/apperrorstracking/utils/factory/FunctionFactory.kt b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/FunctionFactory.kt index fd48c8d..0c9a2d5 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/utils/factory/FunctionFactory.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/FunctionFactory.kt @@ -111,6 +111,34 @@ fun Context.appIcon(packageName: String) = .applicationInfo.loadIcon(packageManager) }.getOrNull() ?: ResourcesCompat.getDrawable(resources, R.drawable.ic_android, null) +/** + * 计算与当前时间戳相差的友好时间 + * @param now 刚刚 + * @param second 秒前 + * @param minute 分钟前 + * @param hour 小时前 + * @param day 天前 + * @param month 月前 + * @param year 年前 + * @return [String] 友好时间 + */ +fun Long.difference(now: String, second: String, minute: String, hour: String, day: String, month: String, year: String) = + ((System.currentTimeMillis() - this) / 1000).toInt().let { diff -> + when (diff) { + in 0..10 -> now + in 11..20 -> "10 $second" + in 21..30 -> "20 $second" + in 31..40 -> "30 $second" + in 41..50 -> "40 $second" + in 51..59 -> "50 $second" + in 60..3599 -> "${(diff / 60).coerceAtLeast(1)} $minute" + in 3600..86399 -> "${diff / 3600} $hour" + in 86400..2591999 -> "${diff / 86400} $day" + in 2592000..31103999 -> "${diff / 2592000} $month" + else -> "${diff / 31104000} $year" + } + } + /** * 弹出 [Toast] * @param msg 提示内容 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d4b9895..80549ec 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -63,4 +63,11 @@ 高速リスタート ルート権限を取得できませんでした より多くの機能が開発中です + 現在 + 秒前 + 分前 + 時間前 + 日前 + 月前 + 年前 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8062f5c..d502f5d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -63,4 +63,11 @@ 快速重启 获取 Root 权限失败 更多功能正在开发 + 刚刚 + 秒前 + 分钟前 + 小时前 + 天前 + 月前 + 年前 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 1cf85fb..f942b29 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -63,4 +63,11 @@ 急速重開 取得 Root 权利失败 更多機能正在開發 + 剛剛 + 秒前 + 分鐘前 + 小時前 + 天前 + 月前 + 年前 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rMO/strings.xml b/app/src/main/res/values-zh-rMO/strings.xml index 403bdbe..9111750 100644 --- a/app/src/main/res/values-zh-rMO/strings.xml +++ b/app/src/main/res/values-zh-rMO/strings.xml @@ -63,4 +63,11 @@ 急速重開 取得 Root 权利失败 更多機能正在開發 + 剛剛 + 秒前 + 分鐘前 + 小時前 + 天前 + 月前 + 年前 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f19712c..5ceecc6 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -63,4 +63,11 @@ 急速重開 取得 Root 权利失败 更多機能正在開發 + 剛剛 + 秒前 + 分鐘前 + 小時前 + 天前 + 月前 + 年前 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e27d4e4..4027028 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,4 +63,11 @@ Fast restart Access Root failed More features are in development + moment ago + second ago + minutes ago + hour ago + days ago + month ago + year ago \ No newline at end of file