From bc670629b4d239933218df6df27aefb7c832584a Mon Sep 17 00:00:00 2001 From: HapeLee <63206378+HapeLee@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:01:19 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E5=8C=85=E6=8A=A5=E5=91=8A=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=EF=BC=88=E5=9B=A0=E4=B8=BA=E5=B4=A9=E6=BA=83=E5=A4=AA=E5=A4=9A?= =?UTF-8?q?=E4=BA=86=E5=AD=A9=E5=AD=90=E4=BB=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 5 + .../java/io/legado/app/help/CrashHandler.kt | 56 ++++++++-- .../app/ui/about/CrashReportActivity.kt | 35 ++++++ .../legado/app/ui/about/CrashReportScreen.kt | 105 ++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 4 + app/src/main/res/values-zh-rHK/strings.xml | 4 + app/src/main/res/values-zh-rTW/strings.xml | 4 + app/src/main/res/values/strings.xml | 4 + 8 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/about/CrashReportActivity.kt create mode 100644 app/src/main/java/io/legado/app/ui/about/CrashReportScreen.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 97d469162..677a36879 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -222,6 +222,11 @@ android:name=".ui.about.AboutActivity" android:enableOnBackInvokedCallback="true" android:launchMode="singleTask" /> + file.isFile } + ?.maxByOrNull { it.name } + file?.readText() + }.getOrNull() } /** diff --git a/app/src/main/java/io/legado/app/ui/about/CrashReportActivity.kt b/app/src/main/java/io/legado/app/ui/about/CrashReportActivity.kt new file mode 100644 index 000000000..b00ea97d5 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/about/CrashReportActivity.kt @@ -0,0 +1,35 @@ +package io.legado.app.ui.about + +import android.content.Intent +import androidx.compose.runtime.Composable +import io.legado.app.base.BaseComposeActivity +import io.legado.app.help.CrashHandler +import io.legado.app.ui.main.MainActivity +import io.legado.app.utils.sendToClip + +class CrashReportActivity : BaseComposeActivity() { + + private val crashText: String by lazy { + CrashHandler.readCrashLog( + intent.getStringExtra(CrashHandler.EXTRA_CRASH_FILE_NAME) + ).orEmpty() + } + + @Composable + override fun Content() { + CrashReportScreen( + errorText = crashText, + onCopy = { sendToClip(crashText) }, + onRestart = { restartApp() }, + onClose = { finish() } + ) + } + + private fun restartApp() { + startActivity( + Intent(this, MainActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) + ) + finish() + } +} diff --git a/app/src/main/java/io/legado/app/ui/about/CrashReportScreen.kt b/app/src/main/java/io/legado/app/ui/about/CrashReportScreen.kt new file mode 100644 index 000000000..b532985d4 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/about/CrashReportScreen.kt @@ -0,0 +1,105 @@ +package io.legado.app.ui.about + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.dp +import io.legado.app.R +import io.legado.app.ui.theme.LegadoTheme +import io.legado.app.ui.widget.components.AppScaffold +import io.legado.app.ui.widget.components.icon.AppIcons +import io.legado.app.ui.widget.components.text.AppText +import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar +import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults +import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) +@Composable +fun CrashReportScreen( + errorText: String, + onCopy: () -> Unit, + onRestart: () -> Unit, + onClose: () -> Unit +) { + val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() + val displayText = errorText.ifBlank { + stringResource(R.string.crash_report_empty) + } + + AppScaffold( + modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), + topBar = { + GlassMediumFlexibleTopAppBar( + title = stringResource(R.string.crash_report), + navigationIcon = { + TopBarNavigationButton( + onClick = onClose, + imageVector = AppIcons.Close + ) + }, + scrollBehavior = scrollBehavior + ) + } + ) { padding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(padding) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + AppText( + text = stringResource(R.string.crash_report_message), + style = LegadoTheme.typography.bodyMedium + ) + + SelectionContainer( + modifier = Modifier + .weight(1f) + .fillMaxWidth() + .verticalScroll(rememberScrollState()) + ) { + Text( + text = displayText, + style = LegadoTheme.typography.bodySmall, + fontFamily = FontFamily.Monospace + ) + } + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + OutlinedButton( + onClick = onRestart, + modifier = Modifier.weight(1f) + ) { + Text(text = stringResource(R.string.restart_app)) + } + Button( + onClick = onCopy, + enabled = errorText.isNotBlank(), + modifier = Modifier.weight(1f) + ) { + Text(text = stringResource(R.string.copy_text)) + } + } + } + } +} diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index fe10a4ab5..3726544d5 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1209,6 +1209,10 @@ 按键长按翻页 保存日志 创建堆转储 + 崩溃报告 + 应用发生崩溃。报告问题时,请复制以下错误信息。 + 未找到崩溃信息。 + 重启应用 当应用发生OOM崩溃时保存堆转储 记录堆转储 字重 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 6f42b0a29..bd067e4b3 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1178,6 +1178,10 @@ 按键长按翻页 保存日志 创建堆转储 + 崩潰報告 + 應用程式發生崩潰。回報問題時,請複製以下錯誤資訊。 + 找不到崩潰資訊。 + 重新啟動應用程式 当应用发生OOM崩溃时保存堆转储 记录堆转储 字重 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f5fced0c9..f99edc6a2 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1181,6 +1181,10 @@ 按键长按翻页 保存日志 创建堆转储 + 崩潰報告 + 應用程式發生崩潰。回報問題時,請複製以下錯誤資訊。 + 找不到崩潰資訊。 + 重新啟動應用程式 当应用发生OOM崩溃时保存堆转储 记录堆转储 字重 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4651f6df6..1aaa51039 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1212,6 +1212,10 @@ Press and Hold the Key to Turn Page Save logs Create Heap Dump + Crash report + The app crashed. Copy the error information below when reporting the issue. + No crash information found. + Restart app Saving a heap dump when the application crashes by OOM Capture heap dump N/B/L