feat: add notification-access setting item with jump
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// 设置页:Miuix Preference 分组 + 玻璃条目(仅 UI 骨架,交互留后续)
|
// 设置页:Miuix Preference 分组 + 玻璃条目(通知使用权为可用交互项)
|
||||||
// Settings page: Miuix Preference groups + glass items (UI skeleton only; interactions later)
|
// Settings page: Miuix Preference groups + glass items (notification access is interactive)
|
||||||
window.loadSettings = function () {
|
window.loadSettings = function () {
|
||||||
const page = document.querySelector('[data-page="settings"]');
|
const page = document.querySelector('[data-page="settings"]');
|
||||||
if (page.dataset.loaded) return; page.dataset.loaded = '1';
|
if (page.dataset.loaded) return; page.dataset.loaded = '1';
|
||||||
@@ -7,10 +7,30 @@ window.loadSettings = function () {
|
|||||||
<div class="st-group">显示</div>
|
<div class="st-group">显示</div>
|
||||||
<div class="st-item"><span class="lbl">跟随系统主题</span><span class="sw on"><i></i></span></div>
|
<div class="st-item"><span class="lbl">跟随系统主题</span><span class="sw on"><i></i></span></div>
|
||||||
<div class="st-item"><span class="lbl">屏幕亮度</span><span class="slider"><i></i></span></div>
|
<div class="st-item"><span class="lbl">屏幕亮度</span><span class="slider"><i></i></span></div>
|
||||||
|
<div class="st-group">权限</div>
|
||||||
|
<div class="st-item" id="notif-access">
|
||||||
|
<span class="lbl">通知使用权(媒体卡)</span>
|
||||||
|
<span class="arrow" id="notif-access-state">›</span>
|
||||||
|
</div>
|
||||||
<div class="st-group">网络</div>
|
<div class="st-group">网络</div>
|
||||||
<div class="st-item"><span class="lbl">webAPP 服务器地址</span><span class="arrow">›</span></div>
|
<div class="st-item"><span class="lbl">webAPP 服务器地址</span><span class="arrow">›</span></div>
|
||||||
<div class="st-item"><span class="lbl">检查更新</span><span class="arrow">›</span></div>
|
<div class="st-item"><span class="lbl">检查更新</span><span class="arrow">›</span></div>
|
||||||
<div class="st-group">关于</div>
|
<div class="st-group">关于</div>
|
||||||
<div class="st-item"><span class="lbl">版本 0.1.0</span><span class="arrow">›</span></div>
|
<div class="st-item"><span class="lbl">版本 0.1.0</span><span class="arrow">›</span></div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
setupNotificationAccess(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通知使用权授权项:异步查状态,未授权点击跳转系统授权页
|
||||||
|
// Notification-access item: async state check, tap to open the system grant page
|
||||||
|
function setupNotificationAccess(page) {
|
||||||
|
const item = page.querySelector('#notif-access');
|
||||||
|
const state = page.querySelector('#notif-access-state');
|
||||||
|
bridge.call('getNotificationAccess').then(granted => {
|
||||||
|
state.textContent = granted ? '已开启 ✓' : '去开启 ›';
|
||||||
|
if (granted) state.style.color = 'var(--accent)';
|
||||||
|
}).catch(() => {});
|
||||||
|
item.onclick = () => {
|
||||||
|
bridge.call('requestNotificationAccess').catch(() => {});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package top.yeij.hearth
|
package top.yeij.hearth
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -24,6 +26,7 @@ import top.yeij.hearth.webapp.Tab
|
|||||||
import top.yeij.hearth.webapp.WebAppContainer
|
import top.yeij.hearth.webapp.WebAppContainer
|
||||||
import top.yeij.hearth.webapp.WebAppRepository
|
import top.yeij.hearth.webapp.WebAppRepository
|
||||||
import top.yeij.hearth.webview.JsBridge
|
import top.yeij.hearth.webview.JsBridge
|
||||||
|
import top.yeij.hearth.webview.NotificationAccessProvider
|
||||||
import top.yeij.hearth.webview.WebAppHost
|
import top.yeij.hearth.webview.WebAppHost
|
||||||
import top.yeij.hearth.webview.WebViewManager
|
import top.yeij.hearth.webview.WebViewManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -47,6 +50,19 @@ class MainActivity : Activity() {
|
|||||||
private val webAppContainer = WebAppContainer()
|
private val webAppContainer = WebAppContainer()
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
private val webAppHost = WebAppHostImpl()
|
private val webAppHost = WebAppHostImpl()
|
||||||
|
|
||||||
|
// 通知使用权访问实现:检查授权状态 + 跳转系统授权页(供设置页授权项使用)
|
||||||
|
// Notification-access implementation: check grant state + jump to system settings
|
||||||
|
// (used by the settings permission item)
|
||||||
|
private val notificationAccess = object : NotificationAccessProvider {
|
||||||
|
override fun isGranted(): Boolean =
|
||||||
|
NotificationManagerCompat.getEnabledListenerPackages(this@MainActivity)
|
||||||
|
.contains(packageName)
|
||||||
|
|
||||||
|
override fun requestAccess() {
|
||||||
|
startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
|
||||||
|
}
|
||||||
|
}
|
||||||
private lateinit var mediaSource: MediaSessionSource
|
private lateinit var mediaSource: MediaSessionSource
|
||||||
private lateinit var root: FrameLayout
|
private lateinit var root: FrameLayout
|
||||||
private lateinit var desktopWebView: WebView
|
private lateinit var desktopWebView: WebView
|
||||||
@@ -91,6 +107,7 @@ class MainActivity : Activity() {
|
|||||||
webAppContainer = webAppContainer,
|
webAppContainer = webAppContainer,
|
||||||
webAppHost = webAppHost,
|
webAppHost = webAppHost,
|
||||||
postToMainThread = { desktopWebView.post(it) },
|
postToMainThread = { desktopWebView.post(it) },
|
||||||
|
notificationAccess = notificationAccess,
|
||||||
)
|
)
|
||||||
root = FrameLayout(this)
|
root = FrameLayout(this)
|
||||||
setContentView(root)
|
setContentView(root)
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ import top.yeij.hearth.webapp.WebApp
|
|||||||
import top.yeij.hearth.webapp.WebAppContainer
|
import top.yeij.hearth.webapp.WebAppContainer
|
||||||
import top.yeij.hearth.webapp.WebAppRepository
|
import top.yeij.hearth.webapp.WebAppRepository
|
||||||
|
|
||||||
|
// 通知使用权访问接口:由 MainActivity 实现,JsBridge 通过它检查/申请授权,
|
||||||
|
// 保持 JsBridge 可 JVM 单测(不直接依赖 Context/NotificationManagerCompat)
|
||||||
|
// Notification-access provider implemented by MainActivity; JsBridge uses it to
|
||||||
|
// check/request access, keeping JsBridge JVM-testable (no direct Context dependency)
|
||||||
|
interface NotificationAccessProvider {
|
||||||
|
fun isGranted(): Boolean
|
||||||
|
fun requestAccess()
|
||||||
|
}
|
||||||
|
|
||||||
class JsBridge(
|
class JsBridge(
|
||||||
private val deviceWidthPx: Int,
|
private val deviceWidthPx: Int,
|
||||||
private val deviceHeightPx: Int,
|
private val deviceHeightPx: Int,
|
||||||
@@ -23,6 +32,9 @@ class JsBridge(
|
|||||||
// 主线程执行器:View 操作必须切到主线程;null(单测)时同步执行
|
// 主线程执行器:View 操作必须切到主线程;null(单测)时同步执行
|
||||||
// Main-thread executor: view ops must run on main; null (unit tests) runs inline
|
// Main-thread executor: view ops must run on main; null (unit tests) runs inline
|
||||||
private val postToMainThread: ((() -> Unit) -> Unit)? = null,
|
private val postToMainThread: ((() -> Unit) -> Unit)? = null,
|
||||||
|
// 通知使用权访问接口(检查/申请授权),供设置页授权项使用
|
||||||
|
// Notification-access provider (check/request) for the settings permission item
|
||||||
|
private val notificationAccess: NotificationAccessProvider? = null,
|
||||||
) {
|
) {
|
||||||
private val gson = com.google.gson.Gson()
|
private val gson = com.google.gson.Gson()
|
||||||
|
|
||||||
@@ -185,6 +197,19 @@ class JsBridge(
|
|||||||
return gson.toJson(cards)
|
return gson.toJson(cards)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回通知使用权是否已授权(未接入返回 false)
|
||||||
|
// Return whether notification access is granted (false when not wired)
|
||||||
|
@android.webkit.JavascriptInterface
|
||||||
|
fun getNotificationAccess(): Boolean = notificationAccess?.isGranted() ?: false
|
||||||
|
|
||||||
|
// 跳转系统「通知使用权」设置页,让用户为媒体卡授权
|
||||||
|
// Jump to the system notification-access settings page for media-card grant
|
||||||
|
@android.webkit.JavascriptInterface
|
||||||
|
fun requestNotificationAccess() {
|
||||||
|
Log.d("HearthBridge", "requestNotificationAccess called")
|
||||||
|
notificationAccess?.requestAccess()
|
||||||
|
}
|
||||||
|
|
||||||
// 注册媒体会话监听,回调推送给 H5(info 为 null 时推 "null")
|
// 注册媒体会话监听,回调推送给 H5(info 为 null 时推 "null")
|
||||||
// Register media session listener; push callbacks to H5 (push "null" when info is null)
|
// Register media session listener; push callbacks to H5 (push "null" when info is null)
|
||||||
fun setMediaListener(source: MediaSessionSource, webView: android.webkit.WebView) {
|
fun setMediaListener(source: MediaSessionSource, webView: android.webkit.WebView) {
|
||||||
|
|||||||
Reference in New Issue
Block a user