Added AppErrorsDetailActivity function and more function

This commit is contained in:
2022-05-11 02:41:54 +08:00
parent cac96e188e
commit e2b6fe8a81
31 changed files with 1058 additions and 11 deletions

View File

@@ -22,27 +22,33 @@ Added more features to app's crash dialog, fixed custom rom deleted dialog, the
## Feature
- 重新定制应用错误对话框
- 重新定制应用异常错误对话框
- 记录每个应用的异常记录,直到重新启动前
- “错误详情”按钮功能,可查看具体的异常堆栈
- 记录每个应用的异常,直到重新启动前持续保留
- “应用信息”按钮功能(原生功能),点击可打开当前出错的应用详情页面
- “重新打开”按钮功能(原生功能),在首次崩溃可点击按钮重新打开应用
- “重新打开”按钮功能(原生功能),在首次错误可点击按钮重新打开应用
- “屡次停止运行”显示(原生功能)
- “忽略(直到设备重新解锁/重新启动)”显示(原生功能)
- 对话框支持 Android 10 及以上系统的深色模式
- “错误详情”按钮功能,可查看具体的异常堆栈
- 导出异常堆栈到文件功能
- 复制异常堆栈功能
- 打印异常堆栈到控制台功能
- 支持 Android 10 及以上系统的深色模式
## Future
此项目依然在开发中,现在未解决的问题和包含的问题如下
- “错误详情”按钮现在是无效的,还在开发
- 异常历史记录和排除列表正在开发
- 后台进程可能依然会弹出崩溃对话框且开发者选项里的设置无效,还在排查

View File

@@ -1,7 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<application
android:name=".application.AppErrorsApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@@ -21,5 +27,10 @@
<meta-data
android:name="xposedscope"
android:resource="@array/module_scope" />
<activity
android:name=".ui.activity.AppErrorsDetailActivity"
android:exported="true"
android:screenOrientation="behind" />
</application>
</manifest>

View File

