mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 03:32:38 +08:00
This commit is contained in:
parent
305c65b776
commit
80b2a23c1f
|
@ -172,7 +172,11 @@ val shizukuOkState by lazy {
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun updatePermissionState() {
|
||||
fun startQueryPkgSettingActivity(context: Activity) {
|
||||
XXPermissions.startPermissionActivity(context, Permission.GET_INSTALLED_APPS)
|
||||
}
|
||||
|
||||
fun updatePermissionState() {
|
||||
arrayOf(
|
||||
notificationState,
|
||||
canDrawOverlaysState,
|
||||
|
|
|
@ -3,19 +3,23 @@ package li.songe.gkd.service
|
|||
import android.provider.Settings
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import li.songe.gkd.app
|
||||
import li.songe.gkd.appScope
|
||||
import li.songe.gkd.permission.writeSecureSettingsState
|
||||
import li.songe.gkd.util.OnChangeListen
|
||||
import li.songe.gkd.util.OnDestroy
|
||||
import li.songe.gkd.util.OnTileClick
|
||||
import li.songe.gkd.util.componentName
|
||||
import li.songe.gkd.util.lastRestartA11yServiceTimeFlow
|
||||
import li.songe.gkd.util.launchTry
|
||||
import li.songe.gkd.util.storeFlow
|
||||
import li.songe.gkd.util.toast
|
||||
import li.songe.gkd.util.useLogLifecycle
|
||||
|
@ -125,13 +129,13 @@ fun switchA11yService(): Boolean {
|
|||
return true
|
||||
}
|
||||
|
||||
fun fixRestartService(): Boolean {
|
||||
fun fixRestartService() = appScope.launchTry(Dispatchers.IO) {
|
||||
// 1. 服务没有运行
|
||||
// 2. 用户配置开启了服务
|
||||
// 3. 有写入系统设置权限
|
||||
if (!A11yService.isRunning.value && storeFlow.value.enableService && writeSecureSettingsState.updateAndGet()) {
|
||||
val t = System.currentTimeMillis()
|
||||
if (t - lastRestartA11yServiceTimeFlow.value < 10_000) return false
|
||||
if (t - lastRestartA11yServiceTimeFlow.value < 5_000) return@launchTry
|
||||
lastRestartA11yServiceTimeFlow.value = t
|
||||
val names = getServiceNames()
|
||||
val a11yBroken = names.contains(a11yClsName)
|
||||
|
@ -139,13 +143,13 @@ fun fixRestartService(): Boolean {
|
|||
// 无障碍出现故障, 重启服务
|
||||
names.remove(a11yClsName)
|
||||
updateServiceNames(names)
|
||||
// 必须等待一段时间, 否则概率不会触发系统重启无障碍服务
|
||||
delay(500)
|
||||
}
|
||||
names.add(a11yClsName)
|
||||
updateServiceNames(names)
|
||||
toast("重启无障碍")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val a11yClsName by lazy { A11yService::class.componentName.flattenToShortString() }
|
||||
|
|
|
@ -172,14 +172,6 @@ fun AuthA11yPage() {
|
|||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
TextButton(onClick = throttle(fn = vm.viewModelScope.launchAsFn(Dispatchers.IO) {
|
||||
grantPermissionByRoot()
|
||||
})) {
|
||||
Text(
|
||||
text = "ROOT授权",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
TextButton(onClick = {
|
||||
vm.showCopyDlgFlow.value = true
|
||||
}) {
|
||||
|
@ -188,6 +180,14 @@ fun AuthA11yPage() {
|
|||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
TextButton(onClick = throttle(fn = vm.viewModelScope.launchAsFn(Dispatchers.IO) {
|
||||
grantPermissionByRoot()
|
||||
})) {
|
||||
Text(
|
||||
text = "ROOT授权",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
|
|
@ -24,15 +24,27 @@ import androidx.lifecycle.viewModelScope
|
|||
import li.songe.gkd.MainActivity
|
||||
import li.songe.gkd.permission.canQueryPkgState
|
||||
import li.songe.gkd.permission.requiredPermission
|
||||
import li.songe.gkd.permission.startQueryPkgSettingActivity
|
||||
import li.songe.gkd.ui.style.EmptyHeight
|
||||
import li.songe.gkd.util.appRefreshingFlow
|
||||
import li.songe.gkd.util.launchAsFn
|
||||
import li.songe.gkd.util.mayQueryPkgNoAccessFlow
|
||||
import li.songe.gkd.util.throttle
|
||||
|
||||
@Composable
|
||||
fun QueryPkgAuthCard() {
|
||||
val canQueryPkg by canQueryPkgState.stateFlow.collectAsState()
|
||||
if (!canQueryPkg) {
|
||||
val mayQueryPkgNoAccess by mayQueryPkgNoAccessFlow.collectAsState()
|
||||
val appRefreshing by appRefreshingFlow.collectAsState()
|
||||
if (appRefreshing) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(EmptyHeight / 2))
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else if (!canQueryPkg || mayQueryPkgNoAccess) {
|
||||
val context = LocalContext.current as MainActivity
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -46,27 +58,20 @@ fun QueryPkgAuthCard() {
|
|||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "如需显示所有应用\n请授予[读取应用列表权限]",
|
||||
text = if (!canQueryPkg) "如需显示所有应用\n请授予[读取应用列表权限]" else "检测到应用数量过少\n可尝试授予[读取应用列表权限]",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
TextButton(onClick = throttle(fn = context.mainVm.viewModelScope.launchAsFn {
|
||||
requiredPermission(context, canQueryPkgState)
|
||||
if (!canQueryPkg) {
|
||||
requiredPermission(context, canQueryPkgState)
|
||||
} else {
|
||||
startQueryPkgSettingActivity(context)
|
||||
}
|
||||
})) {
|
||||
Text(text = "申请权限")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val appRefreshing by appRefreshingFlow.collectAsState()
|
||||
if (appRefreshing) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(EmptyHeight / 2))
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import li.songe.gkd.META
|
||||
import li.songe.gkd.app
|
||||
import li.songe.gkd.appScope
|
||||
import li.songe.gkd.data.AppInfo
|
||||
|
@ -35,6 +36,14 @@ val orderedAppInfosFlow by lazy {
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/orgs/gkd-kit/discussions/761
|
||||
// 某些设备在应用更新后出现权限错乱/缓存错乱
|
||||
val mayQueryPkgNoAccessFlow by lazy {
|
||||
appInfoCacheFlow.map(appScope) { c ->
|
||||
c.values.count { a -> !a.isSystem && !a.hidden && a.id != META.appId } < 8
|
||||
}
|
||||
}
|
||||
|
||||
private val packageReceiver by lazy {
|
||||
object : BroadcastReceiver() {
|
||||
/**
|
||||
|
@ -80,7 +89,7 @@ private fun updateAppInfo(appId: String) {
|
|||
val newMap = appInfoCacheFlow.value.toMutableMap()
|
||||
val info = try {
|
||||
packageManager.getPackageInfo(appId, 0)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
if (info != null) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user