From a5d5e69a1571677a57af8bc353a27120a323b0c8 Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Wed, 24 Jul 2024 11:20:05 +0800 Subject: [PATCH] App manager: Permission manage: use dialog to set permission grant status, remove permission picker close #64 --- .../com/bintianqi/owndroid/MainActivity.kt | 1 - .../bintianqi/owndroid/PermissionPicker.kt | 120 --------------- .../owndroid/dpm/ApplicationManage.kt | 145 ++++++++++-------- .../java/com/bintianqi/owndroid/dpm/DPM.kt | 53 ++++++- .../main/res/drawable/check_circle_fill0.xml | 9 ++ 5 files changed, 141 insertions(+), 187 deletions(-) delete mode 100644 app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt create mode 100644 app/src/main/res/drawable/check_circle_fill0.xml diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index b3cb331..683eb94 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -162,7 +162,6 @@ fun Home(materialYou:MutableState, blackTheme:MutableState) { composable(route = "AppSetting") { AppSetting(navCtrl, materialYou, blackTheme) } composable(route = "Network") { Network(navCtrl) } composable(route = "PackageSelector") { PackageSelector(navCtrl, pkgName) } - composable(route = "PermissionPicker") { PermissionPicker(navCtrl) } } LaunchedEffect(Unit) { val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false) diff --git a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt b/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt deleted file mode 100644 index b7134a7..0000000 --- a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt +++ /dev/null @@ -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{ - val list = mutableListOf() - 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 -} diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt index 39fd4c0..676d141 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt @@ -19,6 +19,7 @@ import android.provider.Settings import android.widget.Toast import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement @@ -41,7 +42,6 @@ import androidx.compose.material3.Card import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text @@ -55,12 +55,15 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember 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.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.painterResource @@ -157,7 +160,7 @@ fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState, } composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(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 = "CrossProfileWidget") { CrossProfileWidget(pkgName.value) } composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName.value) } @@ -399,84 +402,98 @@ private fun UserCtrlDisabledPkg(pkgName:String) { @SuppressLint("NewApi") @Composable -private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { +private fun PermissionManage(pkgName: String) { val context = LocalContext.current val dpm = context.getDPM() val receiver = context.getReceiver() - val focusMgr = LocalFocusManager.current - var inputPermission by remember { mutableStateOf("") } - var currentState by remember { mutableStateOf(context.getString(R.string.unknown)) } + var showDialog by remember { mutableStateOf(false) } + var selectedPermission by remember { mutableStateOf(PermissionPickerItem("", R.string.unknown, R.drawable.block_fill0)) } + val statusMap = remember { mutableStateMapOf() } val grantState = mapOf( PERMISSION_GRANT_STATE_DEFAULT to stringResource(R.string.default_stringres), PERMISSION_GRANT_STATE_GRANTED to stringResource(R.string.granted), PERMISSION_GRANT_STATE_DENIED to stringResource(R.string.denied) ) - val applyPermission by selectedPermission.collectAsState() - LaunchedEffect(applyPermission) { - if(applyPermission != "") { - inputPermission = applyPermission - selectedPermission.value = "" - } - } 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())) { - Spacer(Modifier.padding(vertical = 10.dp)) - Text(text = stringResource(R.string.permission_manage), style = typography.headlineLarge) - Spacer(Modifier.padding(vertical = 5.dp)) - OutlinedTextField( - 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 - .clip(RoundedCornerShape(50)) - .clickable(onClick = { navCtrl.navigate("PermissionPicker") }) - .padding(3.dp)) - } - ) - 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) + Spacer(Modifier.padding(vertical = 4.dp)) + for(permission in permissionList()) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .clickable { + if(pkgName != "") { + selectedPermission = permission + showDialog = true + } + } + .padding(top = 8.dp, bottom = 8.dp, end = 8.dp) ) { - Text(stringResource(R.string.grant)) + 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 + ) + } } - 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)) } + 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") diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt index 104a6ae..b547300 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt @@ -1,12 +1,12 @@ package com.bintianqi.owndroid.dpm +import android.Manifest import android.annotation.SuppressLint import android.app.PendingIntent import android.app.admin.DevicePolicyManager import android.app.admin.FactoryResetProtectionPolicy import android.app.admin.IDevicePolicyManager import android.app.admin.SystemUpdatePolicy -import android.app.admin.WifiSsidPolicy import android.content.ComponentName import android.content.Context import android.content.Intent @@ -15,7 +15,10 @@ import android.os.Build.VERSION import androidx.activity.ComponentActivity.CONTEXT_IGNORE_SECURITY import androidx.activity.ComponentActivity.DEVICE_POLICY_SERVICE import androidx.activity.result.ActivityResultLauncher +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes import com.bintianqi.owndroid.PackageInstallerReceiver +import com.bintianqi.owndroid.R import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.backToHomeStateFlow import com.rosan.dhizuku.api.Dhizuku @@ -25,7 +28,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import java.io.IOException import java.io.InputStream -var selectedPermission = MutableStateFlow("") lateinit var createManagedProfile: ActivityResultLauncher lateinit var addDeviceAdmin: ActivityResultLauncher @@ -194,3 +196,50 @@ fun Context.resetDevicePolicy() { } dpm.setRecommendedGlobalProxy(receiver, null) } + + +data class PermissionPickerItem( + val permission: String, + @StringRes val label: Int, + @DrawableRes val icon: Int +) + +fun permissionList(): List{ + val list = mutableListOf() + 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 +} diff --git a/app/src/main/res/drawable/check_circle_fill0.xml b/app/src/main/res/drawable/check_circle_fill0.xml new file mode 100644 index 0000000..e63dbdf --- /dev/null +++ b/app/src/main/res/drawable/check_circle_fill0.xml @@ -0,0 +1,9 @@ + + +