@@ -0,0 +1,34 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/10.
*/
package com.fankes.apperrorstracking.application
import androidx.appcompat.app.AppCompatDelegate
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication
class AppErrorsApplication : ModuleApplication() {
override fun onCreate() {
super.onCreate()
/** 跟随系统夜间模式 */
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
}

View File

@@ -0,0 +1,50 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/10.
*/
package com.fankes.apperrorstracking.bean
import java.io.Serializable
/**
* 应用异常信息 bean
* @param packageName 包名
* @param isNativeCrash 是否为原生层异常
* @param exceptionClassName 异常类名
* @param exceptionMessage 异常信息
* @param throwClassName 抛出异常的类名
* @param throwFileName 抛出异常的文件名
* @param throwMethodName 抛出异常的方法名
* @param throwLineNumber 抛出异常的行号
* @param stackTrace 异常堆栈
* @param timestamp 记录时间戳
*/
data class AppErrorsInfoBean(
var packageName: String,
var isNativeCrash: Boolean,
var exceptionClassName: String,
var exceptionMessage: String,
var throwFileName: String,
var throwClassName: String,
var throwMethodName: String,
var throwLineNumber: Int,
var stackTrace: String,
var timestamp: Long,
) : Serializable

View File

@@ -24,6 +24,7 @@
package com.fankes.apperrorstracking.hook.entity
import android.app.AlertDialog
import android.app.ApplicationErrorReport
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -40,6 +41,8 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
import com.fankes.apperrorstracking.ui.activity.AppErrorsDetailActivity
import com.fankes.apperrorstracking.utils.drawable.drawabletoolbox.DrawableBuilder
import com.fankes.apperrorstracking.utils.factory.*
import com.highcapable.yukihookapi.hook.bean.VariousClass
@@ -52,6 +55,8 @@ import com.highcapable.yukihookapi.hook.type.android.MessageClass
object FrameworkHooker : YukiBaseHooker() {
const val APP_ERRORS_INFO = "app_errors_info"
private const val AppErrorsClass = "com.android.server.am.AppErrors"
private const val AppErrorResultClass = "com.android.server.am.AppErrorResult"
@@ -79,6 +84,9 @@ object FrameworkHooker : YukiBaseHooker() {
/** 已忽略错误的 APP 数组 - 直到重新启动 */
private var ignoredErrorsIfRestartApps = HashSet<String>()
/** 已记录的 APP 异常信息数组 - 直到重新启动 */
private val appErrorsRecords = arrayListOf<AppErrorsInfoBean>()
/** 是否已经注册广播 */
private var isRegisterReceiver = false
@@ -113,6 +121,14 @@ object FrameworkHooker : YukiBaseHooker() {
isRegisterReceiver = true
}
/**
* 获取最新的 APP 错误信息
* @param packageName 包名
* @return [AppErrorsInfoBean] or null
*/
private fun lastAppErrorsInfo(packageName: String) =
appErrorsRecords.takeIf { it.isNotEmpty() }?.filter { it.packageName == packageName }?.get(0)
/**
* 获取 I18n 字符串
* @param resId 模块资源 Id
@@ -203,7 +219,7 @@ object FrameworkHooker : YukiBaseHooker() {
val packageName = appInfo?.packageName ?: processName
/** 当前 APP 名称 */
val appName = appInfo?.let { context.packageManager.getApplicationLabel(it) } ?: packageName
val appName = appInfo?.let { context.appName(it.packageName) } ?: packageName
/** 是否为 APP */
val isApp = (PackageListClass.clazz.method {
@@ -260,7 +276,9 @@ object FrameworkHooker : YukiBaseHooker() {
/** 错误详情按钮 */
val errorDetailButton =
createButtonItem(context, R.drawable.ic_baseline_bug_report, string(R.string.error_detail)) {
// TODO 待开发
cancel()
lastAppErrorsInfo(packageName)?.let { AppErrorsDetailActivity.start(context, it) }
?: context.toast(msg = "Invalid AppErrorsInfo")
}
/** 忽略按钮 - 直到解锁 */
@@ -300,6 +318,34 @@ object FrameworkHooker : YukiBaseHooker() {
}.show()
}
}
injectMember {
method {
name = "crashApplication"
paramCount = 2
}
afterHook {
/** 当前 APP 信息 */
val appInfo = ProcessRecordClass.clazz.field { name = "info" }.get(args().first().any()).cast<ApplicationInfo>()
/** 当前异常信息 */
args().last().cast<ApplicationErrorReport.CrashInfo>()?.also { crashInfo ->
/** 添加到第一位 */
appErrorsRecords.add(
0, AppErrorsInfoBean(
packageName = appInfo?.packageName ?: "",
isNativeCrash = crashInfo.exceptionClassName.lowercase() == "native crash",
exceptionClassName = crashInfo.exceptionClassName ?: "",
exceptionMessage = crashInfo.exceptionMessage ?: "",
throwFileName = crashInfo.throwFileName ?: "",
throwClassName = crashInfo.throwClassName ?: "",
throwMethodName = crashInfo.throwMethodName ?: "",
throwLineNumber = crashInfo.throwLineNumber,
stackTrace = crashInfo.stackTrace?.trim() ?: "",
timestamp = System.currentTimeMillis()
)
)
}
}
}
}
}
}

View File

@@ -0,0 +1,126 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/7.
*/
@file:Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
package com.fankes.apperrorstracking.ui.activity
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import androidx.core.view.isGone
import com.fankes.apperrorstracking.BuildConfig
import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
import com.fankes.apperrorstracking.databinding.ActivityAppErrorsDetailBinding
import com.fankes.apperrorstracking.hook.entity.FrameworkHooker
import com.fankes.apperrorstracking.ui.activity.base.BaseActivity
import com.fankes.apperrorstracking.utils.factory.*
import com.highcapable.yukihookapi.hook.log.loggerE
import java.text.SimpleDateFormat
import java.util.*
class AppErrorsDetailActivity : BaseActivity<ActivityAppErrorsDetailBinding>() {
companion object {
/** 请求保存文件回调标识 */
private const val WRITE_REQUEST_CODE = 0
/**
* 启动 [AppErrorsDetailActivity]
* @param context 实例
* @param appErrorsInfo 应用异常信息
*/
fun start(context: Context, appErrorsInfo: AppErrorsInfoBean) {
runCatching {
context.startActivity(Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
component = ComponentName(BuildConfig.APPLICATION_ID, AppErrorsDetailActivity::class.java.name)
putExtra(FrameworkHooker.APP_ERRORS_INFO, appErrorsInfo)
})
}.onFailure { context.toast(msg = "Start AppErrorsDetailActivity failed") }
}
}
/** 预导出的异常堆栈 */
private var stackTrace = ""
override fun onCreate() {
val appErrorsInfo =
intent?.getSerializableExtra(FrameworkHooker.APP_ERRORS_INFO) as? AppErrorsInfoBean ?: return toastAndFinish()
/** 创建异常堆栈模板 */
fun createStack() =
"package name: ${appErrorsInfo.packageName} timestamp: ${appErrorsInfo.timestamp}\n${appErrorsInfo.stackTrace}"
binding.titleBackIcon.setOnClickListener { onBackPressed() }
binding.printIcon.setOnClickListener {
loggerE(msg = createStack())
toast(getString(R.string.print_to_logcat_success))
}
binding.copyIcon.setOnClickListener { copyToClipboard(appErrorsInfo.stackTrace) }
binding.exportIcon.setOnClickListener {
stackTrace = createStack()
runCatching {
startActivityForResult(Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/plain"
putExtra(Intent.EXTRA_TITLE, "${appErrorsInfo.packageName}_${appErrorsInfo.timestamp}.log")
}, WRITE_REQUEST_CODE)
}.onFailure { toast(msg = "Start Android SAF failed") }
}
binding.appIcon.setImageDrawable(appIcon(appErrorsInfo.packageName))
binding.appName.text = appName(appErrorsInfo.packageName)
binding.appVersion.text = appVersion(appErrorsInfo.packageName)
binding.jvmErrorPanel.isGone = appErrorsInfo.isNativeCrash
binding.errorTypeIcon.setImageResource(if (appErrorsInfo.isNativeCrash) R.drawable.ic_cpp else R.drawable.ic_java)
binding.errorInfoText.text = appErrorsInfo.exceptionMessage
binding.errorTypeText.text = appErrorsInfo.exceptionClassName
binding.errorFileNameText.text = appErrorsInfo.throwFileName
binding.errorThrowClassText.text = appErrorsInfo.throwClassName
binding.errorThrowMethodText.text = appErrorsInfo.throwMethodName
binding.errorLineNumberText.text = appErrorsInfo.throwLineNumber.toString()
binding.errorRecordTimeText.text = SimpleDateFormat.getDateTimeInstance().format(Date(appErrorsInfo.timestamp))
binding.errorStackText.text = appErrorsInfo.stackTrace
}
/** 弹出提示并退出 */
private fun toastAndFinish() {
toast(msg = "Invalid AppErrorsInfo, exit")
finish()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) runCatching {
data?.data?.let {
contentResolver?.openOutputStream(it)?.apply { write(stackTrace.toByteArray()) }?.close()
toast(getString(R.string.output_stack_success))
} ?: toast(getString(R.string.output_stack_fail))
}.onFailure { toast(getString(R.string.output_stack_fail)) }
}
override fun onBackPressed() {
intent?.removeExtra(FrameworkHooker.APP_ERRORS_INFO)
finish()
}
}

