feat(webview): 添加外部链接处理功能

- 引入 Context 和 Intent 导入以支持外部链接打开
- 添加 Locale 导入用于 URL 方案小写转换
- 实现 shouldLoadInWebView 函数检查 URL 方案是否允许在 WebView 中加载
- 实现 openExternalScheme 函数用于启动外部应用处理非 HTTP 链接
- 在 shouldOverrideUrlLoading 中集成新的 URL 处理逻辑
- 添加对 http、https、about、data、blob、javascript 方案的支持判断
这个提交包含在:
XuqmGroup 2026-05-18 13:55:02 +08:00
父节点 aa20a790a1
当前提交 dc0cd7b2b1

查看文件

@ -2,6 +2,8 @@ package com.xuqm.sdk.webview
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Handler
@ -30,6 +32,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import java.io.File
import java.util.Locale
// JS injected into every page to bridge dialog APIs and download interception.
// Uses addJavascriptInterface("ReactNativeWebView") for the JS→Native channel.
@ -107,6 +110,21 @@ true;
internal fun buildInjectedJs(config: XWebViewConfig): String =
DIALOG_OVERRIDE_JS + "\n" + (config.injectedJavaScript ?: "") + "\ntrue;"
internal fun shouldLoadInWebView(uri: Uri): Boolean {
val scheme = uri.scheme?.lowercase(Locale.ROOT) ?: return true
return scheme in setOf("http", "https", "about", "data", "blob", "javascript")
}
internal fun openExternalScheme(context: Context, uri: Uri): Boolean {
return runCatching {
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
true
}.getOrDefault(false)
}
// Routes window.ReactNativeWebView.postMessage() calls to [onMessage].
// @JavascriptInterface methods are called on a background thread; we post to main.
internal class XWebViewJsBridge(
@ -224,8 +242,13 @@ fun XWebViewView(
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val uri = request?.url ?: return false
if (shouldLoadInWebView(uri)) {
return false
}
openExternalScheme(ctx, uri)
return true
}
}
webChromeClient = object : WebChromeClient() {