search in Package selector

optimize system app filter in Package selector
fix UserRestrictionItem padding
This commit is contained in:
BinTianqi
2024-08-05 18:00:58 +08:00
parent 7b4fccd54b
commit b908a50686
6 changed files with 103 additions and 72 deletions

View File

@@ -1,28 +1,52 @@
package com.bintianqi.owndroid package com.bintianqi.owndroid
import android.content.pm.ApplicationInfo
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.widget.Toast import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.* 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.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape 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.colorScheme
import androidx.compose.material3.MaterialTheme.typography 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.bintianqi.owndroid.ui.NavIcon import com.bintianqi.owndroid.ui.NavIcon
@@ -36,12 +60,12 @@ private data class PkgInfo(
val pkgName: String, val pkgName: String,
val label: String, val label: String,
val icon: Drawable, val icon: Drawable,
val type:String val system: Boolean
) )
private val pkgs = mutableListOf<PkgInfo>() private val pkgs = mutableListOf<PkgInfo>()
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) { fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
val context = LocalContext.current val context = LocalContext.current
@@ -50,8 +74,10 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
var progress by remember { mutableIntStateOf(0) } var progress by remember { mutableIntStateOf(0) }
var show by remember { mutableStateOf(true) } var show by remember { mutableStateOf(true) }
var hideProgress 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 scrollState = rememberLazyListState()
val focusMgr = LocalFocusManager.current
val co = rememberCoroutineScope() val co = rememberCoroutineScope()
val getPkgList: suspend ()->Unit = { val getPkgList: suspend ()->Unit = {
show = false show = false
@@ -59,16 +85,9 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
hideProgress = false hideProgress = false
pkgs.clear() pkgs.clear()
for(pkg in apps) { for(pkg in apps) {
val srcDir = pkg.sourceDir
pkgs += PkgInfo( pkgs += PkgInfo(
pkg.packageName, pkg.loadLabel(pm).toString(), pkg.loadIcon(pm), pkg.packageName, pkg.loadLabel(pm).toString(), pkg.loadIcon(pm),
if(srcDir.contains("/data/")) { "data" } (pkg.flags and ApplicationInfo.FLAG_SYSTEM) != 0
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"}
) )
withContext(Dispatchers.Main) { progress += 1 } withContext(Dispatchers.Main) { progress += 1 }
} }
@@ -84,48 +103,45 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
painter = painterResource(R.drawable.filter_alt_fill0), painter = painterResource(R.drawable.filter_alt_fill0),
contentDescription = "filter", contentDescription = "filter",
modifier = Modifier modifier = Modifier
.padding(horizontal = 6.dp) .padding(horizontal = 4.dp)
.clip(RoundedCornerShape(50)) .clip(RoundedCornerShape(50))
.combinedClickable( .clickable {
onClick = { system = !system
when(filter) { Toast.makeText(context, if(system) R.string.show_system_app else R.string.show_user_app, Toast.LENGTH_SHORT).show()
"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()
}
)
.padding(5.dp) .padding(5.dp)
) )
Icon( Icon(
painter = painterResource(R.drawable.refresh_fill0), painter = painterResource(R.drawable.refresh_fill0),
contentDescription = "refresh", contentDescription = "refresh",
modifier = Modifier modifier = Modifier
.padding(horizontal = 6.dp) .padding(horizontal = 4.dp)
.clip(RoundedCornerShape(50)) .clip(RoundedCornerShape(50))
.clickable { .clickable {
co.launch{ co.launch { getPkgList() }
getPkgList()
}
} }
.padding(5.dp) .padding(5.dp)
) )
}, },
title = { 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) colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background)
@@ -144,9 +160,15 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
} }
if(show) { if(show) {
items(pkgs) { items(pkgs) {
if(filter == it.type) { if(system == it.system) {
if(search != "") {
if(it.pkgName.contains(search, ignoreCase = true) || it.label.contains(search, ignoreCase = true)) {
PackageItem(it, navCtrl, pkgName) PackageItem(it, navCtrl, pkgName)
} }
} else {
PackageItem(it, navCtrl, pkgName)
}
}
} }
items(1) { Spacer(Modifier.padding(vertical = 30.dp)) } items(1) { Spacer(Modifier.padding(vertical = 30.dp)) }
} else { } else {

View File

@@ -8,6 +8,7 @@ import android.widget.Toast
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.ScrollState import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -192,6 +193,7 @@ private fun UserRestrictionItem(
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
Box(modifier = Modifier.padding(start = 22.dp, end = 16.dp)) {
SwitchItem( SwitchItem(
itemName,restrictionDescription,leadIcon, itemName,restrictionDescription,leadIcon,
{ if(context.isDeviceOwner||context.isProfileOwner) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, { if(context.isDeviceOwner||context.isProfileOwner) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } },
@@ -207,10 +209,10 @@ private fun UserRestrictionItem(
Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show()
} }
} }
}, }
context.isDeviceOwner||context.isProfileOwner
) )
} }
}
object RestrictionData { object RestrictionData {
fun internet(): List<Restriction>{ fun internet(): List<Restriction>{

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="m256,760 l-56,-56 224,-224 -224,-224 56,-56 224,224 224,-224 56,56 -224,224 224,224 -56,56 -224,-224 -224,224Z"
android:fillColor="#000000"/>
</vector>

View File

@@ -298,8 +298,6 @@
<string name="loading">Yükleniyor</string> <string name="loading">Yükleniyor</string>
<string name="show_user_app">Kullanıcı uygulamalarını göster</string> <string name="show_user_app">Kullanıcı uygulamalarını göster</string>
<string name="show_system_app">Sistem uygulamalarını göster</string> <string name="show_system_app">Sistem uygulamalarını göster</string>
<string name="show_priv_app">Priv uygulamalarını göster</string>
<string name="show_apex_app">Apex uygulamalarını göster</string>
<string name="permission_picker">İzin seçici</string> <string name="permission_picker">İzin seçici</string>
<string name="suspend">Askıya al</string> <string name="suspend">Askıya al</string>
<string name="hide">Gizle</string> <string name="hide">Gizle</string>
@@ -346,6 +344,7 @@
<string name="select_apk" tools:ignore="TypographyEllipsis">APK seç...</string> <string name="select_apk" tools:ignore="TypographyEllipsis">APK seç...</string>
<string name="silent_install">Sessiz yükleme</string> <string name="silent_install">Sessiz yükleme</string>
<string name="request_install">Yükleme isteği</string> <string name="request_install">Yükleme isteği</string>
<string name="search">Search</string> <!--TODO-->
<!--App install session status--> <!--App install session status-->
<string name="app_installer_status">Uygulama yükleyici:</string> <string name="app_installer_status">Uygulama yükleyici:</string>

View File

@@ -293,8 +293,6 @@
<string name="loading">加载中</string> <string name="loading">加载中</string>
<string name="show_user_app">显示用户应用</string> <string name="show_user_app">显示用户应用</string>
<string name="show_system_app">显示系统应用</string> <string name="show_system_app">显示系统应用</string>
<string name="show_priv_app">显示priv-app</string>
<string name="show_apex_app">显示apex应用</string>
<string name="permission_picker">权限选择器</string> <string name="permission_picker">权限选择器</string>
<string name="suspend">挂起</string> <string name="suspend">挂起</string>
<string name="hide">隐藏</string> <string name="hide">隐藏</string>
@@ -339,6 +337,8 @@
<string name="request_install">请求安装</string> <string name="request_install">请求安装</string>
<string name="enable_system_app">启用系统应用</string> <string name="enable_system_app">启用系统应用</string>
<string name="enable_system_app_desc">重新启用一个默认被禁用的系统应用</string> <string name="enable_system_app_desc">重新启用一个默认被禁用的系统应用</string>
<string name="search">搜索</string>
<!--App install session status-->
<string name="app_installer_status">应用安装器:</string> <string name="app_installer_status">应用安装器:</string>
<string name="status_pending_action">等待用户操作</string> <string name="status_pending_action">等待用户操作</string>
<string name="status_fail_blocked">被阻止</string> <string name="status_fail_blocked">被阻止</string>

View File

@@ -306,8 +306,6 @@
<string name="loading">Loading</string> <string name="loading">Loading</string>
<string name="show_user_app">Show user apps</string> <string name="show_user_app">Show user apps</string>
<string name="show_system_app">Show system apps</string> <string name="show_system_app">Show system apps</string>
<string name="show_priv_app">Show priv-apps</string>
<string name="show_apex_app">Show apex apps</string>
<string name="permission_picker">Permission picker</string> <string name="permission_picker">Permission picker</string>
<string name="suspend">Suspend</string> <string name="suspend">Suspend</string>
<string name="hide">Hide</string> <string name="hide">Hide</string>
@@ -353,6 +351,7 @@
<string name="select_apk" tools:ignore="TypographyEllipsis">Select APK...</string> <string name="select_apk" tools:ignore="TypographyEllipsis">Select APK...</string>
<string name="silent_install">Silent install</string> <string name="silent_install">Silent install</string>
<string name="request_install">Request install</string> <string name="request_install">Request install</string>
<string name="search">Search</string>
<!--App install session status--> <!--App install session status-->
<string name="app_installer_status">App installer:</string> <string name="app_installer_status">App installer:</string>
<string name="status_pending_action">Pending user action</string> <string name="status_pending_action">Pending user action</string>