App manager: Permission manage: use dialog to set permission grant status, remove permission picker

close #64
This commit is contained in:
BinTianqi
2024-07-24 11:20:05 +08:00
parent 2bb045e952
commit a5d5e69a15
5 changed files with 141 additions and 187 deletions

View File

@@ -162,7 +162,6 @@ fun Home(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
composable(route = "AppSetting") { AppSetting(navCtrl, materialYou, blackTheme) } composable(route = "AppSetting") { AppSetting(navCtrl, materialYou, blackTheme) }
composable(route = "Network") { Network(navCtrl) } composable(route = "Network") { Network(navCtrl) }
composable(route = "PackageSelector") { PackageSelector(navCtrl, pkgName) } composable(route = "PackageSelector") { PackageSelector(navCtrl, pkgName) }
composable(route = "PermissionPicker") { PermissionPicker(navCtrl) }
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false) val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false)

View File

@@ -1,120 +0,0 @@
package com.bintianqi.owndroid
import android.Manifest
import android.os.Build.VERSION
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.bintianqi.owndroid.dpm.selectedPermission
import com.bintianqi.owndroid.ui.NavIcon
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PermissionPicker(navCtrl: NavHostController) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = stringResource(R.string.permission_picker)) },
navigationIcon = { NavIcon{ navCtrl.navigateUp() } },
colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.background)
)
}
) { paddingValues->
LazyColumn(
modifier = Modifier.fillMaxSize().padding(top = paddingValues.calculateTopPadding())
) {
items(permissionList()) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable{
selectedPermission.value = it.permission
navCtrl.navigateUp()
}
.padding(vertical = 8.dp, horizontal = 8.dp)
) {
Icon(
painter = painterResource(it.icon),
contentDescription = stringResource(it.label),
modifier = Modifier.padding(start = 8.dp, end = 10.dp)
)
Column {
Text(text = stringResource(it.label))
Text(text = it.permission, modifier = Modifier.alpha(0.8F), style = MaterialTheme.typography.bodyMedium)
}
}
}
items(1) { Spacer(Modifier.padding(vertical = 30.dp)) }
}
}
}
private data class PermissionPickerItem(
val permission: String,
@StringRes val label: Int,
@DrawableRes val icon: Int
)
private fun permissionList(): List<PermissionPickerItem>{
val list = mutableListOf<PermissionPickerItem>()
list.add(PermissionPickerItem(Manifest.permission.READ_EXTERNAL_STORAGE, R.string.permission_READ_EXTERNAL_STORAGE, R.drawable.folder_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, R.string.permission_WRITE_EXTERNAL_STORAGE, R.drawable.folder_fill0))
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_AUDIO, R.string.permission_READ_MEDIA_AUDIO, R.drawable.music_note_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_VIDEO, R.string.permission_READ_MEDIA_VIDEO, R.drawable.movie_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_IMAGES, R.string.permission_READ_MEDIA_IMAGES, R.drawable.image_fill0))
}
list.add(PermissionPickerItem(Manifest.permission.CAMERA, R.string.permission_CAMERA, R.drawable.photo_camera_fill0))
list.add(PermissionPickerItem(Manifest.permission.RECORD_AUDIO, R.string.permission_RECORD_AUDIO, R.drawable.mic_fill0))
list.add(PermissionPickerItem(Manifest.permission.ACCESS_COARSE_LOCATION, R.string.permission_ACCESS_COARSE_LOCATION, R.drawable.location_on_fill0))
list.add(PermissionPickerItem(Manifest.permission.ACCESS_FINE_LOCATION, R.string.permission_ACCESS_FINE_LOCATION, R.drawable.location_on_fill0))
if(VERSION.SDK_INT >= 29) {
list.add(PermissionPickerItem(Manifest.permission.ACCESS_BACKGROUND_LOCATION, R.string.permission_ACCESS_BACKGROUND_LOCATION, R.drawable.location_on_fill0))
}
list.add(PermissionPickerItem(Manifest.permission.READ_CONTACTS, R.string.permission_READ_CONTACTS, R.drawable.contacts_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CONTACTS, R.string.permission_WRITE_CONTACTS, R.drawable.contacts_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_CALENDAR, R.string.permission_READ_CALENDAR, R.drawable.calendar_month_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CALENDAR, R.string.permission_WRITE_CALENDAR, R.drawable.calendar_month_fill0))
list.add(PermissionPickerItem(Manifest.permission.CALL_PHONE, R.string.permission_CALL_PHONE, R.drawable.call_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_PHONE_STATE, R.string.permission_READ_PHONE_STATE, R.drawable.mobile_phone_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_SMS, R.string.permission_READ_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.RECEIVE_SMS, R.string.permission_RECEIVE_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.SEND_SMS, R.string.permission_SEND_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_CALL_LOG, R.string.permission_READ_CALL_LOG, R.drawable.call_log_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CALL_LOG, R.string.permission_WRITE_CALL_LOG, R.drawable.call_log_fill0))
list.add(PermissionPickerItem(Manifest.permission.BODY_SENSORS, R.string.permission_BODY_SENSORS, R.drawable.sensors_fill0))
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.BODY_SENSORS_BACKGROUND, R.string.permission_BODY_SENSORS_BACKGROUND, R.drawable.sensors_fill0))
}
if(VERSION.SDK_INT > 29) {
list.add(PermissionPickerItem(Manifest.permission.ACTIVITY_RECOGNITION, R.string.permission_ACTIVITY_RECOGNITION, R.drawable.history_fill0))
}
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.POST_NOTIFICATIONS, R.string.permission_POST_NOTIFICATIONS, R.drawable.notifications_fill0))
}
return list
}

