mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
实现JS方法(openUrl),能够弹窗提示用户是否跳转外部链接 (#4649)
Some checks are pending
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions
Some checks are pending
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions
* feat(ui): 添加外部链接跳转确认对话框 - 新增 ConfirmationDialogActivity 用于显示跳转确认对话框 - 在 AndroidManifest.xml 中注册新活动 - 添加 confirmation_dialog.xml 布局文件- 在 JsExtensions.kt 中实现 openUrl 函数以启动对话框 - 更新 styles.xml 添加透明主题样式 - 在 strings.xml 中添加新的错误提示字符串 * feat(dialog): 优化外部链接/应用跳转确认对话框 - 更新对话框布局,增加文本大小设置 - 添加来源标签显示,提高用户识别度 - 优化对话框逻辑,正确处理视图初始化顺序 - 更新字符串资源,支持来源标签显示 --------- Co-authored-by: SunQAQ <sunqi87c6@gmail.com>
This commit is contained in:
@@ -433,6 +433,13 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.javascript.ConfirmationDialogActivity"
|
||||
android:theme="@style/Theme.Translucent.NoTitleBar"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity=""
|
||||
android:launchMode="singleInstance"/>
|
||||
|
||||
<service
|
||||
android:name=".service.CheckSourceService"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
|
||||
@@ -2,6 +2,8 @@ package io.legado.app.help
|
||||
|
||||
import android.net.Uri
|
||||
import android.webkit.WebSettings
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import androidx.annotation.Keep
|
||||
import cn.hutool.core.codec.Base64
|
||||
import cn.hutool.core.util.HexUtil
|
||||
@@ -21,6 +23,7 @@ import io.legado.app.help.source.SourceVerificationHelp
|
||||
import io.legado.app.model.Debug
|
||||
import io.legado.app.model.analyzeRule.AnalyzeUrl
|
||||
import io.legado.app.model.analyzeRule.QueryTTF
|
||||
import io.legado.app.ui.javascript.ConfirmationDialogActivity
|
||||
import io.legado.app.utils.ArchiveUtils
|
||||
import io.legado.app.utils.ChineseUtils
|
||||
import io.legado.app.utils.EncoderUtils
|
||||
@@ -45,9 +48,11 @@ import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.stackTraceStr
|
||||
import io.legado.app.utils.toStringArray
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import okio.use
|
||||
import org.jsoup.Connection
|
||||
import org.jsoup.Jsoup
|
||||
@@ -958,4 +963,17 @@ interface JsExtensions : JsEncodeUtils {
|
||||
return AppConst.androidId
|
||||
}
|
||||
|
||||
fun openUrl(url: String) {
|
||||
try {
|
||||
val intent = Intent(appCtx, ConfirmationDialogActivity::class.java).apply {
|
||||
data = Uri.parse(url)
|
||||
putExtra("sourceTag", getSource()?.getTag() ?: "") // 添加来源标签参数
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
appCtx.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
AppLog.put("启动跳转对话框失败", e)
|
||||
appCtx.toastOnUi("启动跳转确认失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.legado.app.ui.javascript
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.ui.widget.text.AccentTextView
|
||||
import io.legado.app.utils.toastOnUi
|
||||
|
||||
|
||||
class ConfirmationDialogActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// 必须先设置布局再获取控件
|
||||
setContentView(R.layout.confirmation_dialog)
|
||||
|
||||
// 正确顺序:先设置布局再获取视图
|
||||
val messageView = findViewById<TextView>(R.id.message)
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
||||
val btnNegative = findViewById<AccentTextView>(R.id.btn_negative)
|
||||
val btnPositive = findViewById<AccentTextView>(R.id.btn_positive)
|
||||
|
||||
val url = intent?.dataString
|
||||
if (url.isNullOrBlank()) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
// 处理来源标签显示
|
||||
val sourceTag = intent.getStringExtra("sourceTag").takeIf { !it.isNullOrBlank() } ?: "当前来源"
|
||||
messageView.text = "$sourceTag 正在请求跳转外部链接/应用,是否跳转?"
|
||||
|
||||
// 设置其他组件
|
||||
toolbar.setNavigationOnClickListener { finish() }
|
||||
btnNegative.setOnClickListener { finish() }
|
||||
btnPositive.setOnClickListener {
|
||||
try {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
toastOnUi(R.string.can_not_open)
|
||||
} catch (e: Exception) {
|
||||
AppLog.put("打开链接失败", e)
|
||||
toastOnUi(R.string.error_occurred)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
56
app/src/main/res/layout/confirmation_dialog.xml
Normal file
56
app/src/main/res/layout/confirmation_dialog.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#80000000"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/shape_card_view"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/actionBarStyle"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
||||
app:title="跳转确认"
|
||||
app:titleTextAppearance="@style/ToolbarTitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:textSize="16sp"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"/>
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
app:flexDirection="row"
|
||||
app:justifyContent="flex_end">
|
||||
|
||||
<io.legado.app.ui.widget.text.AccentTextView
|
||||
android:id="@+id/btn_negative"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/cancel"/>
|
||||
|
||||
<io.legado.app.ui.widget.text.AccentTextView
|
||||
android:id="@+id/btn_positive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/ok"/>
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -1185,4 +1185,6 @@
|
||||
<string name="theme_config">主题配置</string>
|
||||
<string name="menu_download_after">Download the chapter after</string>
|
||||
<string name="menu_download_all">Download all chapter</string>
|
||||
<string name="error_occurred" translatable="false">打开失败</string>
|
||||
<string name="confirmation_message" translatable="false">%s正在请求跳转外部链接/应用,是否跳转?</string>
|
||||
</resources>
|
||||
|
||||
@@ -127,4 +127,16 @@
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
</style>
|
||||
|
||||
<!-- 基础透明主题 -->
|
||||
<style name="Theme.Translucent" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<!-- 无标题栏变体 -->
|
||||
<style name="Theme.Translucent.NoTitleBar" parent="Theme.Translucent">
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user