优化夜晚模式下对话框文字+添加MIME 类型参数,调用对应应用 (#4655)

* style(dialog): 优化确认对话框样式

- 修改工具栏 ID为 tool_bar
- 为消息文本添加主文本颜色
- 设置工具栏标题文本颜色

* feat(app): 优化外部链接跳转逻辑并支持 MIME 类型- 重构 ConfirmationDialogActivity 中的跳转逻辑,支持处理 MIME 类型
- 在 JsExtensions 中的 openUrl 函数增加 mimeType 参数,允许传递 MIME 类型

---------

Co-authored-by: SunQAQ <sunqi87c6@gmail.com>
This commit is contained in:
Sun-QAQ
2025-02-12 12:51:32 +08:00
committed by GitHub
co-authored by SunQAQ
parent 3dbd9ba3fe
commit ea267b2cff
4 changed files with 37 additions and 17 deletions
@@ -963,11 +963,19 @@ interface JsExtensions : JsEncodeUtils {
return AppConst.androidId return AppConst.androidId
} }
fun openUrl(url: String) { // 新增 mimeType 参数,默认为 null(保持兼容性)
fun openUrl(url: String, mimeType: String? = null) {
try { try {
val intent = Intent(appCtx, ConfirmationDialogActivity::class.java).apply { val intent = Intent(appCtx, ConfirmationDialogActivity::class.java).apply {
data = Uri.parse(url) // 同时设置 Data 和 Type(避免单独设置 data/type 导致冲突)
putExtra("sourceTag", getSource()?.getTag() ?: "") // 添加来源标签参数 if (mimeType != null) {
setDataAndType(Uri.parse(url), mimeType)
} else {
data = Uri.parse(url)
}
putExtra("sourceTag", getSource()?.getTag() ?: "")
// 可选:添加 MIME 类型到 Extra 供后续逻辑使用
putExtra("mimeType", mimeType)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
} }
appCtx.startActivity(intent) appCtx.startActivity(intent)
@@ -976,4 +984,5 @@ interface JsExtensions : JsEncodeUtils {
appCtx.toastOnUi("启动跳转确认失败") appCtx.toastOnUi("启动跳转确认失败")
} }
} }
} }
@@ -2,7 +2,6 @@ package io.legado.app.ui.javascript
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
@@ -12,22 +11,21 @@ import io.legado.app.constant.AppLog
import io.legado.app.ui.widget.text.AccentTextView import io.legado.app.ui.widget.text.AccentTextView
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
class ConfirmationDialogActivity : AppCompatActivity() { class ConfirmationDialogActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// 必须先设置布局再获取控件
setContentView(R.layout.confirmation_dialog) setContentView(R.layout.confirmation_dialog)
// 正确顺序:先设置布局再获取视图
val messageView = findViewById<TextView>(R.id.message) val messageView = findViewById<TextView>(R.id.message)
val toolbar = findViewById<Toolbar>(R.id.toolbar) val toolbar = findViewById<Toolbar>(R.id.tool_bar)
val btnNegative = findViewById<AccentTextView>(R.id.btn_negative) val btnNegative = findViewById<AccentTextView>(R.id.btn_negative)
val btnPositive = findViewById<AccentTextView>(R.id.btn_positive) val btnPositive = findViewById<AccentTextView>(R.id.btn_positive)
val url = intent?.dataString // 获取原始 Intent 的数据和 MIME 类型
if (url.isNullOrBlank()) { val uri = intent?.data
val mimeType = intent?.getStringExtra("mimeType")
if (uri == null) {
finish() finish()
return return
} }
@@ -36,16 +34,27 @@ class ConfirmationDialogActivity : AppCompatActivity() {
val sourceTag = intent.getStringExtra("sourceTag").takeIf { !it.isNullOrBlank() } ?: "当前来源" val sourceTag = intent.getStringExtra("sourceTag").takeIf { !it.isNullOrBlank() } ?: "当前来源"
messageView.text = "$sourceTag 正在请求跳转外部链接/应用,是否跳转?" messageView.text = "$sourceTag 正在请求跳转外部链接/应用,是否跳转?"
// 设置其他组件
toolbar.setNavigationOnClickListener { finish() } toolbar.setNavigationOnClickListener { finish() }
btnNegative.setOnClickListener { finish() } btnNegative.setOnClickListener { finish() }
btnPositive.setOnClickListener { btnPositive.setOnClickListener {
try { try {
startActivity( // 创建目标 Intent 并设置类型
Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { val targetIntent = Intent(Intent.ACTION_VIEW).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // 同时设置 Data 和 Type
if (!mimeType.isNullOrBlank()) {
setDataAndType(uri, mimeType)
} else {
data = uri
} }
) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
// 验证是否有应用可以处理
if (targetIntent.resolveActivity(packageManager) != null) {
startActivity(targetIntent)
} else {
toastOnUi(R.string.can_not_open)
}
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
toastOnUi(R.string.can_not_open) toastOnUi(R.string.can_not_open)
} catch (e: Exception) { } catch (e: Exception) {
@@ -14,7 +14,7 @@
android:orientation="vertical"> android:orientation="vertical">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/tool_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle" android:theme="?attr/actionBarStyle"
@@ -28,7 +28,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp" android:padding="16dp"
android:textSize="16sp" android:textSize="16sp"
android:textAppearance="?attr/textAppearanceBodyMedium"/> android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="@color/primaryText" />
<com.google.android.flexbox.FlexboxLayout <com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent" android:layout_width="match_parent"
+1
View File
@@ -80,6 +80,7 @@
<style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"> <style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">20sp</item> <item name="android:textSize">20sp</item>
<item name="android:textColor">@color/primaryText</item>
</style> </style>
//*******************Widget Style**********************************// //*******************Widget Style**********************************//