View File

@@ -19,6 +19,7 @@ import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -41,7 +42,6 @@ import androidx.compose.material3.Card
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
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.material3.OutlinedTextField
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
@@ -55,12 +55,15 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue 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.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -157,7 +160,7 @@ fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState<String>,
} }
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(pkgName.value) } composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(pkgName.value) }
composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName.value) } composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName.value) }
composable(route = "PermissionManage") { PermissionManage(pkgName.value, navCtrl) } composable(route = "PermissionManage") { PermissionManage(pkgName.value) }
composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName.value) } composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName.value) }
composable(route = "CrossProfileWidget") { CrossProfileWidget(pkgName.value) } composable(route = "CrossProfileWidget") { CrossProfileWidget(pkgName.value) }
composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName.value) } composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName.value) }
@@ -399,84 +402,98 @@ private fun UserCtrlDisabledPkg(pkgName:String) {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Composable @Composable
private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { private fun PermissionManage(pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current var showDialog by remember { mutableStateOf(false) }
var inputPermission by remember { mutableStateOf("") } var selectedPermission by remember { mutableStateOf(PermissionPickerItem("", R.string.unknown, R.drawable.block_fill0)) }
var currentState by remember { mutableStateOf(context.getString(R.string.unknown)) } val statusMap = remember { mutableStateMapOf<String, Int>() }
val grantState = mapOf( val grantState = mapOf(
PERMISSION_GRANT_STATE_DEFAULT to stringResource(R.string.default_stringres), PERMISSION_GRANT_STATE_DEFAULT to stringResource(R.string.default_stringres),
PERMISSION_GRANT_STATE_GRANTED to stringResource(R.string.granted), PERMISSION_GRANT_STATE_GRANTED to stringResource(R.string.granted),
PERMISSION_GRANT_STATE_DENIED to stringResource(R.string.denied) PERMISSION_GRANT_STATE_DENIED to stringResource(R.string.denied)
) )
val applyPermission by selectedPermission.collectAsState()
LaunchedEffect(applyPermission) {
if(applyPermission != "") {
inputPermission = applyPermission
selectedPermission.value = ""
}
}
LaunchedEffect(pkgName) { LaunchedEffect(pkgName) {
if(pkgName!="") { currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!! } if(pkgName != "") {
permissionList().forEach { statusMap[it.permission] = dpm.getPermissionGrantState(receiver, pkgName, it.permission) }
}
} }
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp)) Spacer(Modifier.padding(vertical = 4.dp))
Text(text = stringResource(R.string.permission_manage), style = typography.headlineLarge) for(permission in permissionList()) {
Spacer(Modifier.padding(vertical = 5.dp)) Row(
OutlinedTextField( verticalAlignment = Alignment.CenterVertically,
value = inputPermission,
label = { Text(stringResource(R.string.permission)) },
onValueChange = {
inputPermission = it
currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!!
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth(),
trailingIcon = {
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
modifier = Modifier modifier = Modifier
.clip(RoundedCornerShape(50)) .fillMaxWidth()
.clickable(onClick = { navCtrl.navigate("PermissionPicker") }) .clickable {
.padding(3.dp)) if(pkgName != "") {
selectedPermission = permission
showDialog = true
} }
}
.padding(top = 8.dp, bottom = 8.dp, end = 8.dp)
) {
Icon(
painter = painterResource(permission.icon),
contentDescription = stringResource(permission.label),
modifier = Modifier.padding(horizontal = 12.dp)
)
Column {
Text(text = stringResource(permission.label))
Text(
text = grantState[statusMap[permission.permission]]?: stringResource(R.string.unknown),
modifier = Modifier.alpha(0.7F), style = typography.bodyMedium
) )
Spacer(Modifier.padding(vertical = 5.dp))
Text(stringResource(R.string.current_state, currentState))
Spacer(Modifier.padding(vertical = 5.dp))
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
dpm.setPermissionGrantState(receiver,pkgName,inputPermission, PERMISSION_GRANT_STATE_GRANTED)
currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!!
},
modifier = Modifier.fillMaxWidth(0.49F)
) {
Text(stringResource(R.string.grant))
}
Button(
onClick = {
dpm.setPermissionGrantState(receiver,pkgName,inputPermission, PERMISSION_GRANT_STATE_DENIED)
currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!!
},
Modifier.fillMaxWidth(0.96F)
) {
Text(stringResource(R.string.deny))
} }
} }
Button(
onClick = {
dpm.setPermissionGrantState(receiver,pkgName,inputPermission, PERMISSION_GRANT_STATE_DEFAULT)
currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!!
},
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.default_stringres))
} }
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
} }
if(showDialog) {
val grantPermission: (Int)->Unit = {
dpm.setPermissionGrantState(receiver, pkgName, selectedPermission.permission, it)
statusMap[selectedPermission.permission] = dpm.getPermissionGrantState(receiver, pkgName, selectedPermission.permission)
showDialog = false
}
@Composable
fun GrantPermissionItem(label: Int, status: Int) {
val selected = statusMap[selectedPermission.permission] == status
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.background(if(selected) colorScheme.primaryContainer else Color.Transparent)
.clickable { grantPermission(status) }
.padding(vertical = 16.dp, horizontal = 12.dp)
) {
Text(text = stringResource(label), color = if(selected) colorScheme.primary else Color.Unspecified)
if(selected) {
Icon(
painter = painterResource(R.drawable.check_circle_fill0),
contentDescription = stringResource(label),
tint = colorScheme.primary
)
}
}
}
AlertDialog(
onDismissRequest = { showDialog = false },
confirmButton = { TextButton(onClick = { showDialog = false }) { Text(stringResource(R.string.cancel)) } },
title = { Text(stringResource(selectedPermission.label)) },
text = {
Column {
Text(selectedPermission.permission)
Spacer(Modifier.padding(vertical = 4.dp))
GrantPermissionItem(R.string.grant, PERMISSION_GRANT_STATE_GRANTED)
GrantPermissionItem(R.string.deny, PERMISSION_GRANT_STATE_DENIED)
GrantPermissionItem(R.string.default_stringres, PERMISSION_GRANT_STATE_DEFAULT)
}
}
)
}
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")

