From b908a50686f21cd8c8cb713a138ede135b01af33 Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Mon, 5 Aug 2024 18:00:58 +0800 Subject: [PATCH] search in Package selector optimize system app filter in Package selector fix UserRestrictionItem padding --- .../com/bintianqi/owndroid/PkgSelector.kt | 122 +++++++++++------- .../bintianqi/owndroid/dpm/UserRestriction.kt | 34 ++--- app/src/main/res/drawable/close_fill0.xml | 9 ++ app/src/main/res/values-tr/strings.xml | 3 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values/strings.xml | 3 +- 6 files changed, 103 insertions(+), 72 deletions(-) create mode 100644 app/src/main/res/drawable/close_fill0.xml diff --git a/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt b/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt index d99c909..f2aee06 100644 --- a/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt +++ b/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt @@ -1,28 +1,52 @@ package com.bintianqi.owndroid +import android.content.pm.ApplicationInfo import android.graphics.drawable.Drawable import android.widget.Toast import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.runtime.* +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import com.bintianqi.owndroid.ui.NavIcon @@ -36,12 +60,12 @@ private data class PkgInfo( val pkgName: String, val label: String, val icon: Drawable, - val type:String + val system: Boolean ) private val pkgs = mutableListOf() -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { val context = LocalContext.current @@ -50,8 +74,10 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { var progress by remember { mutableIntStateOf(0) } var show by remember { mutableStateOf(true) } var hideProgress by remember { mutableStateOf(true) } - var filter by remember { mutableStateOf("data") } + var system by remember { mutableStateOf(false) } + var search by remember { mutableStateOf("") } val scrollState = rememberLazyListState() + val focusMgr = LocalFocusManager.current val co = rememberCoroutineScope() val getPkgList: suspend ()->Unit = { show = false @@ -59,16 +85,9 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { hideProgress = false pkgs.clear() for(pkg in apps) { - val srcDir = pkg.sourceDir pkgs += PkgInfo( pkg.packageName, pkg.loadLabel(pm).toString(), pkg.loadIcon(pm), - if(srcDir.contains("/data/")) { "data" } - else if( - srcDir.contains("system/priv-app")||srcDir.contains("product/priv-app")|| - srcDir.contains("ext/priv-app")||srcDir.contains("vendor/priv-app") - ) {"priv"} - else if(srcDir.contains("apex")) {"apex"} - else{"system"} + (pkg.flags and ApplicationInfo.FLAG_SYSTEM) != 0 ) withContext(Dispatchers.Main) { progress += 1 } } @@ -84,50 +103,47 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { painter = painterResource(R.drawable.filter_alt_fill0), contentDescription = "filter", modifier = Modifier - .padding(horizontal = 6.dp) + .padding(horizontal = 4.dp) .clip(RoundedCornerShape(50)) - .combinedClickable( - onClick = { - when(filter) { - "data"-> { - filter = "system"; co.launch {scrollState.scrollToItem(0) } - Toast.makeText(context, R.string.show_system_app, Toast.LENGTH_SHORT).show() - } - "system"-> { - filter = "priv"; co.launch {scrollState.scrollToItem(0) } - Toast.makeText(context, R.string.show_priv_app, Toast.LENGTH_SHORT).show() - } - else-> { - filter = "data"; co.launch {scrollState.scrollToItem(0) } - Toast.makeText(context, R.string.show_user_app, Toast.LENGTH_SHORT).show() - } - } - }, - onLongClick = { - filter = "apex" - Toast.makeText(context, R.string.show_apex_app, Toast.LENGTH_SHORT).show() - } - ) + .clickable { + system = !system + Toast.makeText(context, if(system) R.string.show_system_app else R.string.show_user_app, Toast.LENGTH_SHORT).show() + } .padding(5.dp) ) Icon( painter = painterResource(R.drawable.refresh_fill0), contentDescription = "refresh", modifier = Modifier - .padding(horizontal = 6.dp) + .padding(horizontal = 4.dp) .clip(RoundedCornerShape(50)) - .clickable{ - co.launch{ - getPkgList() - } + .clickable { + co.launch { getPkgList() } } .padding(5.dp) ) }, title = { - Text(text = stringResource(R.string.pkg_selector)) + OutlinedTextField( + value = search, + onValueChange = { search = it }, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + keyboardActions = KeyboardActions { focusMgr.clearFocus() }, + placeholder = { Text(stringResource(R.string.search)) }, + trailingIcon = { + Icon( + painter = painterResource(R.drawable.close_fill0), + contentDescription = "clear search", + modifier = Modifier.clickable { + search = "" + focusMgr.clearFocus() + } + ) + }, + modifier = Modifier.padding(vertical = 8.dp) + ) }, - navigationIcon = { NavIcon{navCtrl.navigateUp() } }, + navigationIcon = { NavIcon{ navCtrl.navigateUp() } }, colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background) ) } @@ -144,12 +160,18 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { } if(show) { items(pkgs) { - if(filter == it.type) { - PackageItem(it, navCtrl, pkgName) + if(system == it.system) { + if(search != "") { + if(it.pkgName.contains(search, ignoreCase = true) || it.label.contains(search, ignoreCase = true)) { + PackageItem(it, navCtrl, pkgName) + } + } else { + PackageItem(it, navCtrl, pkgName) + } } } items(1) { Spacer(Modifier.padding(vertical = 30.dp)) } - }else{ + } else { items(1) { Spacer(Modifier.padding(top = 5.dp)) Text(text = stringResource(R.string.loading), modifier = Modifier.alpha(0.8F)) @@ -157,7 +179,7 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { } } LaunchedEffect(Unit) { - if(pkgs.size==0) { getPkgList() } + if(pkgs.size == 0) { getPkgList() } } } } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt index 933abd7..ab58e1f 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt @@ -8,6 +8,7 @@ import android.widget.Toast import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -192,24 +193,25 @@ private fun UserRestrictionItem( val context = LocalContext.current val dpm = context.getDPM() val receiver = context.getReceiver() - SwitchItem( - itemName,restrictionDescription,leadIcon, - { if(context.isDeviceOwner||context.isProfileOwner) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, - { - try{ - if(it) { - dpm.addUserRestriction(receiver,restriction) - }else{ - dpm.clearUserRestriction(receiver,restriction) - } - }catch(e:SecurityException) { - if(context.isProfileOwner) { - Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() + Box(modifier = Modifier.padding(start = 22.dp, end = 16.dp)) { + SwitchItem( + itemName,restrictionDescription,leadIcon, + { if(context.isDeviceOwner||context.isProfileOwner) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, + { + try{ + if(it) { + dpm.addUserRestriction(receiver,restriction) + }else{ + dpm.clearUserRestriction(receiver,restriction) + } + }catch(e:SecurityException) { + if(context.isProfileOwner) { + Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() + } } } - }, - context.isDeviceOwner||context.isProfileOwner - ) + ) + } } object RestrictionData { diff --git a/app/src/main/res/drawable/close_fill0.xml b/app/src/main/res/drawable/close_fill0.xml new file mode 100644 index 0000000..0dffe63 --- /dev/null +++ b/app/src/main/res/drawable/close_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d1b6e66..a4d87e4 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -298,8 +298,6 @@ Yükleniyor Kullanıcı uygulamalarını göster Sistem uygulamalarını göster - Priv uygulamalarını göster - Apex uygulamalarını göster İzin seçici Askıya al Gizle @@ -346,6 +344,7 @@ APK seç... Sessiz yükleme Yükleme isteği + Search Uygulama yükleyici: diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index fea670a..4608e77 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -293,8 +293,6 @@ 加载中 显示用户应用 显示系统应用 - 显示priv-app - 显示apex应用 权限选择器 挂起 隐藏 @@ -339,6 +337,8 @@ 请求安装 启用系统应用 重新启用一个默认被禁用的系统应用 + 搜索 + 应用安装器: 等待用户操作 被阻止 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd7ae10..4529352 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -306,8 +306,6 @@ Loading Show user apps Show system apps - Show priv-apps - Show apex apps Permission picker Suspend Hide @@ -353,6 +351,7 @@ Select APK... Silent install Request install + Search App installer: Pending user action