82 lines
3.8 KiB
Kotlin
82 lines
3.8 KiB
Kotlin
package top.yeij.hearth.webview
|
||
|
||
import android.annotation.SuppressLint
|
||
import android.app.Activity
|
||
import android.graphics.Color
|
||
import android.view.ViewGroup
|
||
import android.webkit.WebView
|
||
import android.webkit.WebViewClient
|
||
|
||
// WebView 工厂:统一内核配置,桌面层挂到指定父容器,内容层按需创建
|
||
// WebView factory: unified kernel config; the desktop layer attaches to a given
|
||
// parent container, content layers are created on demand
|
||
class WebViewManager(private val activity: Activity) {
|
||
// 创建桌面 WebView(底层 H5)挂到 parent,加载内置 index.html
|
||
// Create the desktop WebView (bottom H5 layer) under parent, load bundled index.html
|
||
@SuppressLint("SetJavaScriptEnabled")
|
||
fun attach(bridge: JsBridge, parent: ViewGroup): WebView {
|
||
val webView = WebView(activity)
|
||
webView.setBackgroundColor(Color.TRANSPARENT)
|
||
configure(webView)
|
||
webView.addJavascriptInterface(bridge, "HearthBridge")
|
||
webView.webViewClient = WebViewClient()
|
||
webView.loadUrl("file:///android_asset/h5/index.html")
|
||
parent.addView(webView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
|
||
return webView
|
||
}
|
||
|
||
// 创建内容 WebView(webAPP 标签页),仅配置不加载、不挂载(由宿主管理)
|
||
// 透明背景:webAPP 未声明背景色时透出桌面壁纸,而非默认白底
|
||
// Create a content WebView (webapp tab), configured but not loaded/attached
|
||
// (lifecycle is managed by the host); transparent background so a webapp without
|
||
// a declared background shows the wallpaper instead of a default white
|
||
@SuppressLint("SetJavaScriptEnabled")
|
||
fun createContentWebView(ua: String?, scale: Int?): WebView {
|
||
val webView = WebView(activity)
|
||
webView.setBackgroundColor(Color.TRANSPARENT)
|
||
configure(webView)
|
||
// UA 解析:desktop/pc → PC UA;自定义字符串 → 直接用;null → 默认平板 UA
|
||
// UA resolution: desktop/pc -> desktop UA; custom string -> used as-is;
|
||
// null -> default tablet UA
|
||
webView.settings.userAgentString = when {
|
||
ua == null -> UA_TABLET
|
||
ua == "desktop" || ua == "pc" -> UA_DESKTOP
|
||
else -> ua
|
||
}
|
||
// scale 由 WebAppHost 在 onPageFinished 里通过 CSS zoom 实现(reflow 缩放),
|
||
// 此处不再做 View 级别缩放
|
||
// scale is applied by WebAppHost via CSS zoom in onPageFinished (reflow
|
||
// scaling); no view-level scaling here
|
||
return webView
|
||
}
|
||
|
||
// 统一内核配置:JS、宽视口、DOM 存储,禁用缩放
|
||
// Common kernel config: JS, wide viewport, DOM storage, zoom disabled
|
||
@SuppressLint("SetJavaScriptEnabled")
|
||
private fun configure(webView: WebView) {
|
||
webView.settings.apply {
|
||
javaScriptEnabled = true
|
||
useWideViewPort = true
|
||
loadWithOverviewMode = true
|
||
setSupportZoom(false)
|
||
domStorageEnabled = true
|
||
// Android 11 + targetSdk 30 默认禁用 file:// 访问,本地离线包需要显式开启
|
||
// Android 11 + targetSdk 30 disables file:// by default; local offline
|
||
// packages need it explicitly enabled
|
||
allowFileAccess = true
|
||
allowContentAccess = true
|
||
}
|
||
}
|
||
|
||
companion object {
|
||
// PC 版 UA(desktop/pc)
|
||
private const val UA_DESKTOP =
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
|
||
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||
// 安卓平板 UA(默认)
|
||
private const val UA_TABLET =
|
||
"Mozilla/5.0 (Linux; Android 13; SM-X700 Build/TP1A.220624.014) " +
|
||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||
}
|
||
}
|