View File

@@ -0,0 +1,69 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/7.
*/
@file:Suppress("UNCHECKED_CAST")
package com.fankes.apperrorstracking.ui.activity.base
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.utils.factory.isNotSystemInDarkMode
import com.gyf.immersionbar.ktx.immersionBar
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass
import java.lang.reflect.ParameterizedType
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
/** 获取绑定布局对象 */
lateinit var binding: VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
javaClass.genericSuperclass.also { type ->
if (type is ParameterizedType) {
binding = (type.actualTypeArguments[0] as Class<VB>).method {
name = "inflate"
param(LayoutInflaterClass)
}.get().invoke<VB>(layoutInflater) ?: error("binding failed")
setContentView(binding.root)
} else error("binding but got wrong type")
}
/** 隐藏系统的标题栏 */
supportActionBar?.hide()
/** 初始化沉浸状态栏 */
immersionBar {
statusBarColor(R.color.colorThemeBackground)
autoDarkModeEnable(true)
statusBarDarkFont(isNotSystemInDarkMode)
navigationBarColor(R.color.colorThemeBackground)
navigationBarDarkIcon(isNotSystemInDarkMode)
fitsSystemWindows(true)
}
/** 装载子类 */
onCreate()
}
/** 回调 [onCreate] 方法 */
abstract fun onCreate()
}

