diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a13ed1a1..58b7dcf4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -42,6 +42,7 @@ android { } dependencies { + implementation(libs.coil.compose) implementation(libs.androidx.work.runtime.ktx) implementation(libs.androidx.work.runtime) implementation(libs.converter.scalars) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9d5c9169..8fa683cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,8 @@ + { item { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text(text = "加载中...") + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = stringResource(id = R.string.loading)) } } } diff --git a/app/src/main/java/com/android/skip/ui/whitelist/WhiteListRepository.kt b/app/src/main/java/com/android/skip/ui/whitelist/WhiteListRepository.kt index 50e28799..ee892d53 100644 --- a/app/src/main/java/com/android/skip/ui/whitelist/WhiteListRepository.kt +++ b/app/src/main/java/com/android/skip/ui/whitelist/WhiteListRepository.kt @@ -1,13 +1,35 @@ package com.android.skip.ui.whitelist -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData +import com.android.skip.MyApp +import com.android.skip.R +import com.android.skip.util.dataStore +import com.blankj.utilcode.util.StringUtils.getString +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Singleton @Singleton class WhiteListRepository @Inject constructor() { - private val _whiteList: MutableList = mutableListOf() + private val _whiteList: MutableList by lazy { + runBlocking { + initWhitelist().toMutableList() + } + } + + private suspend fun initWhitelist() = withContext(Dispatchers.IO) { + val allPreferences = MyApp.context.dataStore.data.first() + allPreferences.asMap() + .filter { + it.key.name.startsWith(getString(R.string.whitelist_dot)) && it.value == true + }.keys.map { + it.name.substringAfter( + getString(R.string.whitelist_dot) + ) + } + } fun updateWhiteList(packageName: String, checked: Boolean) { if (checked) { diff --git a/app/src/main/java/com/android/skip/ui/whitelist/WhiteListViewModel.kt b/app/src/main/java/com/android/skip/ui/whitelist/WhiteListViewModel.kt index 2cc5d6ec..56ad7434 100644 --- a/app/src/main/java/com/android/skip/ui/whitelist/WhiteListViewModel.kt +++ b/app/src/main/java/com/android/skip/ui/whitelist/WhiteListViewModel.kt @@ -1,13 +1,26 @@ package com.android.skip.ui.whitelist import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.android.skip.R +import com.android.skip.util.DataStoreUtils +import com.blankj.utilcode.util.StringUtils.getString import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel class WhiteListViewModel @Inject constructor( private val whiteListRepository: WhiteListRepository ) : ViewModel() { - fun updateWhiteList(packageName: String, checked: Boolean) = + fun updateWhiteList(packageName: String, checked: Boolean) { whiteListRepository.updateWhiteList(packageName, checked) + viewModelScope.launch { + withContext(Dispatchers.IO) { + DataStoreUtils.putData(getString(R.string.whitelist_dot) + packageName, checked) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/android/skip/ui/whitelist/list/AppListColumn.kt b/app/src/main/java/com/android/skip/ui/whitelist/list/AppListColumn.kt index d2605a97..f41fb528 100644 --- a/app/src/main/java/com/android/skip/ui/whitelist/list/AppListColumn.kt +++ b/app/src/main/java/com/android/skip/ui/whitelist/list/AppListColumn.kt @@ -1,8 +1,10 @@ package com.android.skip.ui.whitelist.list +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -10,14 +12,19 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.paging.LoadState import androidx.paging.compose.collectAsLazyPagingItems +import coil.annotation.ExperimentalCoilApi +import coil.compose.rememberImagePainter +import com.android.skip.R import com.android.skip.ui.components.FlatButton import com.android.skip.ui.components.RowContent import com.android.skip.ui.whitelist.WhiteListViewModel -import com.google.accompanist.drawablepainter.rememberDrawablePainter +@OptIn(ExperimentalCoilApi::class) @Composable fun AppListColumn( appListViewModel: AppListViewModel, @@ -36,10 +43,10 @@ fun AppListColumn( title = item.appName, subTitle = item.packageName, { - Icon( - painter = rememberDrawablePainter(drawable = item.appIcon), + Image( + painter = rememberImagePainter(data = item.appIcon), contentDescription = null, - tint = Color.Unspecified + modifier = Modifier.size(40.dp) ) }, checked.value, { checked.value = it @@ -54,8 +61,11 @@ fun AppListColumn( when { loadState.refresh is LoadState.Loading -> { item { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text(text = "加载中...") + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = stringResource(id = R.string.loading)) } } } diff --git a/app/src/main/java/com/android/skip/ui/whitelist/list/AppListRepository.kt b/app/src/main/java/com/android/skip/ui/whitelist/list/AppListRepository.kt index c68ec4aa..2f567fb0 100644 --- a/app/src/main/java/com/android/skip/ui/whitelist/list/AppListRepository.kt +++ b/app/src/main/java/com/android/skip/ui/whitelist/list/AppListRepository.kt @@ -1,27 +1,29 @@ package com.android.skip.ui.whitelist.list +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import com.android.skip.MyApp import com.android.skip.dataclass.AppListItem import com.android.skip.ui.whitelist.WhiteListRepository -import com.blankj.utilcode.util.AppUtils import javax.inject.Inject -import javax.inject.Singleton -@Singleton class AppListRepository @Inject constructor() { @Inject lateinit var whiteListRepository: WhiteListRepository - private var appInfos: MutableList = mutableListOf() + private val appInfos: MutableList by lazy { + MyApp.context.packageManager.getInstalledApplications(PackageManager.GET_META_DATA) + } fun getData(currentPage: Int, pageSize: Int, isShowSystem: Boolean): List { try { - if (appInfos.isEmpty()) appInfos = AppUtils.getAppsInfo() + val pkgManager = MyApp.context.packageManager val apps = if (isShowSystem) { appInfos } else { - appInfos.filterNot { it.isSystem } + appInfos.filter { (it.flags and ApplicationInfo.FLAG_SYSTEM) == 0 } } val fromIndex = currentPage * pageSize val toIndex = minOf(fromIndex + pageSize, apps.size) @@ -29,9 +31,9 @@ class AppListRepository @Inject constructor() { return apps.subList(fromIndex, toIndex) .map { AppListItem( - it.name, + it.loadLabel(pkgManager).toString(), it.packageName, - it.icon, + it.loadIcon(pkgManager), whiteListRepository.isAppInWhiteList(it.packageName) ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 76265216..011cad88 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,6 +32,7 @@ 显示系统应用 功能介绍 https://skip.guoxicheng.top/guide/white-list/intro + WHITELIST_DOT 设置 是否允许提示 @@ -107,4 +108,6 @@ 无障碍服务运行中 布局检查服务运行中 + + 加载中… \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2b3ae3ec..29ba1145 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ accompanistDrawablepainter = "0.34.0" activityCompose = "1.9.0" agp = "8.5.1" +coilCompose = "1.3.2" converterScalars = "2.5.0" datastorePreferences = "1.0.0" gson = "2.10.1" @@ -42,6 +43,7 @@ androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version.r androidx-ui = { module = "androidx.compose.ui:ui", version.ref = "ui" } androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "workRuntime" } androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntime" } +coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } converter-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "converterScalars" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }