diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3569209..b8c1e5a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,6 +15,9 @@ android { buildTypes { release { isMinifyEnabled = false } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } + // 本地单元测试中 android.* 桩方法返回默认值(避免 Log.d 抛 "not mocked") + // android.* stub methods return default values in local unit tests (avoid Log.d "not mocked") + testOptions { unitTests { isReturnDefaultValues = true } } } dependencies { implementation("androidx.core:core-ktx:1.13.1") diff --git a/app/src/main/java/top/yeij/hearth/MainActivity.kt b/app/src/main/java/top/yeij/hearth/MainActivity.kt index bab453f..f1b2e41 100644 --- a/app/src/main/java/top/yeij/hearth/MainActivity.kt +++ b/app/src/main/java/top/yeij/hearth/MainActivity.kt @@ -1,10 +1,13 @@ package top.yeij.hearth import android.app.Activity +import android.content.res.Configuration import android.os.Bundle import android.util.Log import android.view.WindowInsets import android.view.WindowInsetsController +import top.yeij.hearth.webview.JsBridge +import top.yeij.hearth.webview.WebViewManager // HOME 桌面 activity,后续 Task 挂载 WebView 与 JsBridge // HOME launcher activity; later tasks mount WebView and JsBridge @@ -18,6 +21,28 @@ class MainActivity : Activity() { super.onCreate(savedInstanceState) Log.d(TAG, "onCreate: enter immersive mode") enterImmersive() + setupWebView() + } + + // 创建 JsBridge 并挂载 WebView 桌面层 + // Create JsBridge and mount the WebView launcher layer + private fun setupWebView() { + val dm = resources.displayMetrics + val darkMode = + (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == + Configuration.UI_MODE_NIGHT_YES + val bridge = JsBridge( + deviceWidthPx = dm.widthPixels, + deviceHeightPx = dm.heightPixels, + density = dm.density, + darkMode = darkMode, + ) + WebViewManager(this).attach(bridge) + Log.d( + TAG, + "setupWebView: attached WebView ${dm.widthPixels}x${dm.heightPixels}" + + " density=${dm.density} darkMode=$darkMode" + ) } // 进入沉浸式全屏:隐藏状态栏与导航栏,滑动可临时唤出 diff --git a/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt b/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt new file mode 100644 index 0000000..0d5ae33 --- /dev/null +++ b/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt @@ -0,0 +1,25 @@ +package top.yeij.hearth.webview + +import android.util.Log + +class JsBridge( + private val deviceWidthPx: Int, + private val deviceHeightPx: Int, + private val density: Float, + private val darkMode: Boolean, +) { + private val gson = com.google.gson.Gson() + + @android.webkit.JavascriptInterface + fun getDeviceInfo(): String { + Log.d("HearthBridge", "getDeviceInfo called") + return gson.toJson( + mapOf( + "widthPx" to deviceWidthPx, + "heightPx" to deviceHeightPx, + "density" to density, + "darkMode" to darkMode + ) + ) + } +} diff --git a/app/src/main/java/top/yeij/hearth/webview/WebViewManager.kt b/app/src/main/java/top/yeij/hearth/webview/WebViewManager.kt new file mode 100644 index 0000000..ebcc73d --- /dev/null +++ b/app/src/main/java/top/yeij/hearth/webview/WebViewManager.kt @@ -0,0 +1,26 @@ +package top.yeij.hearth.webview + +import android.annotation.SuppressLint +import android.app.Activity +import android.webkit.WebView +import android.webkit.WebSettings +import android.webkit.WebViewClient + +class WebViewManager(private val activity: Activity) { + @SuppressLint("SetJavaScriptEnabled") + fun attach(bridge: JsBridge): WebView { + val webView = WebView(activity) + webView.settings.apply { + javaScriptEnabled = true + useWideViewPort = true + loadWithOverviewMode = true + setSupportZoom(false) + domStorageEnabled = true + } + webView.addJavascriptInterface(bridge, "HearthBridge") + webView.webViewClient = WebViewClient() + webView.loadUrl("file:///android_asset/h5/index.html") + activity.setContentView(webView) + return webView + } +} diff --git a/app/src/test/java/top/yeij/hearth/webview/JsBridgeTest.kt b/app/src/test/java/top/yeij/hearth/webview/JsBridgeTest.kt new file mode 100644 index 0000000..6d95cc1 --- /dev/null +++ b/app/src/test/java/top/yeij/hearth/webview/JsBridgeTest.kt @@ -0,0 +1,14 @@ +package top.yeij.hearth.webview + +import org.junit.Assert.assertTrue +import org.junit.Test + +class JsBridgeTest { + @Test + fun getDeviceInfo_returnsJsonWithDarkMode() { + val bridge = JsBridge(deviceWidthPx = 800, deviceHeightPx = 480, density = 2.0f, darkMode = true) + val json = bridge.getDeviceInfo() + assertTrue(json.contains("\"widthPx\":800")) + assertTrue(json.contains("\"darkMode\":true")) + } +}