View File

@@ -1,12 +1,12 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.PendingIntent import android.app.PendingIntent
import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager
import android.app.admin.FactoryResetProtectionPolicy import android.app.admin.FactoryResetProtectionPolicy
import android.app.admin.IDevicePolicyManager import android.app.admin.IDevicePolicyManager
import android.app.admin.SystemUpdatePolicy import android.app.admin.SystemUpdatePolicy
import android.app.admin.WifiSsidPolicy
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -15,7 +15,10 @@ import android.os.Build.VERSION
import androidx.activity.ComponentActivity.CONTEXT_IGNORE_SECURITY import androidx.activity.ComponentActivity.CONTEXT_IGNORE_SECURITY
import androidx.activity.ComponentActivity.DEVICE_POLICY_SERVICE import androidx.activity.ComponentActivity.DEVICE_POLICY_SERVICE
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.bintianqi.owndroid.PackageInstallerReceiver import com.bintianqi.owndroid.PackageInstallerReceiver
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.Receiver
import com.bintianqi.owndroid.backToHomeStateFlow import com.bintianqi.owndroid.backToHomeStateFlow
import com.rosan.dhizuku.api.Dhizuku import com.rosan.dhizuku.api.Dhizuku
@@ -25,7 +28,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
var selectedPermission = MutableStateFlow("")
lateinit var createManagedProfile: ActivityResultLauncher<Intent> lateinit var createManagedProfile: ActivityResultLauncher<Intent>
lateinit var addDeviceAdmin: ActivityResultLauncher<Intent> lateinit var addDeviceAdmin: ActivityResultLauncher<Intent>
@@ -194,3 +196,50 @@ fun Context.resetDevicePolicy() {
} }
dpm.setRecommendedGlobalProxy(receiver, null) dpm.setRecommendedGlobalProxy(receiver, null)
} }
data class PermissionPickerItem(
val permission: String,
@StringRes val label: Int,
@DrawableRes val icon: Int
)
fun permissionList(): List<PermissionPickerItem>{
val list = mutableListOf<PermissionPickerItem>()
list.add(PermissionPickerItem(Manifest.permission.READ_EXTERNAL_STORAGE, R.string.permission_READ_EXTERNAL_STORAGE, R.drawable.folder_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, R.string.permission_WRITE_EXTERNAL_STORAGE, R.drawable.folder_fill0))
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_AUDIO, R.string.permission_READ_MEDIA_AUDIO, R.drawable.music_note_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_VIDEO, R.string.permission_READ_MEDIA_VIDEO, R.drawable.movie_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_MEDIA_IMAGES, R.string.permission_READ_MEDIA_IMAGES, R.drawable.image_fill0))
}
list.add(PermissionPickerItem(Manifest.permission.CAMERA, R.string.permission_CAMERA, R.drawable.photo_camera_fill0))
list.add(PermissionPickerItem(Manifest.permission.RECORD_AUDIO, R.string.permission_RECORD_AUDIO, R.drawable.mic_fill0))
list.add(PermissionPickerItem(Manifest.permission.ACCESS_COARSE_LOCATION, R.string.permission_ACCESS_COARSE_LOCATION, R.drawable.location_on_fill0))
list.add(PermissionPickerItem(Manifest.permission.ACCESS_FINE_LOCATION, R.string.permission_ACCESS_FINE_LOCATION, R.drawable.location_on_fill0))
if(VERSION.SDK_INT >= 29) {
list.add(PermissionPickerItem(Manifest.permission.ACCESS_BACKGROUND_LOCATION, R.string.permission_ACCESS_BACKGROUND_LOCATION, R.drawable.location_on_fill0))
}
list.add(PermissionPickerItem(Manifest.permission.READ_CONTACTS, R.string.permission_READ_CONTACTS, R.drawable.contacts_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CONTACTS, R.string.permission_WRITE_CONTACTS, R.drawable.contacts_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_CALENDAR, R.string.permission_READ_CALENDAR, R.drawable.calendar_month_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CALENDAR, R.string.permission_WRITE_CALENDAR, R.drawable.calendar_month_fill0))
list.add(PermissionPickerItem(Manifest.permission.CALL_PHONE, R.string.permission_CALL_PHONE, R.drawable.call_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_PHONE_STATE, R.string.permission_READ_PHONE_STATE, R.drawable.mobile_phone_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_SMS, R.string.permission_READ_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.RECEIVE_SMS, R.string.permission_RECEIVE_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.SEND_SMS, R.string.permission_SEND_SMS, R.drawable.sms_fill0))
list.add(PermissionPickerItem(Manifest.permission.READ_CALL_LOG, R.string.permission_READ_CALL_LOG, R.drawable.call_log_fill0))
list.add(PermissionPickerItem(Manifest.permission.WRITE_CALL_LOG, R.string.permission_WRITE_CALL_LOG, R.drawable.call_log_fill0))
list.add(PermissionPickerItem(Manifest.permission.BODY_SENSORS, R.string.permission_BODY_SENSORS, R.drawable.sensors_fill0))
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.BODY_SENSORS_BACKGROUND, R.string.permission_BODY_SENSORS_BACKGROUND, R.drawable.sensors_fill0))
}
if(VERSION.SDK_INT > 29) {
list.add(PermissionPickerItem(Manifest.permission.ACTIVITY_RECOGNITION, R.string.permission_ACTIVITY_RECOGNITION, R.drawable.history_fill0))
}
if(VERSION.SDK_INT >= 33) {
list.add(PermissionPickerItem(Manifest.permission.POST_NOTIFICATIONS, R.string.permission_POST_NOTIFICATIONS, R.drawable.notifications_fill0))
}
return list
}

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="m424,664 l282,-282 -56,-56 -226,226 -114,-114 -56,56 170,170ZM480,880q-83,0 -156,-31.5T197,763q-54,-54 -85.5,-127T80,480q0,-83 31.5,-156T197,197q54,-54 127,-85.5T480,80q83,0 156,31.5T763,197q54,54 85.5,127T880,480q0,83 -31.5,156T763,763q-54,54 -127,85.5T480,880ZM480,800q134,0 227,-93t93,-227q0,-134 -93,-227t-227,-93q-134,0 -227,93t-93,227q0,134 93,227t227,93ZM480,480Z"
android:fillColor="#000000"/>
</vector>