mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
fix user operation problems
This commit is contained in:
@@ -31,6 +31,10 @@
|
|||||||
- 显示与音量:禁止调整亮度、音量
|
- 显示与音量:禁止调整亮度、音量
|
||||||
- 用户和工作资料:禁止添加/切换/移除用户,禁止添加/移除工作资料
|
- 用户和工作资料:禁止添加/切换/移除用户,禁止添加/移除工作资料
|
||||||
- 杂项:禁止自动填充服务、禁止调试
|
- 杂项:禁止自动填充服务、禁止调试
|
||||||
|
- 用户管理
|
||||||
|
- 添加用户并切换至新用户
|
||||||
|
- 修改当前用户的名称
|
||||||
|
- 设置切换用户时的提示
|
||||||
- 密码
|
- 密码
|
||||||
- 修改密码
|
- 修改密码
|
||||||
- 最大密码错误次数
|
- 最大密码错误次数
|
||||||
|
|||||||
@@ -52,16 +52,16 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.10.1")
|
implementation("androidx.core:core-ktx:1.12.0")
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
||||||
implementation("androidx.activity:activity-compose:1.7.0")
|
implementation("androidx.activity:activity-compose:1.8.2")
|
||||||
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
|
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
|
||||||
implementation("androidx.compose.ui:ui")
|
implementation("androidx.compose.ui:ui")
|
||||||
implementation("androidx.compose.ui:ui-graphics")
|
implementation("androidx.compose.ui:ui-graphics")
|
||||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
implementation("androidx.compose.material3:material3:1.1.1")
|
implementation("androidx.compose.material3:material3:1.1.2")
|
||||||
implementation("androidx.navigation:navigation-compose:2.7.6")
|
implementation("androidx.navigation:navigation-compose:2.7.6")
|
||||||
implementation("com.google.accompanist:accompanist-systemuicontroller:0.33.2-alpha")
|
implementation("com.google.accompanist:accompanist-systemuicontroller:0.34.0")
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ fun MyScaffold(){
|
|||||||
composable(route = "Permissions", content = { DpmPermissions(navCtrl)})
|
composable(route = "Permissions", content = { DpmPermissions(navCtrl)})
|
||||||
composable(route = "ApplicationManage", content = { ApplicationManage()})
|
composable(route = "ApplicationManage", content = { ApplicationManage()})
|
||||||
composable(route = "UserRestriction", content = { UserRestriction()})
|
composable(route = "UserRestriction", content = { UserRestriction()})
|
||||||
composable(route = "UserManage", content = { UserManage()})
|
composable(route = "UserManage", content = { UserManage(navCtrl)})
|
||||||
composable(route = "Password", content = { Password()})
|
composable(route = "Password", content = { Password()})
|
||||||
composable(route = "AppSetting", content = { AppSetting(navCtrl)})
|
composable(route = "AppSetting", content = { AppSetting(navCtrl)})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ class MyDeviceAdminReceiver : DeviceAdminReceiver() {
|
|||||||
super.onEnabled(context, intent)
|
super.onEnabled(context, intent)
|
||||||
Toast.makeText(context, "已启用", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "已启用", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
/*override fun onReceive(context: Context, intent: Intent) {
|
||||||
super.onReceive(context, intent)
|
super.onReceive(context, intent)
|
||||||
Toast.makeText(context, "已接收", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "已接收", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}*/
|
||||||
override fun onDisableRequested(context: Context, intent: Intent): CharSequence {
|
override fun onDisableRequested(context: Context, intent: Intent): CharSequence {
|
||||||
Toast.makeText(context, "撤销授权", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "撤销授权", Toast.LENGTH_SHORT).show()
|
||||||
return "这是取消时的提示"
|
return "这是取消时的提示"
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.binbin.androidowner;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.UserManager;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Test {
|
|
||||||
public static List<UserHandle> returnUsers(Context myContext){
|
|
||||||
UserManager userManager = (UserManager) myContext.getSystemService(Context.USER_SERVICE);
|
|
||||||
return userManager.getUserProfiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@ import android.os.UserHandle
|
|||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
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
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -17,10 +18,12 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
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.Button
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
@@ -30,32 +33,33 @@ import androidx.compose.runtime.mutableIntStateOf
|
|||||||
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.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.shadow
|
||||||
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.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.os.UserManagerCompat
|
import androidx.core.os.UserManagerCompat
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserManage(){
|
fun UserManage(navCtrl:NavHostController){
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
//val myUM = myContext.getSystemService(Context.USER_SERVICE)
|
|
||||||
val myContext = LocalContext.current
|
val myContext = LocalContext.current
|
||||||
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
|
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
val currentUser = android.os.Process.myUserHandle()
|
val userManager = myContext.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
val userList = Test.returnUsers(myContext)
|
|
||||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
val isWear = sharedPref.getBoolean("isWear",false)
|
val isWear = sharedPref.getBoolean("isWear",false)
|
||||||
Column(modifier = sections()) {
|
Column(modifier = sections()) {
|
||||||
Text(text = "用户信息", style = MaterialTheme.typography.titleLarge,color = MaterialTheme.colorScheme.onPrimaryContainer)
|
Text(text = "用户信息", style = MaterialTheme.typography.titleLarge,color = MaterialTheme.colorScheme.onPrimaryContainer)
|
||||||
Text("用户个数:${userList.size}",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
|
||||||
Spacer(Modifier.padding(vertical = if(isWear){2.dp}else{5.dp}))
|
|
||||||
Text("用户已解锁:${UserManagerCompat.isUserUnlocked(myContext)}",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
Text("用户已解锁:${UserManagerCompat.isUserUnlocked(myContext)}",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
||||||
if(VERSION.SDK_INT>=24){
|
if(VERSION.SDK_INT>=24){
|
||||||
Text("支持多用户:${UserManager.supportsMultipleUsers()}",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
Text("支持多用户:${UserManager.supportsMultipleUsers()}",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
||||||
@@ -75,49 +79,162 @@ fun UserManage(){
|
|||||||
Text(text = "次级用户: $affiliatedUser",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
Text(text = "次级用户: $affiliatedUser",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = if(isWear){2.dp}else{5.dp}))
|
Spacer(Modifier.padding(vertical = if(isWear){2.dp}else{5.dp}))
|
||||||
Text("切换用户后或设备重启后会删除临时用户",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
Text("当前UID:${android.os.Process.myUid()}")
|
||||||
|
Text("当前UserID:${getCurrentUserId()}")
|
||||||
|
Text("当前用户序列号:${userManager.getSerialNumberForUser(android.os.Process.myUserHandle())}")
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(modifier = sections()) {
|
Column(modifier = sections()) {
|
||||||
Text(text = "用户操作", style = MaterialTheme.typography.titleLarge,color = MaterialTheme.colorScheme.onPrimaryContainer)
|
Text(text = "用户操作", style = MaterialTheme.typography.titleLarge,color = MaterialTheme.colorScheme.onPrimaryContainer)
|
||||||
|
var idInput by remember{ mutableStateOf("") }
|
||||||
|
var userHandleById:UserHandle by remember{ mutableStateOf(android.os.Process.myUserHandle()) }
|
||||||
|
var useUid by remember{ mutableStateOf(false) }
|
||||||
|
TextField(
|
||||||
|
value = idInput,
|
||||||
|
onValueChange = {
|
||||||
|
idInput=it
|
||||||
|
if(useUid){
|
||||||
|
if(idInput!=""&&VERSION.SDK_INT>=24){
|
||||||
|
userHandleById = UserHandle.getUserHandleForUid(idInput.toInt())
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
val userHandleBySerial = userManager.getUserForSerialNumber(idInput.toLong())
|
||||||
|
userHandleById = userHandleBySerial ?: android.os.Process.myUserHandle()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label = {Text(if(useUid){"UID"}else{"序列号"})},
|
||||||
|
enabled = isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp),
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||||
|
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()})
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(15.dp))
|
||||||
|
.clickable(enabled = VERSION.SDK_INT>=24&&isDeviceOwner(myDpm)){useUid=!useUid}
|
||||||
|
.padding(end = 12.dp)
|
||||||
|
){
|
||||||
|
Checkbox(
|
||||||
|
checked = useUid,
|
||||||
|
onCheckedChange = {useUid=it},
|
||||||
|
enabled = VERSION.SDK_INT>=24&& isDeviceOwner(myDpm)
|
||||||
|
)
|
||||||
|
Text(text = "使用UID(不靠谱)",modifier = Modifier.padding(bottom = 2.dp))
|
||||||
|
}
|
||||||
if(VERSION.SDK_INT>28){
|
if(VERSION.SDK_INT>28){
|
||||||
var resultForLogout by remember{ mutableIntStateOf(-1) }
|
if(isProfileOwner(myDpm)&&myDpm.isAffiliatedUser){
|
||||||
var resultForStop by remember{ mutableIntStateOf(-1) }
|
Button(
|
||||||
Text("登出用户需要成为次级用户的Profile Owner",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
onClick = {
|
||||||
Button(onClick = {resultForLogout = myDpm.logoutUser(myComponent)}, enabled = isProfileOwner(myDpm)) {
|
val result = myDpm.logoutUser(myComponent)
|
||||||
Text("登出用户")
|
Toast.makeText(myContext, userOperationResultCode(result), Toast.LENGTH_SHORT).show()
|
||||||
}
|
},
|
||||||
if(resultForLogout!=-1){
|
enabled = isProfileOwner(myDpm),
|
||||||
Text(userOperationResultCode(resultForLogout))
|
modifier = Modifier.fillMaxWidth()
|
||||||
}
|
) {
|
||||||
Button(onClick = {myDpm.switchUser(myComponent,currentUser)}, enabled = isDeviceOwner(myDpm)) {
|
Text("登出当前用户")
|
||||||
Text("切换用户")
|
|
||||||
}
|
|
||||||
Button(onClick = {resultForStop = myDpm.stopUser(myComponent,currentUser)}, enabled = isDeviceOwner(myDpm)) {
|
|
||||||
Text("停止用户")
|
|
||||||
}
|
|
||||||
if(resultForStop!=-1){
|
|
||||||
Text(userOperationResultCode(resultForStop))
|
|
||||||
}
|
|
||||||
Button(onClick = {myDpm.setProfileEnabled(myComponent)}, enabled = isProfileOwner(myDpm)||isDeviceOwner(myDpm)) {
|
|
||||||
Text(text = "启用资料")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
val success = myDpm.removeUser(myComponent,currentUser)
|
focusMgr.clearFocus()
|
||||||
if(success){
|
val result = myDpm.startUserInBackground(myComponent,userHandleById)
|
||||||
|
Toast.makeText(myContext, userOperationResultCode(result), Toast.LENGTH_SHORT).show()
|
||||||
|
},
|
||||||
|
enabled = isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
){
|
||||||
|
Text("在后台启动用户")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
focusMgr.clearFocus()
|
||||||
|
if(myDpm.switchUser(myComponent,userHandleById)){
|
||||||
|
focusMgr.clearFocus()
|
||||||
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
}else{
|
}else{
|
||||||
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = isDeviceOwner(myDpm)
|
enabled = isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text("切换至用户")
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = if(isWear){
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.horizontalScroll(rememberScrollState())}else{Modifier.fillMaxWidth()},
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
){
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
focusMgr.clearFocus()
|
||||||
|
try{
|
||||||
|
if(VERSION.SDK_INT>=28){
|
||||||
|
val result = myDpm.stopUser(myComponent,userHandleById)
|
||||||
|
Toast.makeText(myContext, userOperationResultCode(result), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}catch(e:IllegalArgumentException){
|
||||||
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enabled = isDeviceOwner(myDpm)&&VERSION.SDK_INT>=28,
|
||||||
|
modifier = Modifier.fillMaxWidth(0.48F)
|
||||||
|
) {
|
||||||
|
Text("停止用户")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
focusMgr.clearFocus()
|
||||||
|
if(myDpm.removeUser(myComponent,userHandleById)){
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
idInput=""
|
||||||
|
}else{
|
||||||
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enabled = isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth(0.92F)
|
||||||
) {
|
) {
|
||||||
Text("移除用户")
|
Text("移除用户")
|
||||||
}
|
}
|
||||||
Button(onClick = { createWorkProfile(myContext)}) {
|
}
|
||||||
Text("创建工作资料")
|
if(VERSION.SDK_INT<28){
|
||||||
|
Text("停止用户需API28")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(modifier = sections()) {
|
||||||
|
Text(text = "工作资料", style = MaterialTheme.typography.titleLarge)
|
||||||
|
Row(
|
||||||
|
modifier = if(isWear){
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.horizontalScroll(rememberScrollState())}else{Modifier.fillMaxWidth()},
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
){
|
||||||
|
Button(
|
||||||
|
onClick = { createWorkProfile(myContext)},
|
||||||
|
modifier = Modifier.fillMaxWidth(0.48F)
|
||||||
|
) {
|
||||||
|
Text("创建")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
try{
|
||||||
|
myDpm.setProfileEnabled(myComponent)
|
||||||
|
}catch(e:SecurityException){
|
||||||
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enabled = isProfileOwner(myDpm)||isDeviceOwner(myDpm),
|
||||||
|
modifier = Modifier.fillMaxWidth(0.95F)
|
||||||
|
) {
|
||||||
|
Text(text = "启用")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Text("可能无法创建工作资料",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
Text("可能无法创建工作资料",style = if(isWear){MaterialTheme.typography.bodyMedium}else{MaterialTheme.typography.bodyLarge})
|
||||||
}
|
}
|
||||||
@@ -143,12 +260,23 @@ fun UserManage(){
|
|||||||
RadioButtonItem("启用所有系统应用",{selectedFlag==DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED},{selectedFlag=DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED})
|
RadioButtonItem("启用所有系统应用",{selectedFlag==DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED},{selectedFlag=DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED})
|
||||||
}
|
}
|
||||||
var newUserHandle: UserHandle? by remember{ mutableStateOf(null) }
|
var newUserHandle: UserHandle? by remember{ mutableStateOf(null) }
|
||||||
Row(modifier = if(isWear){Modifier.horizontalScroll(rememberScrollState())}else{Modifier}) {
|
Row(
|
||||||
|
modifier = if(isWear){Modifier.fillMaxWidth().horizontalScroll(rememberScrollState())}else{Modifier.fillMaxWidth()},
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {newUserHandle=myDpm.createAndManageUser(myComponent,userName,myComponent,null,selectedFlag);focusMgr.clearFocus()},
|
onClick = {
|
||||||
|
newUserHandle=myDpm.createAndManageUser(myComponent,userName,myComponent,null,selectedFlag)
|
||||||
|
focusMgr.clearFocus()
|
||||||
|
if(newUserHandle!=null){
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
}else{
|
||||||
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
},
|
||||||
enabled = isDeviceOwner(myDpm),
|
enabled = isDeviceOwner(myDpm),
|
||||||
modifier = if(!isWear){
|
modifier = if(!isWear){
|
||||||
if(newUserHandle==null){Modifier.fillMaxWidth(1F)}else{Modifier.fillMaxWidth(0.48F)}
|
if(newUserHandle==null){Modifier.fillMaxWidth(1F)}else{Modifier.fillMaxWidth(0.4F)}
|
||||||
}else{Modifier}
|
}else{Modifier}
|
||||||
) {
|
) {
|
||||||
Text("创建")
|
Text("创建")
|
||||||
@@ -159,17 +287,20 @@ fun UserManage(){
|
|||||||
onClick = {
|
onClick = {
|
||||||
if(myDpm.switchUser(myComponent,newUserHandle)){
|
if(myDpm.switchUser(myComponent,newUserHandle)){
|
||||||
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
navCtrl.navigate("HomePage")
|
||||||
} else{
|
} else{
|
||||||
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.92F)}
|
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.97F)}
|
||||||
) {
|
) {
|
||||||
Text("切换至新用户")
|
Text("切换至新用户")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(newUserHandle!=null){
|
||||||
|
Text("新用户的序列号:${userManager.getSerialNumberForUser(newUserHandle)}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Text("创建用户需安卓7")
|
Text("创建用户需安卓7")
|
||||||
@@ -243,11 +374,11 @@ fun UserSessionMessage(
|
|||||||
|
|
||||||
fun userOperationResultCode(result:Int): String {
|
fun userOperationResultCode(result:Int): String {
|
||||||
return when(result){
|
return when(result){
|
||||||
UserManager.USER_OPERATION_SUCCESS->"USER_OPERATION_SUCCESS"
|
UserManager.USER_OPERATION_SUCCESS->"成功"
|
||||||
UserManager.USER_OPERATION_ERROR_UNKNOWN->"USER_OPERATION_ERROR_UNKNOWN"
|
UserManager.USER_OPERATION_ERROR_UNKNOWN->"未知结果(失败)"
|
||||||
UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE->"USER_OPERATION_ERROR_MANAGED_PROFILE"
|
UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE->"失败:受管理的资料"
|
||||||
UserManager.USER_OPERATION_ERROR_CURRENT_USER->"USER_OPERATION_ERROR_CURRENT_USER"
|
UserManager.USER_OPERATION_ERROR_CURRENT_USER->"失败:当前用户"
|
||||||
else->"Unknown"
|
else->"未知"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,3 +392,13 @@ private fun createWorkProfile(myContext: Context) {
|
|||||||
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"hello")
|
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"hello")
|
||||||
myContext.startActivity(intent)
|
myContext.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCurrentUserId(): Int {
|
||||||
|
try {
|
||||||
|
val uh = UserHandle::class.java.getDeclaredMethod("myUserId")
|
||||||
|
uh.isAccessible = true
|
||||||
|
val userId = uh.invoke(null)
|
||||||
|
if (userId is Int) { return userId }
|
||||||
|
} catch (ignored: Exception) { }
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ fun UserRestriction(){
|
|||||||
color = MaterialTheme.colorScheme.error)
|
color = MaterialTheme.colorScheme.error)
|
||||||
}
|
}
|
||||||
if(isProfileOwner(myDpm)){
|
if(isProfileOwner(myDpm)){
|
||||||
Text(text = "Profile owner无法更改部分功能",
|
Text(text = "Profile owner无法使用部分功能",
|
||||||
style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium})
|
style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium})
|
||||||
}
|
}
|
||||||
if(isWear){
|
if(isWear){
|
||||||
@@ -221,7 +221,7 @@ private fun UserRestrictionItem(
|
|||||||
}
|
}
|
||||||
}catch(e:SecurityException){
|
}catch(e:SecurityException){
|
||||||
if(isProfileOwner(myDpm)){
|
if(isProfileOwner(myDpm)){
|
||||||
Toast.makeText(myContext, "Profile owner 无法更改", Toast.LENGTH_SHORT).show()
|
Toast.makeText(myContext, "需要DeviceOwner", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
||||||
|
|||||||
Reference in New Issue
Block a user