feat(webview): 添加外部链接处理功能
- 引入 Context 和 Intent 导入以支持外部链接打开 - 添加 Locale 导入用于 URL 方案小写转换 - 实现 shouldLoadInWebView 函数检查 URL 方案是否允许在 WebView 中加载 - 实现 openExternalScheme 函数用于启动外部应用处理非 HTTP 链接 - 在 shouldOverrideUrlLoading 中集成新的 URL 处理逻辑 - 添加对 http、https、about、data、blob、javascript 方案的支持判断
这个提交包含在:
父节点
aa20a790a1
当前提交
dc0cd7b2b1
@ -2,6 +2,8 @@ package com.xuqm.sdk.webview
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@ -30,6 +32,7 @@ import androidx.compose.ui.viewinterop.AndroidView
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
// JS injected into every page to bridge dialog APIs and download interception.
|
// JS injected into every page to bridge dialog APIs and download interception.
|
||||||
// Uses addJavascriptInterface("ReactNativeWebView") for the JS→Native channel.
|
// Uses addJavascriptInterface("ReactNativeWebView") for the JS→Native channel.
|
||||||
@ -107,6 +110,21 @@ true;
|
|||||||
internal fun buildInjectedJs(config: XWebViewConfig): String =
|
internal fun buildInjectedJs(config: XWebViewConfig): String =
|
||||||
DIALOG_OVERRIDE_JS + "\n" + (config.injectedJavaScript ?: "") + "\ntrue;"
|
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].
|
// Routes window.ReactNativeWebView.postMessage() calls to [onMessage].
|
||||||
// @JavascriptInterface methods are called on a background thread; we post to main.
|
// @JavascriptInterface methods are called on a background thread; we post to main.
|
||||||
internal class XWebViewJsBridge(
|
internal class XWebViewJsBridge(
|
||||||
@ -224,7 +242,12 @@ fun XWebViewView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
|
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
|
||||||
return false
|
val uri = request?.url ?: return false
|
||||||
|
if (shouldLoadInWebView(uri)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
openExternalScheme(ctx, uri)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户