From 59cbc1246a81d264a7b3555a50112e2fbe4db445 Mon Sep 17 00:00:00 2001
From: BinTianqi <1220958406@qq.com>
Date: Mon, 22 Jan 2024 14:13:20 +0800
Subject: [PATCH] support profile owner
---
app/src/main/AndroidManifest.xml | 3 +
.../binbin/androidowner/ApplicationManage.kt | 8 +-
.../com/binbin/androidowner/DeviceControl.kt | 113 ++++++------
.../com/binbin/androidowner/MainActivity.kt | 8 +-
.../java/com/binbin/androidowner/Password.kt | 17 +-
.../com/binbin/androidowner/Permissions.kt | 95 ++++++++---
.../main/java/com/binbin/androidowner/User.kt | 39 +++--
.../com/binbin/androidowner/UserRestrict.kt | 161 ++++++++++--------
gradle.properties | 22 +--
9 files changed, 279 insertions(+), 187 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 48efe20..26ad53a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,9 @@
+
+
+
Unit
){
var isEnabled by remember{ mutableStateOf(false) }
- if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){
+ if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
isEnabled = getMethod()
}
Row(
@@ -141,7 +141,7 @@ private fun AppManageItem(
setMethod(!isEnabled)
isEnabled = getMethod()
},
- enabled = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
+ enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
)
}
}
diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt
index 11f0550..ecd55c0 100644
--- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt
+++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt
@@ -4,9 +4,9 @@ import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.os.Build.VERSION
+import android.os.UserManager
import android.widget.Toast
import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -21,7 +21,6 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.RadioButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -46,62 +45,73 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte
.padding(bottom = 20.dp)
.navigationBarsPadding()
) {
- DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0,myDpm,{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)})
- DeviceCtrlItem(R.string.disable_scrcap,R.string.aosp_scrrec_also_work,R.drawable.screenshot_fill0,myDpm,{myDpm.getScreenCaptureDisabled(null)},{b -> myDpm.setScreenCaptureDisabled(myComponent,b) })
- if(VERSION.SDK_INT>=34){
+ if(isDeviceOwner(myDpm)){
+ DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0,myDpm,{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)})
+ }
+ if(isDeviceOwner(myDpm)){
+ DeviceCtrlItem(R.string.disable_scrcap,R.string.aosp_scrrec_also_work,R.drawable.screenshot_fill0,myDpm,{myDpm.getScreenCaptureDisabled(null)},{b -> myDpm.setScreenCaptureDisabled(myComponent,b) })
+ }
+ if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser))){
DeviceCtrlItem(R.string.hide_status_bar,R.string.may_hide_notifi_icon_only,R.drawable.notifications_fill0,myDpm,{myDpm.isStatusBarDisabled},{b -> myDpm.setStatusBarDisabled(myComponent,b) })
}
- if(VERSION.SDK_INT>=30){
+ if(VERSION.SDK_INT>=30&&isDeviceOwner(myDpm)){
DeviceCtrlItem(R.string.auto_time,R.string.place_holder,R.drawable.schedule_fill0,myDpm,{myDpm.getAutoTimeEnabled(myComponent)},{b -> myDpm.setAutoTimeEnabled(myComponent,b) })
DeviceCtrlItem(R.string.auto_timezone,R.string.place_holder,R.drawable.globe_fill0,myDpm,{myDpm.getAutoTimeZoneEnabled(myComponent)},{b -> myDpm.setAutoTimeZoneEnabled(myComponent,b) })
}
- DeviceCtrlItem(R.string.master_mute,R.string.place_holder,R.drawable.volume_up_fill0,myDpm,{myDpm.isMasterVolumeMuted(myComponent)},{b -> myDpm.setMasterVolumeMuted(myComponent,b) })
- if(VERSION.SDK_INT>=26){
+ if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
+ DeviceCtrlItem(R.string.master_mute,R.string.place_holder,R.drawable.volume_up_fill0,myDpm,{myDpm.isMasterVolumeMuted(myComponent)},{b -> myDpm.setMasterVolumeMuted(myComponent,b) })
+ }
+ if(VERSION.SDK_INT>=26&&(isDeviceOwner(myDpm)|| isProfileOwner(myDpm))){
DeviceCtrlItem(R.string.backup_service,R.string.place_holder,R.drawable.backup_fill0,myDpm,{myDpm.isBackupServiceEnabled(myComponent)},{b -> myDpm.setBackupServiceEnabled(myComponent,b) })
}
- DeviceCtrlItem(R.string.disable_bt_contact_share,R.string.place_holder,R.drawable.account_circle_fill0,myDpm,{myDpm.getBluetoothContactSharingDisabled(myComponent)},{b -> myDpm.setBluetoothContactSharingDisabled(myComponent,b)})
- if(VERSION.SDK_INT>=31){
+ if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
+ DeviceCtrlItem(R.string.disable_bt_contact_share,R.string.place_holder,R.drawable.account_circle_fill0,myDpm,{myDpm.getBluetoothContactSharingDisabled(myComponent)},{b -> myDpm.setBluetoothContactSharingDisabled(myComponent,b)})
+ }
+ if(VERSION.SDK_INT>=31&&isDeviceOwner(myDpm)){
if(myDpm.canUsbDataSignalingBeDisabled()){
DeviceCtrlItem(R.string.usb_signal,R.string.place_holder,R.drawable.usb_fill0,myDpm,{myDpm.isUsbDataSignalingEnabled},{b -> myDpm.isUsbDataSignalingEnabled = b })
}else{
Text("你的设备不支持关闭USB信号")
}
}
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = 6.dp, vertical = 4.dp)
- .clip(RoundedCornerShape(15))
- .background(color = MaterialTheme.colorScheme.primaryContainer)
- .padding(vertical = 5.dp),
- horizontalArrangement = Arrangement.SpaceEvenly
- ) {
- Button(
- onClick = {
- if(myDpm.setKeyguardDisabled(myComponent,true)){
- Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
- }else{
- Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
- }
- },
- enabled = isDeviceOwner(myDpm)
+ if(VERSION.SDK_INT>=28){
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 6.dp, vertical = 4.dp)
+ .clip(RoundedCornerShape(15))
+ .background(color = MaterialTheme.colorScheme.primaryContainer)
+ .padding(vertical = 5.dp),
+ horizontalArrangement = Arrangement.SpaceEvenly
) {
- Text("禁用锁屏(需无密码)")
- }
- Spacer(Modifier.padding(horizontal = 5.dp))
- Button(
- onClick = {
- if(myDpm.setKeyguardDisabled(myComponent,false)){
- Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
- }else{
- Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
- }
- },
- enabled = isDeviceOwner(myDpm)
- ) {
- Text("启用锁屏")
+ Button(
+ onClick = {
+ if(myDpm.setKeyguardDisabled(myComponent,true)){
+ Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
+ }else{
+ Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
+ }
+ },
+ enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser)
+ ) {
+ Text("禁用锁屏(需无密码)")
+ }
+ Spacer(Modifier.padding(horizontal = 5.dp))
+ Button(
+ onClick = {
+ if(myDpm.setKeyguardDisabled(myComponent,false)){
+ Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
+ }else{
+ Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
+ }
+ },
+ enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser)
+ ) {
+ Text("启用锁屏")
+ }
}
}
+
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier
@@ -141,10 +151,16 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte
if(VERSION.SDK_INT<34){
Text("隐藏状态栏需要API34")
}
- Button(onClick = {myDpm.uninstallAllUserCaCerts(myComponent)},modifier = Modifier.align(Alignment.CenterHorizontally), enabled = isDeviceOwner(myDpm)) {
+ Button(
+ onClick = {myDpm.uninstallAllUserCaCerts(myComponent)},
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
+ ) {
Text(text = "清除用户Ca证书")
}
- SysUpdatePolicy(myDpm,myComponent,myContext)
+ if(isDeviceOwner(myDpm)){
+ SysUpdatePolicy(myDpm,myComponent,myContext)
+ }
Column(
modifier = Modifier
.fillMaxWidth()
@@ -168,7 +184,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte
containerColor = if(confirmed){MaterialTheme.colorScheme.primary}else{MaterialTheme.colorScheme.error},
contentColor = if(confirmed){MaterialTheme.colorScheme.onPrimary}else{MaterialTheme.colorScheme.onError}
),
- enabled = isDeviceOwner(myDpm)
+ enabled = myDpm.isAdminActive(myComponent)
) {
Text(text = if(confirmed){"取消"}else{"确定"})
}
@@ -241,16 +257,13 @@ private fun DeviceCtrlItem(
}
}
}
- if(isDeviceOwner(myDpm)){
- isEnabled = getMethod()
- }
+ isEnabled = getMethod()
Switch(
checked = isEnabled,
onCheckedChange = {
setMethod(!isEnabled)
isEnabled=getMethod()
- },
- enabled = isDeviceOwner(myDpm)
+ }
)
}
}
diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt
index b09720d..d65350c 100644
--- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt
+++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt
@@ -128,7 +128,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent,mainContext)})
composable(route = "Permissions", content = { DpmPermissions(mainDpm,mainComponent,mainContext,navCtrl)})
composable(route = "ApplicationManage", content = { ApplicationManage(mainDpm,mainComponent,mainContext)})
- composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent)})
+ composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent,mainContext)})
composable(route = "UserManage", content = { UserManage(mainDpm,mainComponent,mainContext)})
composable(route = "Password", content = { Password(mainDpm,mainComponent,mainContext)})
}
@@ -139,7 +139,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:ComponentName){
val isda = myDpm.isAdminActive(myComponent)
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
- val activateType = if(isdo){"Device Owner"}else if(isda){"Device Admin"}else{""}
+ val activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(isda){"Device Admin"}else{""}
val isActivated = if(isdo||isda){"已激活"}else{"未激活"}
Column {
Row(
@@ -235,3 +235,7 @@ fun RadioButtonItem(
fun isDeviceOwner(dpm:DevicePolicyManager): Boolean {
return dpm.isDeviceOwnerApp("com.binbin.androidowner")
}
+
+fun isProfileOwner(dpm:DevicePolicyManager): Boolean {
+ return dpm.isProfileOwnerApp("com.binbin.androidowner")
+}
diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt
index 8b0c738..5e622a3 100644
--- a/app/src/main/java/com/binbin/androidowner/Password.kt
+++ b/app/src/main/java/com/binbin/androidowner/Password.kt
@@ -145,19 +145,26 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 4.dp)
- .clip(RoundedCornerShape(10))
+ .clip(RoundedCornerShape(16.dp))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(10.dp)
) {
TextField(
value = newPwd,
onValueChange = {newPwd=it},
- enabled = !confirmed&& isDeviceOwner(myDpm),
+ enabled = !confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)),
label = { Text("密码")},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
)
Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 5.dp))
+ var resetPwdFlag by remember{ mutableStateOf(0) }
+ RadioButtonItem("RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT",
+ {resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT},
+ {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT})
+ RadioButtonItem("RESET_PASSWORD_REQUIRE_ENTRY",{resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY},
+ {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY})
+ RadioButtonItem("无",{resetPwdFlag==0},{resetPwdFlag=0})
Row {
Button(
onClick = {
@@ -165,14 +172,14 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
}else{ Toast.makeText(myContext, "需要4位数字或字母", Toast.LENGTH_SHORT).show() }
},
modifier = Modifier.padding(end = 10.dp),
- enabled = isDeviceOwner(myDpm)
+ enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
) {
Text("确认密码")
}
if(VERSION.SDK_INT>=26){
Button(
onClick = {
- val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,0)
+ val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show()
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
confirmed=false
@@ -185,7 +192,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
}else{
Button(
onClick = {
- val resetSuccess = myDpm.resetPassword(newPwd,0)
+ val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show()
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
confirmed=false
diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt
index e1932b2..7154e6e 100644
--- a/app/src/main/java/com/binbin/androidowner/Permissions.kt
+++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt
@@ -102,6 +102,58 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
Text("或者进入设置 -> 安全 -> 更多安全设置 -> 设备管理应用 -> Android Owner")
}
}
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 5.dp)
+ .clip(RoundedCornerShape(15))
+ .background(color = MaterialTheme.colorScheme.primaryContainer)
+ .padding(10.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Column {
+ Text(text = "Profile Owner", style = MaterialTheme.typography.titleLarge)
+ Text(if(isProfileOwner(myDpm)){"已激活"}else{"未激活"})
+ }
+ if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24){
+ Button(
+ onClick = {
+ myDpm.clearProfileOwner(myComponent)
+ navCtrl.navigate("HomePage") {
+ popUpTo(
+ navCtrl.graph.findStartDestination().id
+ ) { saveState = true }
+ }
+ }
+ ) {
+ Text("撤销")
+ }
+ }
+ }
+ if(!isProfileOwner(myDpm)){
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 5.dp)
+ .clip(RoundedCornerShape(15.dp))
+ .background(color = MaterialTheme.colorScheme.tertiaryContainer)
+ .padding(10.dp),
+ horizontalAlignment = Alignment.Start
+ ) {
+ if(!isDeviceOwner(myDpm)){
+ Text("你可以在adb shell中使用以下命令激活Profile Owner")
+ SelectionContainer {
+ Text("dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
+ color = MaterialTheme.colorScheme.onTertiaryContainer)
+ }
+ Text("一个设备只能有一个Device owner,强烈建议激活Device owner")
+ }
+ if(isDeviceOwner(myDpm)){
+ Text("Device owner创建其他用户后,这个应用会成为新用户的Profile owner")
+ }
+ }
+ }
Row(
modifier = Modifier
.fillMaxWidth()
@@ -131,7 +183,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
}
}
}
- if(isdo||isda){
+ if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)){
Text(
text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态",
color = MaterialTheme.colorScheme.onErrorContainer,
@@ -143,27 +195,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
.padding(6.dp)
)
}
- if(isdo){
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .padding(vertical = 5.dp)
- .clip(RoundedCornerShape(15))
- .background(color = MaterialTheme.colorScheme.primaryContainer)
- .padding(8.dp)
- ) {
- Text(text = "设备信息", style = MaterialTheme.typography.titleLarge)
- if(VERSION.SDK_INT>=30){
- val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile
- Text("由组织拥有的工作资料设备:$orgDevice")
- }
- if(VERSION.SDK_INT>=34&&(myDpm.isProfileOwnerApp("com.binbin.androidowner")||myDpm.isManagedProfile(myComponent))){
- val financed = myDpm.isDeviceFinanced
- Text("Financed Device : $financed")
- }
- }
- }
- if(!isdo){
+ if(!isdo&&!isProfileOwner(myDpm)){
Column(
modifier = Modifier
.fillMaxWidth()
@@ -183,6 +215,25 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
}
}
}
+ if(VERSION.SDK_INT>=30){
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 5.dp)
+ .clip(RoundedCornerShape(15))
+ .background(color = MaterialTheme.colorScheme.primaryContainer)
+ .padding(8.dp)
+ ) {
+ Text(text = "设备信息", style = MaterialTheme.typography.titleLarge)
+ val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile
+ Text("由组织拥有的受管理资料设备:$orgDevice")
+ Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}")
+ if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){
+ val financed = myDpm.isDeviceFinanced
+ Text("企业资产 : $financed")
+ }
+ }
+ }
if(isdo&&VERSION.SDK_INT>=24){
DeviceOwnerInfo(R.string.owner_lockscr_info,R.string.place_holder,R.string.owner_lockscr_info,focusManager,myContext,
diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt
index a3e80e0..81bab3d 100644
--- a/app/src/main/java/com/binbin/androidowner/User.kt
+++ b/app/src/main/java/com/binbin/androidowner/User.kt
@@ -1,5 +1,6 @@
package com.binbin.androidowner
+import android.app.ActivityManager
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
@@ -43,7 +44,6 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
//val myUM = myContext.getSystemService(Context.USER_SERVICE)
val currentUser = android.os.Process.myUserHandle()
val userList = Test.returnUsers(myContext)
- Text("因为我的模拟器的多用户无法使用,部分功能并未测试")
Column(
modifier = Modifier
.fillMaxWidth()
@@ -60,16 +60,16 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
Text("支持多用户:${UserManager.supportsMultipleUsers()}")
}
if(VERSION.SDK_INT>=31){
- Text("Headless system user: ${UserManager.isHeadlessSystemUserMode()}")
+ Text("系统用户: ${UserManager.isHeadlessSystemUserMode()}")
}
Spacer(Modifier.padding(vertical = 5.dp))
- if (VERSION.SDK_INT >= 28&& isDeviceOwner(myDpm)) {
+ if (VERSION.SDK_INT >= 28) {
val logoutable = myDpm.isLogoutEnabled
Text(text = "用户可以退出 : $logoutable")
val ephemeralUser = myDpm.isEphemeralUser(myComponent)
Text(text = "临时用户: $ephemeralUser")
val affiliatedUser = myDpm.isAffiliatedUser
- Text(text = "Affiliated User: $affiliatedUser")
+ Text(text = "次级用户: $affiliatedUser")
}
Spacer(Modifier.padding(5.dp))
Text("切换用户后或设备重启后会删除临时用户")
@@ -88,7 +88,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
var resultForLogout by remember{ mutableIntStateOf(-1) }
var resultForStop by remember{ mutableIntStateOf(-1) }
Text("登出用户需要成为次级用户的Profile Owner")
- Button(onClick = {resultForLogout = myDpm.logoutUser(myComponent)}, enabled = isDeviceOwner(myDpm)) {
+ Button(onClick = {resultForLogout = myDpm.logoutUser(myComponent)}, enabled = isProfileOwner(myDpm)) {
Text("登出用户")
}
if(resultForLogout!=-1){
@@ -100,6 +100,11 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
if(resultForStop!=-1){
Text(userOperationResultCode(resultForStop))
}
+ if(isProfileOwner(myDpm)){
+ Button(onClick = {myDpm.setProfileEnabled(myComponent)}) {
+ Text(text = "启用资料")
+ }
+ }
}
Button(
onClick = {
@@ -169,10 +174,10 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
}else{
Text("创建用户需安卓7")
}
- UserSessionMessage("用户名","用户名",myDpm,myContext,{null},{msg -> myDpm.setProfileName(myComponent, msg.toString())})
+ UserSessionMessage("用户名","用户名",true,myDpm,myContext,{null},{msg -> myDpm.setProfileName(myComponent, msg.toString())})
if(VERSION.SDK_INT>=28){
- UserSessionMessage("用户会话开始消息","消息",myDpm,myContext,{myDpm.getStartUserSessionMessage(myComponent)},{msg -> myDpm.setStartUserSessionMessage(myComponent,msg)})
- UserSessionMessage("用户会话结束消息","消息",myDpm,myContext,{myDpm.getEndUserSessionMessage(myComponent)},{msg -> myDpm.setEndUserSessionMessage(myComponent,msg)})
+ UserSessionMessage("用户会话开始消息","消息",false,myDpm,myContext,{myDpm.getStartUserSessionMessage(myComponent)},{msg -> myDpm.setStartUserSessionMessage(myComponent,msg)})
+ UserSessionMessage("用户会话结束消息","消息",false,myDpm,myContext,{myDpm.getEndUserSessionMessage(myComponent)},{msg -> myDpm.setEndUserSessionMessage(myComponent,msg)})
}
Spacer(Modifier.padding(vertical = 30.dp))
}
@@ -182,6 +187,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
fun UserSessionMessage(
text:String,
textField:String,
+ profileOwner:Boolean,
myDpm:DevicePolicyManager,
myContext: Context,
get:()->CharSequence?,
@@ -196,29 +202,26 @@ fun UserSessionMessage(
.padding(10.dp)
) {
val focusMgr = LocalFocusManager.current
- var msg:CharSequence? by remember{ mutableStateOf(null) }
- if(isDeviceOwner(myDpm)){
- msg = if(get()==null){""}else{get()}
- }
+ var msg by remember{ mutableStateOf(if(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)){ if(get()==null){""}else{get().toString()} }else{""}) }
Text(text = text, style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onPrimaryContainer)
TextField(
- value = msg.toString(),
+ value = msg,
onValueChange = {msg=it},
label = {Text(textField)},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.padding(vertical = 6.dp),
- enabled = isDeviceOwner(myDpm)
+ enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)
)
Row {
Button(
onClick = {
focusMgr.clearFocus()
setMsg(msg)
- msg = if(get()==null){""}else{get()}
+ msg = if(get()==null){""}else{get().toString()}
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
},
- enabled = isDeviceOwner(myDpm)
+ enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)
) {
Text("应用")
}
@@ -227,10 +230,10 @@ fun UserSessionMessage(
onClick = {
focusMgr.clearFocus()
setMsg(null)
- msg = if(get()==null){""}else{get()}
+ msg = if(get()==null){""}else{get().toString()}
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
},
- enabled = isDeviceOwner(myDpm)
+ enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)
) {
Text("使用默认")
}
diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt
index 73f9907..5678867 100644
--- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt
+++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt
@@ -2,8 +2,10 @@ package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
+import android.content.Context
import android.os.Build.VERSION
import android.os.UserManager
+import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -35,7 +37,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@Composable
-fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){
+fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName,myContext: Context){
val verticalScrolling = rememberScrollState()
var currentSection by remember{ mutableIntStateOf(0) }
Column(
@@ -46,110 +48,113 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){
.navigationBarsPadding()
) {
Text("打开开关后会禁用对应的功能")
+ if(isProfileOwner(myDpm)){
+ Text("Profile owner无法更改部分功能")
+ }
SectionTab("网络和互联网",{currentSection==1}) { currentSection = if(currentSection==1){ 0 }else{ 1 } }
if(currentSection==1){
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",R.drawable.signal_cellular_alt_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0,myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",R.drawable.signal_cellular_alt_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0, myContext, myComponent, myDpm)}
if(VERSION.SDK_INT>=34){
- UserRestrictionItem(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.android_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
}
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",R.drawable.wifi_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm)
if(VERSION.SDK_INT>=33){
- UserRestrictionItem(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CHANGE_WIFI_STATE,R.string.change_wifi_state,"",R.drawable.wifi_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_WIFI_DIRECT,R.string.wifi_direct,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_WIFI_TETHERING,R.string.wifi_tethering,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,R.string.share_admin_wifi,"",R.drawable.share_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CHANGE_WIFI_STATE,R.string.change_wifi_state,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_WIFI_DIRECT,R.string.wifi_direct,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_WIFI_TETHERING,R.string.wifi_tethering,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,R.string.share_admin_wifi,"",R.drawable.share_fill0, myContext, myComponent, myDpm)
}
- UserRestrictionItem(UserManager.DISALLOW_NETWORK_RESET,R.string.network_reset,"",R.drawable.reset_wrench_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_TETHERING,R.string.config_tethering,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_VPN,R.string.config_vpn,"",R.drawable.vpn_key_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,R.string.config_private_dns,"",R.drawable.dns_fill0,myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_NETWORK_RESET,R.string.network_reset,"",R.drawable.reset_wrench_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_TETHERING,R.string.config_tethering,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_VPN,R.string.config_vpn,"",R.drawable.vpn_key_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,R.string.config_private_dns,"",R.drawable.dns_fill0, myContext, myComponent, myDpm)}
- if(VERSION.SDK_INT>=28){ UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",R.drawable.airplanemode_active_fill0,myComponent, myDpm) }
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,R.string.config_cell_broadcasts,"",R.drawable.cell_tower_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",R.drawable.sms_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0,myComponent, myDpm)
+ if(VERSION.SDK_INT>=28){ UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",R.drawable.airplanemode_active_fill0, myContext, myComponent, myDpm) }
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,R.string.config_cell_broadcasts,"",R.drawable.cell_tower_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",R.drawable.sms_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0, myContext, myComponent, myDpm)
}
SectionTab("其他连接",{currentSection==6}) { currentSection = if(currentSection==6){ 0 }else{ 6 } }
if(currentSection==6){
if(VERSION.SDK_INT>=26){
- UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",R.drawable.bluetooth_searching_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",R.drawable.bluetooth_searching_fill0, myContext, myComponent, myDpm)
}
- UserRestrictionItem(UserManager.DISALLOW_SHARE_LOCATION,R.string.share_location,"",R.drawable.location_on_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0,myComponent, myDpm)}
- UserRestrictionItem(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, stringResource(R.string.mount_phisical_media_desc),R.drawable.sd_card_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0,myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_SHARE_LOCATION,R.string.share_location,"",R.drawable.location_on_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0, myContext, myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, stringResource(R.string.mount_phisical_media_desc),R.drawable.sd_card_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0, myContext, myComponent, myDpm)}
}
SectionTab("应用",{currentSection==2}) { currentSection = if(currentSection==2){ 0 }else{ 2 } }
if(currentSection==2){
- UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0,myComponent, myDpm)}
- UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),R.drawable.apps_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0,myComponent, myDpm) }
+ UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0, myContext, myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),R.drawable.apps_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0, myContext, myComponent, myDpm) }
}
SectionTab("显示与音量",{currentSection==3}) { currentSection = if(currentSection==3){ 0 }else{ 3 } }
if(currentSection==3){
if(VERSION.SDK_INT>=28){
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",R.drawable.brightness_5_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,R.string.config_scr_timeout,"",R.drawable.screen_lock_portrait_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_AMBIENT_DISPLAY,R.string.ambient_display,"",R.drawable.brightness_5_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",R.drawable.brightness_5_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,R.string.config_scr_timeout,"",R.drawable.screen_lock_portrait_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_AMBIENT_DISPLAY,R.string.ambient_display,"",R.drawable.brightness_5_fill0, myContext, myComponent, myDpm)
}
- UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",R.drawable.volume_up_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_UNMUTE_MICROPHONE,R.string.unmute_microphone,"",R.drawable.mic_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",R.drawable.volume_up_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_UNMUTE_MICROPHONE,R.string.unmute_microphone,"",R.drawable.mic_fill0, myContext, myComponent, myDpm)
if(VERSION.SDK_INT>=31){
- UserRestrictionItem(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",R.drawable.cameraswitch_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_MICROPHONE_TOGGLE,R.string.microphone_toggle,"",R.drawable.mic_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",R.drawable.cameraswitch_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_MICROPHONE_TOGGLE,R.string.microphone_toggle,"",R.drawable.mic_fill0, myContext, myComponent, myDpm)
}
}
SectionTab("用户与工作资料",{currentSection==4}) { currentSection = if(currentSection==4){ 0 }else{ 4 } }
if(currentSection==4){
- UserRestrictionItem(UserManager.DISALLOW_ADD_USER,R.string.add_user,"",R.drawable.account_circle_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0,myComponent, myDpm)
- if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0,myComponent, myDpm)}
- if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0,myComponent, myDpm)}
- UserRestrictionItem(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, stringResource(R.string.cross_profile_copy_desc),R.drawable.content_paste_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_ADD_USER,R.string.add_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)}
+ if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, stringResource(R.string.cross_profile_copy_desc),R.drawable.content_paste_fill0, myContext, myComponent, myDpm)
if(VERSION.SDK_INT>=26){
- UserRestrictionItem(UserManager.DISALLOW_ADD_MANAGED_PROFILE,R.string.add_managed_profile,"",R.drawable.work_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,R.string.remove_managed_profile,"",R.drawable.work_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_ADD_MANAGED_PROFILE,R.string.add_managed_profile,"",R.drawable.work_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,R.string.remove_managed_profile,"",R.drawable.work_fill0, myContext, myComponent, myDpm)
}
if(VERSION.SDK_INT>=28){
- UserRestrictionItem(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unifiied_pwd,"",R.drawable.work_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unifiied_pwd,"",R.drawable.work_fill0, myContext, myComponent, myDpm)
}
}
SectionTab("杂项",{currentSection==5}) { currentSection = if(currentSection==5){ 0 }else{ 5 } }
if(currentSection==5){
- if(VERSION.SDK_INT>=26){ UserRestrictionItem(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0,myComponent, myDpm) }
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0,myComponent, myDpm)
+ if(VERSION.SDK_INT>=26){ UserRestrictionItem(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0, myContext, myComponent, myDpm) }
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
if(VERSION.SDK_INT>=29){
- UserRestrictionItem(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
}
- UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),R.drawable.web_asset,myComponent, myDpm)
- if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0,myComponent, myDpm)}
- if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0,myComponent, myDpm) }
- UserRestrictionItem(UserManager.DISALLOW_FUN,R.string.`fun`,"可能会影响谷歌商店的游戏",R.drawable.stadia_controller_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),R.drawable.web_asset, myContext, myComponent, myDpm)
+ if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0, myContext, myComponent, myDpm)}
+ if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0, myContext, myComponent, myDpm) }
+ UserRestrictionItem(UserManager.DISALLOW_FUN,R.string.`fun`,"可能会影响谷歌商店的游戏",R.drawable.stadia_controller_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0, myContext, myComponent, myDpm)
if(VERSION.SDK_INT>=28){
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_CONFIG_DATE_TIME,R.string.config_date_time,"",R.drawable.schedule_fill0,myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DATE_TIME,R.string.config_date_time,"",R.drawable.schedule_fill0, myContext, myComponent, myDpm)
}
- if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,R.string.sys_err_dialog,"",R.drawable.android_fill0,myComponent, myDpm)}
- UserRestrictionItem(UserManager.DISALLOW_FACTORY_RESET,R.string.factory_reset,"",R.drawable.android_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_SAFE_BOOT,R.string.safe_boot,"",R.drawable.android_fill0,myComponent, myDpm)
- UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",R.drawable.adb_fill0,myComponent, myDpm)
+ if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,R.string.sys_err_dialog,"",R.drawable.android_fill0, myContext, myComponent, myDpm)}
+ UserRestrictionItem(UserManager.DISALLOW_FACTORY_RESET,R.string.factory_reset,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_SAFE_BOOT,R.string.safe_boot,"",R.drawable.android_fill0, myContext, myComponent, myDpm)
+ UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",R.drawable.adb_fill0, myContext, myComponent, myDpm)
}
if(VERSION.SDK_INT<24){
@@ -195,8 +200,14 @@ fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){
}
@Composable
-private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDescription:String, leadIcon:Int,myComponent: ComponentName, myDpm: DevicePolicyManager){
- val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
+private fun UserRestrictionItem(
+ restriction:String, itemName:Int,
+ restrictionDescription:String,
+ leadIcon:Int,
+ myContext: Context,
+ myComponent: ComponentName,
+ myDpm: DevicePolicyManager
+){
var strictState by remember{ mutableStateOf(false) }
Row(
modifier = Modifier
@@ -228,7 +239,7 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes
if(restrictionDescription!=""){Text(text = restrictionDescription, color = MaterialTheme.colorScheme.onSecondaryContainer)}
}
}
- if(isdo&&VERSION.SDK_INT>=24){
+ if(VERSION.SDK_INT>=24&&(isDeviceOwner(myDpm)|| isProfileOwner(myDpm))){
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
}
if(VERSION.SDK_INT>=24){
@@ -236,14 +247,20 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes
checked = strictState,
onCheckedChange = {
strictState=it
- if(strictState){
- myDpm.addUserRestriction(myComponent,restriction)
- }else{
- myDpm.clearUserRestriction(myComponent,restriction)
+ try{
+ if(strictState){
+ myDpm.addUserRestriction(myComponent,restriction)
+ }else{
+ myDpm.clearUserRestriction(myComponent,restriction)
+ }
+ }catch(e:SecurityException){
+ if(isProfileOwner(myDpm)){
+ Toast.makeText(myContext, "Profile owner 无法更改", Toast.LENGTH_SHORT).show()
+ }
}
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
},
- enabled = isdo
+ enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
)
}
}
diff --git a/gradle.properties b/gradle.properties
index 3c5031e..9403523 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,23 +1,17 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
+## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
+#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# Default value: -Xmx1024m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app's APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
+#Sun Jan 21 20:24:56 CST 2024
+android.nonTransitiveRClass=true
android.useAndroidX=true
-# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
-# Enables namespacing of each library's R class so that its R class includes only the
-# resources declared in the library itself and none from the library's dependencies,
-# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M" -Dfile.encoding\=UTF-8