feat: page preload, card grid span, wallpaper into webview for glass blur

This commit is contained in:
2026-08-16 19:51:08 +08:00
parent 1a79b4ed55
commit 8c42dca7bc
8 changed files with 175 additions and 47 deletions
@@ -1,12 +1,16 @@
package top.yeij.hearth
import android.app.Activity
import android.app.WallpaperManager
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.util.Base64
import android.util.Log
import android.view.View
import android.view.ViewGroup
@@ -30,8 +34,10 @@ import top.yeij.hearth.webview.BrightnessProvider
import top.yeij.hearth.webview.JsBridge
import top.yeij.hearth.webview.NotificationAccessProvider
import top.yeij.hearth.webview.ServerUrlProvider
import top.yeij.hearth.webview.WallpaperProvider
import top.yeij.hearth.webview.WebAppHost
import top.yeij.hearth.webview.WebViewManager
import java.io.ByteArrayOutputStream
import java.io.File
// HOME 桌面 activity,接线各能力层:Repository、媒体监听、多 WebView webAPP 管理
@@ -106,6 +112,35 @@ class MainActivity : Activity() {
}
}
// 壁纸提供实现:WallpaperManager 取当前壁纸转 base64,供 H5 body 背景使用
// Wallpaper implementation: WallpaperManager -> base64 for the H5 body background
private val wallpaperProvider = object : WallpaperProvider {
override fun getWallpaperBase64(): String {
return try {
val wm = WallpaperManager.getInstance(this@MainActivity)
// 动态壁纸(Live Wallpaper)是实时渲染、无静态 Drawable,返回空让 H5 保持
// 透明透出动态壁纸;此时玻璃模糊降级为普通半透明(backdrop-filter 无内容可模糊)
// Live wallpapers render in real time with no static drawable; return empty
// so H5 stays transparent and shows the live wallpaper, with the glass blur
// degrading to plain translucency (backdrop-filter has nothing to blur)
if (wm.wallpaperInfo != null) return ""
val d = wm.drawable ?: return ""
val dm = resources.displayMetrics
val bmp = Bitmap.createBitmap(dm.widthPixels, dm.heightPixels, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
d.setBounds(0, 0, dm.widthPixels, dm.heightPixels)
d.draw(canvas)
val out = ByteArrayOutputStream()
bmp.compress(Bitmap.CompressFormat.JPEG, 80, out)
bmp.recycle()
"data:image/jpeg;base64," + Base64.encodeToString(out.toByteArray(), Base64.NO_WRAP)
} catch (e: Exception) {
Log.w(TAG, "getWallpaper: ${e.message}")
""
}
}
}
private lateinit var webAppRepository: WebAppRepository
private lateinit var mediaSource: MediaSessionSource
private lateinit var root: FrameLayout
@@ -155,6 +190,7 @@ class MainActivity : Activity() {
notificationAccess = notificationAccess,
brightness = brightnessProvider,
serverUrl = serverUrlProvider,
wallpaper = wallpaperProvider,
)
root = FrameLayout(this)
setContentView(root)
@@ -36,6 +36,14 @@ interface ServerUrlProvider {
fun setServerUrl(url: String)
}
// 壁纸提供接口:由 MainActivity 实现(WallpaperManager 转 base64),
// 让壁纸进入 WebView 内部,backdrop-filter 玻璃才能模糊到壁纸
// Wallpaper provider implemented by MainActivity (WallpaperManager -> base64), so the
// wallpaper lives inside the WebView and the glass backdrop-filter can blur it
interface WallpaperProvider {
fun getWallpaperBase64(): String
}
class JsBridge(
private val deviceWidthPx: Int,
private val deviceHeightPx: Int,
@@ -58,6 +66,9 @@ class JsBridge(
// 服务器地址存储接口
// Server URL storage provider
private val serverUrl: ServerUrlProvider? = null,
// 壁纸提供接口(base64
// Wallpaper provider (base64)
private val wallpaper: WallpaperProvider? = null,
) {
private val gson = com.google.gson.Gson()
@@ -270,6 +281,11 @@ class JsBridge(
serverUrl?.setServerUrl(url)
}
// 返回壁纸 base64(data URI,未接入返回空字符串)
// Return the wallpaper base64 (data URI; empty string when not wired)
@android.webkit.JavascriptInterface
fun getWallpaper(): String = wallpaper?.getWallpaperBase64() ?: ""
// 重新拉取 webAPP 清单 + 卡片目录,返回 { count }
// Re-fetch the webAPP manifest + card catalog, return { count }
@android.webkit.JavascriptInterface