mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
App permission manage
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,5 @@
|
|||||||
*.iml
|
*.iml
|
||||||
/.gradle
|
/.gradle
|
||||||
/gradle
|
|
||||||
/local.properties
|
/local.properties
|
||||||
/.idea
|
/.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES"/>
|
||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK_TASK"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK_TASK"/>
|
||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIFI"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIFI"/>
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS"/>
|
||||||
<application
|
<application
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package com.binbin.androidowner
|
package com.binbin.androidowner
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
|
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT
|
||||||
|
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|
||||||
|
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager.NameNotFoundException
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
@@ -17,12 +21,9 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.*
|
||||||
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.Switch
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -31,6 +32,7 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
@@ -89,6 +91,61 @@ fun ApplicationManage(){
|
|||||||
Text("防卸载")
|
Text("防卸载")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(VERSION.SDK_INT>=23&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))){
|
||||||
|
val grantState = mapOf(
|
||||||
|
PERMISSION_GRANT_STATE_DEFAULT to "由用户决定",
|
||||||
|
PERMISSION_GRANT_STATE_GRANTED to "允许",
|
||||||
|
PERMISSION_GRANT_STATE_DENIED to "拒绝"
|
||||||
|
)
|
||||||
|
Column(modifier = sections()){
|
||||||
|
var inputPermission by remember{mutableStateOf("android.permission.")}
|
||||||
|
var currentState by remember{mutableStateOf(grantState[myDpm.getPermissionGrantState(myComponent,pkgName,inputPermission)])}
|
||||||
|
Text(text = "权限管理", style = typography.titleLarge)
|
||||||
|
Text(text = "查看系统支持的权限:adb shell pm list permissions", style = bodyTextStyle)
|
||||||
|
OutlinedTextField(
|
||||||
|
value = inputPermission,
|
||||||
|
label = { Text("权限")},
|
||||||
|
onValueChange = {inputPermission = it},
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
|
||||||
|
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||||
|
enabled = isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp)
|
||||||
|
)
|
||||||
|
Text("当前状态:$currentState", style = bodyTextStyle)
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.setPermissionGrantState(myComponent,pkgName,inputPermission, PERMISSION_GRANT_STATE_GRANTED)
|
||||||
|
currentState = grantState[myDpm.getPermissionGrantState(myComponent,pkgName,inputPermission)]
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth(0.49F)
|
||||||
|
) {
|
||||||
|
Text("允许")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.setPermissionGrantState(myComponent,pkgName,inputPermission, PERMISSION_GRANT_STATE_DENIED)
|
||||||
|
currentState = grantState[myDpm.getPermissionGrantState(myComponent,pkgName,inputPermission)]
|
||||||
|
},
|
||||||
|
Modifier.fillMaxWidth(0.96F)
|
||||||
|
) {
|
||||||
|
Text("拒绝")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.setPermissionGrantState(myComponent,pkgName,inputPermission, PERMISSION_GRANT_STATE_DEFAULT)
|
||||||
|
currentState = grantState[myDpm.getPermissionGrantState(myComponent,pkgName,inputPermission)]
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text("由用户决定")
|
||||||
|
}
|
||||||
|
Text(text ="设为允许或拒绝后,用户不能改变状态", style = bodyTextStyle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(modifier = sections()) {
|
Column(modifier = sections()) {
|
||||||
Text(text = "许可的输入法", style = typography.titleLarge,color = colorScheme.onPrimaryContainer)
|
Text(text = "许可的输入法", style = typography.titleLarge,color = colorScheme.onPrimaryContainer)
|
||||||
var imeList = mutableListOf<String>()
|
var imeList = mutableListOf<String>()
|
||||||
|
|||||||
@@ -194,6 +194,26 @@ fun DeviceControl(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(VERSION.SDK_INT>=23&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))){
|
||||||
|
Column(modifier = sections()){
|
||||||
|
var selectedPolicy by remember{mutableIntStateOf(myDpm.getPermissionPolicy(myComponent))}
|
||||||
|
Text(text = "权限策略", style = typography.titleLarge)
|
||||||
|
RadioButtonItem("默认", {selectedPolicy==PERMISSION_POLICY_PROMPT}, {selectedPolicy= PERMISSION_POLICY_PROMPT})
|
||||||
|
RadioButtonItem("自动允许", {selectedPolicy==PERMISSION_POLICY_AUTO_GRANT}, {selectedPolicy= PERMISSION_POLICY_AUTO_GRANT})
|
||||||
|
RadioButtonItem("自动拒绝", {selectedPolicy==PERMISSION_POLICY_AUTO_DENY}, {selectedPolicy= PERMISSION_POLICY_AUTO_DENY})
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.setPermissionPolicy(myComponent,selectedPolicy)
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text("应用")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(VERSION.SDK_INT>=34&&isDeviceOwner(myDpm)){
|
if(VERSION.SDK_INT>=34&&isDeviceOwner(myDpm)){
|
||||||
Column(modifier = sections()){
|
Column(modifier = sections()){
|
||||||
Text(text = "MTE策略", style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
|
Text(text = "MTE策略", style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
|
||||||
@@ -352,9 +372,7 @@ fun DeviceControl(){
|
|||||||
SysUpdatePolicy()
|
SysUpdatePolicy()
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(modifier = sections(if(isSystemInDarkTheme()){
|
Column(modifier = sections(if(isSystemInDarkTheme()){ colorScheme.errorContainer }else{ colorScheme.errorContainer.copy(alpha = 0.6F) })) {
|
||||||
colorScheme.errorContainer}else{
|
|
||||||
colorScheme.errorContainer.copy(alpha = 0.6F)})) {
|
|
||||||
var flag by remember{ mutableIntStateOf(0) }
|
var flag by remember{ mutableIntStateOf(0) }
|
||||||
var confirmed by remember{ mutableStateOf(false) }
|
var confirmed by remember{ mutableStateOf(false) }
|
||||||
Text(text = "清除数据",style = typography.titleLarge,modifier = Modifier.padding(6.dp),color = colorScheme.onErrorContainer)
|
Text(text = "清除数据",style = typography.titleLarge,modifier = Modifier.padding(6.dp),color = colorScheme.onErrorContainer)
|
||||||
@@ -368,12 +386,8 @@ fun DeviceControl(){
|
|||||||
Button(
|
Button(
|
||||||
onClick = {confirmed=!confirmed},
|
onClick = {confirmed=!confirmed},
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = if(confirmed){
|
containerColor = if(confirmed){ colorScheme.primary }else{ colorScheme.error },
|
||||||
colorScheme.primary}else{
|
contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError }
|
||||||
colorScheme.error},
|
|
||||||
contentColor = if(confirmed){
|
|
||||||
colorScheme.onPrimary}else{
|
|
||||||
colorScheme.onError}
|
|
||||||
),
|
),
|
||||||
enabled = myDpm.isAdminActive(myComponent)
|
enabled = myDpm.isAdminActive(myComponent)
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.binbin.androidowner
|
|||||||
|
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.app.admin.WifiSsidPolicy
|
import android.app.admin.WifiSsidPolicy
|
||||||
|
import android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST
|
||||||
|
import android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.wifi.WifiSsid
|
import android.net.wifi.WifiSsid
|
||||||
@@ -103,8 +105,8 @@ fun Network(){
|
|||||||
var inited by remember{mutableStateOf(false)}
|
var inited by remember{mutableStateOf(false)}
|
||||||
if(!inited){refreshList(); inited=true}
|
if(!inited){refreshList(); inited=true}
|
||||||
Text(text = "WiFi SSID策略", style = typography.titleLarge)
|
Text(text = "WiFi SSID策略", style = typography.titleLarge)
|
||||||
RadioButtonItem("白名单",{selectedPolicyType==WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST},{selectedPolicyType= WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST})
|
RadioButtonItem("白名单",{selectedPolicyType==WIFI_SSID_POLICY_TYPE_ALLOWLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_ALLOWLIST})
|
||||||
RadioButtonItem("黑名单",{selectedPolicyType==WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST},{selectedPolicyType= WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST})
|
RadioButtonItem("黑名单",{selectedPolicyType==WIFI_SSID_POLICY_TYPE_DENYLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_DENYLIST})
|
||||||
Text("SSID列表:")
|
Text("SSID列表:")
|
||||||
Text(text = if(ssidList!=""){ssidList}else{"无"}, style = bodyTextStyle)
|
Text(text = if(ssidList!=""){ssidList}else{"无"}, style = bodyTextStyle)
|
||||||
TextField(
|
TextField(
|
||||||
|
|||||||
@@ -106,8 +106,15 @@ fun Password(){
|
|||||||
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
|
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
if(myDpm.setResetPasswordToken(myComponent, myByteArray)){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show()
|
try {
|
||||||
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
|
if(myDpm.setResetPasswordToken(myComponent, myByteArray)){
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
}else{
|
||||||
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}catch(e:SecurityException){
|
||||||
|
Toast.makeText(myContext, "失败(安全异常)", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
enabled = isDeviceOwner(myDpm),
|
enabled = isDeviceOwner(myDpm),
|
||||||
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.47F)}
|
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.47F)}
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Fri Jan 12 20:22:20 CST 2024
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
Reference in New Issue
Block a user