View File

@@ -23,12 +23,19 @@
package com.fankes.apperrorstracking.utils.factory
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.Settings
import android.widget.Toast
import com.fankes.apperrorstracking.R
/**
* 系统深色模式是否开启
@@ -56,12 +63,57 @@ fun Number.dp(context: Context) = dpFloat(context).toInt()
*/
fun Number.dpFloat(context: Context) = toFloat() * context.resources.displayMetrics.density
/**
* 获取 APP 名称
* @param packageName 包名
* @return [String]
*/
fun Context.appName(packageName: String) =
runCatching {
packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA)
.applicationInfo.loadLabel(packageManager).toString()
}.getOrNull() ?: packageName
/**
* 获取 APP 完整版本
* @param packageName 包名
* @return [String]
*/
fun Context.appVersion(packageName: String) =
runCatching {
packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA)?.let { "${it.versionName} (${it.versionCode})" }
}.getOrNull() ?: "unknown"
/**
* 获取 APP 图标
* @param packageName 包名
* @return [Drawable]
*/
fun Context.appIcon(packageName: String) =
runCatching {
packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA)
.applicationInfo.loadIcon(packageManager)
}.getOrNull() ?: ColorDrawable(Color.WHITE)
/**
* 弹出 [Toast]
* @param msg 提示内容
*/
fun Context.toast(msg: String) = Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
/**
* 复制到剪贴板
* @param content 要复制的文本
*/
fun Context.copyToClipboard(content: String) = runCatching {
(getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).apply {
setPrimaryClip(ClipData.newPlainText(null, content))
(primaryClip?.getItemAt(0)?.text ?: "").also {
if (it != content) toast(getString(R.string.copy_fail)) else toast(getString(R.string.copied))
}
}
}
/**
* 跳转 APP 自身设置界面
* @param packageName 包名

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#666E6E6E" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#777777">
<item>
<shape android:shape="rectangle">
<solid android:color="#66DAD9D9" />
<corners android:radius="15dp" />
</shape>
</item>
</ripple>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#66E4E4E4" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF14171F" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="150dp"
android:height="150dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#ffffff"
android:pathData="M316.8,784h377.6v140.8c0,42.2 -34.6,76.8 -76.8,76.8h-518.4c-42.2,0 -76.8,-34.6 -76.8,-76.8v-518.4c0,-42.2 34.6,-76.8 76.8,-76.8h140.8v377.6c0,42.2 34.6,76.8 76.8,76.8z" />
<path
android:fillColor="#ffffff"
android:pathData="M1008,105.6v518.4c0,42.2 -34.6,76.8 -76.8,76.8h-518.4c-42.2,0 -76.8,-34.6 -76.8,-76.8v-518.4c0,-42.2 34.6,-76.8 76.8,-76.8h518.4c42.2,0 76.8,34.6 76.8,76.8z" />
</vector>

View File

@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="250dp"
android:height="250dp"
android:viewportWidth="1024"
android:viewportHeight="1024"
tools:ignore="VectorRaster">
<path
android:fillColor="#1D88E5"
android:pathData="M403.5,880.6c-202.8,0 -368.6,-165.9 -368.6,-368.6s165.9,-368.6 368.6,-368.6c116.7,0 223.2,54.3 292.9,145.4L563.2,367.6c-41,-44 -98.3,-70.7 -158.7,-70.7 -117.8,0 -215,96.3 -215,215s96.3,215 215,215c60.4,0 117.8,-26.6 158.7,-70.7l134.1,78.8C628.7,826.4 520.2,880.6 403.5,880.6z" />
<path
android:fillColor="#1D88E5"
android:pathData="M772.1,542.7L711.7,542.7v61.4h-62.5v-61.4L588.8,542.7v-61.4h60.4v-61.4h62.5v61.4h60.4v61.4zM989.2,542.7L926.7,542.7v61.4h-60.4v-61.4L803.8,542.7v-61.4h62.5v-61.4h60.4v61.4h62.5v61.4z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="250dp"
android:height="250dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M511,0a376.4,376.4 0,0 0,-265.1 106.8,365.1 365.1,0 0,0 -108,258.6v498.7h742L880,365.5a362.4,362.4 0,0 0,-108.9 -258.6A374.9,374.9 0,0 0,511 0zM480.3,744.6L469.5,502.9L286.9,502.9l239.9,-303.1 20.5,195.2 174.1,6.1 -243.2,343.3zM0.1,966.4a55.6,55.6 0,0 1,55.6 -56.2h910.6a57.6,57.6 0,0 1,39.3 16.3,58.7 58.7,0 0,1 16.4,39.9 55.7,55.7 0,0 1,-55.7 55.6L55.6,1022.1a55.6,55.6 0,0 1,-55.5 -55.6z"
android:fillColor="#ffffff"/>
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="150dp"
android:height="150dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#ffffff"
android:pathData="M768,678.4v108.8H256v-108.8c0,-12.8 -6.4,-19.2 -19.2,-19.2H147.2c-12.8,0 -19.2,6.4 -19.2,19.2v172.8c0,38.4 25.6,64 64,64h640c38.4,0 64,-25.6 64,-64v-172.8c0,-12.8 -6.4,-19.2 -19.2,-19.2h-89.6c-12.8,0 -19.2,6.4 -19.2,19.2z" />
<path
android:fillColor="#ffffff"
android:pathData="M499.2,115.2L281.6,390.4c-12.8,12.8 0,32 12.8,32H448v268.8c0,6.4 6.4,12.8 19.2,12.8h89.6c12.8,0 19.2,-6.4 19.2,-19.2V416h153.6c19.2,0 25.6,-19.2 12.8,-32L524.8,115.2c-6.4,-6.4 -19.2,-6.4 -25.6,0z" />
</vector>

View File

@@ -0,0 +1,26 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="250dp"
android:height="250dp"
android:viewportWidth="1024"
android:viewportHeight="1024"
tools:ignore="VectorRaster">
<path
android:fillColor="#FF1515"
android:pathData="M747,175.6c-29.7,21 -58.4,38.9 -90.1,64.5 -24.1,19.5 -67.6,46.6 -69.6,82.4 -3.6,54.8 80.9,106 36.4,175.6 -16.9,26.6 -46.1,37.9 -82.4,54.3 -4.6,-8.2 9.7,-14.8 15.4,-23 56.3,-81.4 -58.4,-108.5 -44,-208.9 13.8,-97.8 128,-131.6 234.5,-144.9z" />
<path
android:fillColor="#2365C4"
android:pathData="M388.1,511c-26.6,12.3 -71.2,14.8 -90.1,41.5 19.5,14.8 48.1,14.3 74.8,15.4 109.1,5.1 245.2,-4.6 337.9,-20.5 3.1,6.7 -12.8,18.4 -23,25.6 -58.4,43 -240.6,54.8 -366.6,46.6 -42,-3.1 -138.2,-13.8 -139.3,-51.7 -1.5,-45.6 116.7,-50.7 164.9,-54.3 9.7,-1 27.6,-4.6 41.5,-2.6zM333.8,626.7c12.3,1.5 -8.7,8.7 -5.1,17.9 44.5,44 182.3,31.2 250.4,17.9 14.3,-3.1 28.2,-11.3 38.9,-10.2 25.6,2.6 42.5,32.3 64.5,36.4 -78.3,35.3 -229.9,52.2 -340.5,30.7 -28.7,-5.6 -78.3,-21 -79.9,-44 -2.6,-30.7 49.2,-43.5 71.7,-48.6zM367.6,732.7c8.2,2.6 -3.1,7.2 -2.6,10.2 23.6,41 139.8,26.1 198.7,12.8 11.8,-3.1 23.6,-11.3 33.8,-10.2 29.7,2 41.5,33.3 67.1,38.9 -82.4,50.2 -281.6,70.7 -364,7.7 -4.1,-46.1 32.8,-51.2 67.1,-59.4z" />
<path
android:fillColor="#2365C4"
android:pathData="M292.9,810c-24.6,6.1 -88.1,-2.6 -90.1,30.7 -1,12.8 21.5,28.2 36.4,33.8 84,31.7 252.9,36.9 392.2,20.5 64.5,-7.7 185.9,-29.2 170.5,-95.2 19.5,2.6 36.9,14.8 38.9,33.8 7.7,71.2 -155.6,101.4 -221.7,108.5 -143.9,15.9 -323.1,12.8 -433.7,-25.6 -35.8,-12.3 -79.4,-35.3 -77.3,-69.6 2,-58.4 141.3,-74.2 184.8,-36.9z" />
<path
android:fillColor="#2365C4"
android:pathData="M512,1024c-96.8,-10.8 -190,-24.6 -268.3,-59.4 205.3,49.2 504.3,45.6 647.7,-59.4 7.7,-5.6 14.8,-16.9 25.6,-15.4 -36.4,108.5 -175.1,115.7 -293.9,134.1H512z" />
<path
android:fillColor="#FF1515"
android:pathData="M579.1,0c17.9,16.9 30.7,48.6 30.7,82.4 0,99.8 -106,157.7 -157.2,224.3 -11.3,14.8 -26.1,37.9 -25.6,62 0.5,54.3 56.8,115.2 77.3,159.7 -36.4,-23.6 -79.9,-55.3 -111.1,-92.7 -30.7,-37.4 -62,-97.3 -33.8,-149.5 42.5,-78.3 169.5,-124.9 214,-208.9 11.3,-20.5 20,-51.7 5.6,-77.3z" />
<path
android:fillColor="#2365C4"
android:pathData="M731.1,536.6c53.2,-45.6 143.4,-27.6 146.9,49.2 4.6,89.6 -93.7,140.3 -165.4,144.4 32.8,-31.2 120.3,-81.9 103.4,-154.6 -6.7,-29.7 -43,-47.6 -85,-38.9z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="150dp"
android:height="150dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M851.2,957.9L179.2,957.9c-61.9,0 -110.9,-49.1 -110.9,-110.9L68.3,454.4c0,-32 25.6,-55.5 55.5,-55.5h55.5v224c0,32 25.6,55.5 55.5,55.5h558.9c32,0 55.5,-25.6 55.5,-55.5L849.1,398.9h55.5c32,0 55.5,25.6 55.5,55.5v390.4c2.1,64 -46.9,113.1 -108.8,113.1zM738.1,622.9h-448c-32,0 -55.5,-25.6 -55.5,-55.5v-448C234.7,89.6 260.3,64 290.1,64h448c32,0 55.5,25.6 55.5,55.5v448c0,29.9 -23.5,55.5 -55.5,55.5zM657.1,232.5L377.6,232.5c-19.2,0 -32,19.2 -32,32s12.8,25.6 32,32h279.5c19.2,0 32,-12.8 32,-32s-19.2,-32 -32,-32zM657.1,398.9L377.6,398.9c-19.2,0 -32,12.8 -32,32 0,12.8 19.2,25.6 32,25.6h279.5c19.2,0 32,-12.8 32,-25.6 0,-19.2 -19.2,-32 -32,-32z"
android:fillColor="#ffffff"/>
</vector>

View File

@@ -0,0 +1,402 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorThemeBackground"
android:orientation="vertical"
tools:context=".ui.activity.AppErrorsDetailActivity"
tools:ignore="UnusedAttribute,ContentDescription,UseCompoundDrawables">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
android:gravity="center|start"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:paddingRight="15dp"
android:paddingBottom="15dp">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/title_back_icon"
style="?android:attr/selectableItemBackgroundBorderless"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="20dp"
android:src="@mipmap/ic_back"
android:tint="@color/colorTextGray"
android:tooltipText="@string/back" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="2.5dp"
android:layout_weight="1"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/colorTextGray"
android:textSize="19sp"
android:textStyle="bold" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/print_icon"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_print"
android:tint="@color/colorTextGray"
android:tooltipText="@string/print_to_logcat" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/copy_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_copy"
android:tint="@color/colorTextGray"
android:tooltipText="@string/copy_error_stack" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/export_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_export"
android:tint="@color/colorTextGray"
android:tooltipText="@string/export_to_file" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:fadingEdgeLength="10dp"
android:fillViewport="true"
android:requiresFadingEdge="vertical"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/bg_permotion_round"
android:gravity="center|start"
android:padding="10dp">
<androidx.cardview.widget.CardView
android:layout_width="45dp"
android:layout_height="45dp"
app:cardBackgroundColor="@color/trans"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="45dp"
android:layout_height="45dp" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:gravity="center|start"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="15sp" />
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@drawable/ic_exception"
app:tint="#FFEF5350" />
</LinearLayout>
<TextView
android:id="@+id/app_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
</LinearLayout>
<ImageView
android:id="@+id/error_type_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/bg_permotion_round"
android:gravity="center|start"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start|top"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_info"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/jvm_error_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_type"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_type_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#FFEF5350"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_file_name"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_file_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_throw_class"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_throw_class_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_throw_method"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_throw_method_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_line_number"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_line_number_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/error_record_time"
android:textColor="@color/colorTextDark"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/error_record_time_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/colorTextGray"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/error_stack_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/bg_stack_round"
android:lineSpacingExtra="5dp"
android:padding="15dp"
android:textColor="#B65B57"
android:textIsSelectable="true"
android:textSize="12sp"
android:typeface="monospace" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -13,4 +13,19 @@
<string name="ignore_if_restart_tip">システイムが再起動するまで、「%1$s」のエラーを無視します</string>
<string name="ignore_if_unlock_tip">ロックが解除されるまで、「%1$s」のエラーを無視します</string>
<string name="back">戻る</string>
<string name="copy_error_stack">例外スタックをコピーする</string>
<string name="export_to_file">ファイルにエクスポート</string>
<string name="error_info">例外情報</string>
<string name="error_type">例外タイプ</string>
<string name="error_file_name">ファイル名</string>
<string name="error_throw_class">投擲クラス</string>
<string name="error_throw_method">投擲メソッド</string>
<string name="error_line_number">行番号</string>
<string name="error_record_time">記録タイム</string>
<string name="copied">コピーしました</string>
<string name="copy_fail">コピーに失敗しました</string>
<string name="print_to_logcat">コンソールに印刷</string>
<string name="print_to_logcat_success">コンソールに印刷されていました</string>
<string name="output_stack_success">エクスポートされた例外スタックされていました</string>
<string name="output_stack_fail">例外スタックのエクスポートに失敗しました</string>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorThemeBackground">#FF2D2D2D</color>
<color name="colorTextDark">#FFCFCFCF</color>
<color name="colorTextGray">#FFD3D3D3</color>
</resources>

View File

@@ -0,0 +1,16 @@
<resources>
<!-- Base application theme. -->
<style name="Theme.AppErrorsTracking" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -13,4 +13,19 @@
<string name="ignore_if_unlock_tip">忽略“%1$s”的错误直到设备重新解锁</string>
<string name="ignore_if_restart_tip">忽略“%1$s”的错误直到设备重新启动</string>
<string name="back">返回</string>
<string name="copy_error_stack">复制异常堆栈</string>
<string name="export_to_file">导出到文件</string>
<string name="error_info">异常信息</string>
<string name="error_type">异常类型</string>
<string name="error_file_name">文件名</string>
<string name="error_throw_class">抛出类</string>
<string name="error_throw_method">抛出方法</string>
<string name="error_line_number">行号</string>
<string name="error_record_time">记录时间</string>
<string name="copied">已复制</string>
<string name="copy_fail">复制失败</string>
<string name="print_to_logcat">打印到控制台</string>
<string name="print_to_logcat_success">已打印到控制台</string>
<string name="output_stack_success">已导出异常堆栈</string>
<string name="output_stack_fail">导出异常堆栈失败</string>
</resources>

View File

@@ -13,4 +13,19 @@
<string name="ignore_if_unlock_tip">忽略“%1$s”的錯誤直到設備重新開屏</string>
<string name="ignore_if_restart_tip">忽略“%1$s”的錯誤直到設備重新開機</string>
<string name="back">回退</string>
<string name="copy_error_stack">複製異常堆棧</string>
<string name="export_to_file">導出到副案</string>
<string name="error_info">異常訊息</string>
<string name="error_type">異常類型</string>
<string name="error_file_name">文件名</string>
<string name="error_throw_class">拋出 Class</string>
<string name="error_throw_method">抛出 Method</string>
<string name="error_line_number">行號</string>
<string name="error_record_time">記錄時間</string>
<string name="copied">已復制</string>
<string name="copy_fail">複製失敗</string>
<string name="print_to_logcat">打印到控制台</string>
<string name="print_to_logcat_success">已打印到控制台</string>
<string name="output_stack_success">已導出異常堆棧</string>
<string name="output_stack_fail">導出異常堆棧失敗</string>
</resources>

View File

@@ -13,4 +13,19 @@
<string name="ignore_if_unlock_tip">忽略“%1$s”的錯誤直到設備重新開屏</string>
<string name="ignore_if_restart_tip">忽略“%1$s”的錯誤直到設備重新開機</string>
<string name="back">回退</string>
<string name="copy_error_stack">複製異常堆棧</string>
<string name="export_to_file">導出到副案</string>
<string name="error_info">異常訊息</string>
<string name="error_type">異常類型</string>
<string name="error_file_name">文件名</string>
<string name="error_throw_class">拋出 Class</string>
<string name="error_throw_method">抛出 Method</string>
<string name="error_line_number">行號</string>
<string name="error_record_time">記錄時間</string>
<string name="copied">已復制</string>
<string name="copy_fail">複製失敗</string>
<string name="print_to_logcat">打印到控制台</string>
<string name="print_to_logcat_success">已打印到控制台</string>
<string name="output_stack_success">已導出異常堆棧</string>
<string name="output_stack_fail">導出異常堆棧失敗</string>
</resources>

View File

@@ -13,4 +13,19 @@
<string name="ignore_if_unlock_tip">忽略“%1$s”的錯誤直到設備重新開屏</string>
<string name="ignore_if_restart_tip">忽略“%1$s”的錯誤直到設備重新開機</string>
<string name="back">回退</string>
<string name="copy_error_stack">複製異常堆棧</string>
<string name="export_to_file">導出到副案</string>
<string name="error_info">異常訊息</string>
<string name="error_type">異常類型</string>
<string name="error_file_name">文件名</string>
<string name="error_throw_class">拋出 Class</string>
<string name="error_throw_method">抛出 Method</string>
<string name="error_line_number">行號</string>
<string name="error_record_time">記錄時間</string>
<string name="copied">已復制</string>
<string name="copy_fail">複製失敗</string>
<string name="print_to_logcat">打印到控制台</string>
<string name="print_to_logcat_success">已打印到控制台</string>
<string name="output_stack_success">已導出異常堆棧</string>
<string name="output_stack_fail">導出異常堆棧失敗</string>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorThemeBackground">#FFFFFFFF</color>
<color name="colorTextDark">#FF777777</color>
<color name="colorTextGray">#FF323B42</color>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#656565</color>
<color name="purple_500">#656565</color>
<color name="purple_700">#656565</color>
<color name="teal_200">#656565</color>
<color name="teal_700">#656565</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="trans">#00000000</color>
</resources>

View File

@@ -12,4 +12,19 @@
<string name="ignore_if_unlock_tip">Ignore errors for \'%1$s\' until device is re-unlocked</string>
<string name="ignore_if_restart_tip">Ignore errors for \'%1$s\' until device reboots</string>
<string name="back">Back</string>
<string name="copy_error_stack">Copy error stack</string>
<string name="export_to_file">Export to file</string>
<string name="error_info">Error Info</string>
<string name="error_type">Error Type</string>
<string name="error_file_name">File Name</string>
<string name="error_throw_class">Throw Class</string>
<string name="error_throw_method">Throw Method</string>
<string name="error_line_number">Line Number</string>
<string name="error_record_time">Record Time</string>
<string name="copied">Copied</string>
<string name="copy_fail">Copy failed</string>
<string name="print_to_logcat">Print to logcat</string>
<string name="print_to_logcat_success">Printed to logcat</string>
<string name="output_stack_success">Export exception stack succeeded</string>
<string name="output_stack_fail">Failed to export exception stack</string>
</resources>

View File

@@ -1,4 +1,16 @@
<resources>
<!-- Base application theme. -->
<style name="Theme.AppErrorsTracking" parent="android:Theme.DeviceDefault" />
<style name="Theme.AppErrorsTracking" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/teal_700</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>