fix(keepalive): 权限「去系统设置里授权后回来」这一档现在真能把服务起起来(补 W53S 登记的那一格)
问题(W53S 标出、我核过代码确认):CyreneApp 里那个起停前台服务的 LaunchedEffect 的 key 只有 `keepAliveEnabled` 与登录态,而通知权限是**现读**的 ⇒ 用户在系统设置里授权后回到 App 时它不会重跑, 设置页已经显示「已开」而服务其实没起(要等下次启动或再动一次开关)。 修法:给 AppPresence 补一条**与既有 `appInForeground` 同源**的 StateFlow(`onStart/onStop` 里 从同一个集合重算,布尔 getter 语义一字未动),让那个 effect 收它当 key —— 「回到前台」正是 「从系统设置返回」必经、且必然变化的那一位。没有新增任何依赖。
This commit is contained in:
1 parent
6505512c0a
commit
77fbedc350
2 files changed
+22
-1
No files matched your search
@@ -40,7 +40,10 @@ fun CyreneApp(container: AppContainer) {
|
|||||||
* 而授权变化只有两条路——本端刚申请完(设置页那次写入会连带把这里重跑一遍)、或用户在系统
|
* 而授权变化只有两条路——本端刚申请完(设置页那次写入会连带把这里重跑一遍)、或用户在系统
|
||||||
* 设置里改过(下次启动必然重跑)。
|
* 设置里改过(下次启动必然重跑)。
|
||||||
*/
|
*/
|
||||||
LaunchedEffect(prefs.keepAliveEnabled, state) {
|
// ⚠️ key 里必须有「回到前台」这一位(W53S 登记的那一格):通知权限是**现读**的,而用户在系统
|
||||||
|
// 设置里授权后回到 App 时,只有这个状态会变 —— 少了它,UI 会说「已开」而服务其实没起。
|
||||||
|
val appInForeground by container.appPresence.appInForegroundFlow.collectAsState()
|
||||||
|
LaunchedEffect(prefs.keepAliveEnabled, state, appInForeground) {
|
||||||
when (
|
when (
|
||||||
keepAliveAction(
|
keepAliveAction(
|
||||||
enabled = prefs.keepAliveEnabled,
|
enabled = prefs.keepAliveEnabled,
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package top.yeij.cyrene.core.notify
|
|||||||
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 进程级的两个「我此刻在哪儿」的事实(W53N):**App 在不在前台**、**聊天页正显示哪个会话**。
|
* 进程级的两个「我此刻在哪儿」的事实(W53N):**App 在不在前台**、**聊天页正显示哪个会话**。
|
||||||
@@ -44,9 +47,23 @@ class AppPresence {
|
|||||||
val appInForeground: Boolean
|
val appInForeground: Boolean
|
||||||
get() = startedActivities.isNotEmpty()
|
get() = startedActivities.isNotEmpty()
|
||||||
|
|
||||||
|
private val _appInForeground = MutableStateFlow(false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [appInForeground] 的**可订阅**形态(W53S 登记的那一格要它)。
|
||||||
|
*
|
||||||
|
* 为什么需要第二条出口:`CyreneApp` 那个「起 / 停前台服务」的 `LaunchedEffect` 的 key 里没有
|
||||||
|
* 通知权限,于是**用户在系统设置里授权后回到 App** 时它不会重跑 —— UI 已经显示「已开」,
|
||||||
|
* 服务却没起。权限本身必须**现读**(不该缓存成状态),能当 key 的是「刚好会在这件事发生时变化」
|
||||||
|
* 的信号:**回到前台**(从系统设置返回必经 `onStart`)。所以这里把「在不在前台」补成一条流。
|
||||||
|
* 判据本身仍然只读 [appInForeground] 那个布尔——两条出口算的是**同一份事实**(同一个集合)。
|
||||||
|
*/
|
||||||
|
val appInForegroundFlow: StateFlow<Boolean> = _appInForeground.asStateFlow()
|
||||||
|
|
||||||
/** 一个 Activity 进入「可见」这一档(`onStart`)。 */
|
/** 一个 Activity 进入「可见」这一档(`onStart`)。 */
|
||||||
fun onActivityStarted(owner: Any) {
|
fun onActivityStarted(owner: Any) {
|
||||||
startedActivities.add(owner)
|
startedActivities.add(owner)
|
||||||
|
_appInForeground.value = appInForeground
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +74,7 @@ class AppPresence {
|
|||||||
*/
|
*/
|
||||||
fun onActivityStopped(owner: Any) {
|
fun onActivityStopped(owner: Any) {
|
||||||
startedActivities.remove(owner)
|
startedActivities.remove(owner)
|
||||||
|
_appInForeground.value = appInForeground
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 聊天页刚显示(或刚换成)[sessionId];`null` = 它离开了屏幕。 */
|
/** 聊天页刚显示(或刚换成)[sessionId];`null` = 它离开了屏幕。 */
|
||||||
|
|||||||
Reference in new issue
Block a user