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
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<PkgInfo>()
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
val context = LocalContext.current
@@ -50,8 +74,10 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
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<String>) {
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,48 +103,45 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
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()
.clickable {
system = !system
Toast.makeText(context, if(system) R.string.show_system_app else R.string.show_user_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)
)
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()
}
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() } },
colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background)
@@ -144,9 +160,15 @@ fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
}
if(show) {
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)
}
} else {
PackageItem(it, navCtrl, pkgName)
}
}
}
items(1) { Spacer(Modifier.padding(vertical = 30.dp)) }
} else {

View File

@@ -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,6 +193,7 @@ private fun UserRestrictionItem(
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
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 } },
@@ -207,10 +209,10 @@ private fun UserRestrictionItem(
Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show()
}
}
},
context.isDeviceOwner||context.isProfileOwner
}
)
}
}
object RestrictionData {
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="show_user_app">Kullanıcı 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="suspend">Askıya al</string>
<string name="hide">Gizle</string>
@@ -346,6 +344,7 @@
<string name="select_apk" tools:ignore="TypographyEllipsis">APK seç...</string>
<string name="silent_install">Sessiz yükleme</string>
<string name="request_install">Yükleme isteği</string>
<string name="search">Search</string> <!--TODO-->
<!--App install session status-->
<string name="app_installer_status">Uygulama yükleyici:</string>

View File

@@ -293,8 +293,6 @@
<string name="loading">加载中</string>
<string name="show_user_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="suspend">挂起</string>
<string name="hide">隐藏</string>
@@ -339,6 +337,8 @@
<string name="request_install">请求安装</string>
<string name="enable_system_app">启用系统应用</string>
<string name="enable_system_app_desc">重新启用一个默认被禁用的系统应用</string>
<string name="search">搜索</string>
<!--App install session status-->
<string name="app_installer_status">应用安装器:</string>
<string name="status_pending_action">等待用户操作</string>
<string name="status_fail_blocked">被阻止</string>

View File

@@ -306,8 +306,6 @@
<string name="loading">Loading</string>
<string name="show_user_app">Show user 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="suspend">Suspend</string>
<string name="hide">Hide</string>
@@ -353,6 +351,7 @@
<string name="select_apk" tools:ignore="TypographyEllipsis">Select APK...</string>
<string name="silent_install">Silent install</string>
<string name="request_install">Request install</string>
<string name="search">Search</string>
<!--App install session status-->
<string name="app_installer_status">App installer:</string>
<string name="status_pending_action">Pending user action</string>