mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
App manager: Permission manage: use dialog to set permission grant status, remove permission picker
close #64
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
9
app/src/main/res/drawable/check_circle_fill0.xml
Normal file
9
app/src/main/res/drawable/check_circle_fill0.xml
Normal 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>
|
||||||
Reference in New Issue
Block a user