From 62c3144a768a3c59bc6b5c33f62b471392692329 Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Fri, 19 Jan 2024 19:50:45 +0800 Subject: [PATCH] ShortSupportMessage can be modified --- app/build.gradle.kts | 4 +- .../binbin/androidowner/ApplicationManage.kt | 3 +- .../com/binbin/androidowner/DeviceControl.kt | 10 ++ .../com/binbin/androidowner/MainActivity.kt | 2 + .../java/com/binbin/androidowner/Password.kt | 25 ++++- .../com/binbin/androidowner/Permissions.kt | 102 ++++++++++++++++-- .../main/java/com/binbin/androidowner/User.kt | 32 ++++++ .../com/binbin/androidowner/UserRestrict.kt | 5 +- app/src/main/res/values/strings.xml | 1 + 9 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/binbin/androidowner/User.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 51c06d9..2a62567 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "com.binbin.androidowner" minSdk = 23 targetSdk = 34 - versionCode = 3 - versionName = "1.2" + versionCode = 4 + versionName = "1.3" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt index 87831f4..58c26a6 100644 --- a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt +++ b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt @@ -49,7 +49,8 @@ fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName,myCon onValueChange = { pkgName = it }, - label = { Text("包名") } + label = { Text("包名") }, + modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) ) if(VERSION.SDK_INT>=24){ val isSuspended = { diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index bacd21c..9c167ed 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -40,6 +41,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){ modifier = Modifier .verticalScroll(rememberScrollState()) .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) }) @@ -54,6 +56,13 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){ if(VERSION.SDK_INT>=26){ DeviceCtrlItem(R.string.backup_service,R.string.place_holder,R.drawable.backup_fill0,myDpm,{myDpm.isBackupServiceEnabled(myComponent)},{b -> myDpm.setBackupServiceEnabled(myComponent,b) }) } + if(VERSION.SDK_INT>=31){ + 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信号") + } + } if(VERSION.SDK_INT>=24){ Button(onClick = {myDpm.reboot(myComponent)}) { Text("重启") @@ -74,6 +83,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){ if(VERSION.SDK_INT<30){ Text("自动设置时间和自动设置时区需要API30") } + if(VERSION.SDK_INT<31){Text("关闭USB信号需API31")} if(VERSION.SDK_INT<34){ Text("隐藏状态栏需要API34") } diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index 1477cc9..571da91 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons @@ -120,6 +121,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon startDestination = "HomePage", modifier = Modifier .padding(top = it.calculateTopPadding()) + .imePadding() ){ composable(route = "HomePage", content = { HomePage(navCtrl,mainDpm,mainComponent)}) composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)}) diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index c169bae..d43c0b7 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -54,6 +55,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte modifier = Modifier .fillMaxWidth() .verticalScroll(rememberScrollState()) + .navigationBarsPadding() ) { val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } Text( @@ -66,6 +68,27 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte .background(color = MaterialTheme.colorScheme.errorContainer) .padding(8.dp) ) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 4.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { + if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){ + if(VERSION.SDK_INT>=29){ + val pwdComplex = myDpm.passwordComplexity + Text(text = "密码复杂度:$pwdComplex") + } + val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts + Text(text = "密码已错误次数:$pwdFailedAttempts") + if(VERSION.SDK_INT>=28&&(myDpm.isManagedProfile(myComponent)||myDpm.isProfileOwnerApp("com.binbin.androidowner"))){ + val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent) + Text("个人与工作应用密码一致:$unifiedPwd") + } + } + } if(VERSION.SDK_INT>=26){ Column( horizontalAlignment = Alignment.Start, @@ -168,7 +191,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte PasswordItem(R.string.max_pwd_fail,R.string.max_pwd_fail_desc,R.string.max_pwd_fail_textfield, focusMgr,false, {myDpm.getMaximumFailedPasswordsForWipe(null).toString()},{ic -> myDpm.setMaximumFailedPasswordsForWipe(myComponent, ic.toInt()) }) PasswordItem(R.string.pwd_timeout,R.string.pwd_timeout_desc,R.string.pwd_timeout_textfield, focusMgr,true, - {myDpm.getPasswordExpirationTimeout(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) }) + {myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) }) PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield, focusMgr,true, {myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) }) diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index 3800115..d9a61be 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.Intent import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.os.Build.VERSION +import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -29,20 +30,21 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController - @Composable fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myContext:Context,navCtrl:NavHostController){ //da:DeviceAdmin do:DeviceOwner val isda = myDpm.isAdminActive(myComponent) val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner") + val focusManager = LocalFocusManager.current Column( modifier = Modifier - .padding(8.dp) + .padding(horizontal = 8.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally ) { @@ -111,7 +113,17 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon Column( horizontalAlignment = Alignment.Start ) { - if(isdo||isda){Text("注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态")} + if(isdo||isda){ + Text( + text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态", + color = MaterialTheme.colorScheme.onErrorContainer, + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.errorContainer) + .padding(6.dp) + ) + } Spacer(Modifier.padding(5.dp)) if(!isda){ Text("你可以在adb shell中使用以下命令激活Device Admin") @@ -131,11 +143,85 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon } } if(isdo&&VERSION.SDK_INT>=24){ - var lockScrInfo by remember { mutableStateOf("") } - TextField(value = lockScrInfo, onValueChange = { lockScrInfo= it}, label = { Text("锁屏信息") }) - Spacer(Modifier.padding(5.dp)) - Button(onClick = {myDpm.setDeviceOwnerLockScreenInfo(myComponent,lockScrInfo)}) { - Text("设置锁屏DeviceOwner信息") + Column( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 10.dp) + .clip(RoundedCornerShape(12.dp)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(10.dp) + ) { + var lockScrInfo by remember { mutableStateOf(myDpm.deviceOwnerLockScreenInfo) } + Text(text = "锁屏DeviceOwner信息", style = MaterialTheme.typography.titleLarge) + TextField( + value = if(lockScrInfo!=null){lockScrInfo.toString()}else{""}, + onValueChange = { lockScrInfo= it}, + label = { Text("锁屏信息") }, + modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp) + ) + Row { + Button(onClick = { + myDpm.setDeviceOwnerLockScreenInfo(myComponent,lockScrInfo) + lockScrInfo=myDpm.deviceOwnerLockScreenInfo + focusManager.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + }) { + Text("应用") + } + Spacer(Modifier.padding(horizontal = 4.dp)) + Button(onClick = { + myDpm.setDeviceOwnerLockScreenInfo(myComponent,null) + lockScrInfo=myDpm.deviceOwnerLockScreenInfo + focusManager.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + }) { + Text("默认") + } + } + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 10.dp) + .clip(RoundedCornerShape(12.dp)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(10.dp) + ) { + Text(text = "提示消息", style = MaterialTheme.typography.titleLarge) + Text(text = "如果你禁用了某个功能,用户尝试使用这个功能时会看见这个消息(可多行)",modifier = Modifier.padding(vertical = 6.dp)) + var supportMsg by remember{ mutableStateOf(myDpm.getShortSupportMessage(myComponent)) } + TextField( + value = if(supportMsg!=null){ supportMsg.toString() }else{""}, + label = {Text("提示消息")}, + onValueChange = { supportMsg=it }, + modifier = Modifier.fillMaxWidth() + ) + Row( + modifier = Modifier.padding(vertical = 6.dp) + ) { + Button( + onClick = { + myDpm.setShortSupportMessage(myComponent,supportMsg) + supportMsg=if(myDpm.getShortSupportMessage(myComponent)!=null){ myDpm.getShortSupportMessage(myComponent).toString() }else{""} + focusManager.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + } + ) { + Text(text = "应用") + } + Spacer(Modifier.padding(horizontal = 4.dp)) + Button( + onClick = { + myDpm.setShortSupportMessage(myComponent,null) + supportMsg = myDpm.getShortSupportMessage(myComponent) + focusManager.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + } + ) { + Text(text = "默认") + } + } + } } } diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt new file mode 100644 index 0000000..7116a50 --- /dev/null +++ b/app/src/main/java/com/binbin/androidowner/User.kt @@ -0,0 +1,32 @@ +package com.binbin.androidowner + +import android.app.admin.DevicePolicyManager +import android.content.ComponentName +import android.os.Build +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable + +@Composable +fun User(myDpm:DevicePolicyManager,myComponent:ComponentName){ + Column { + Column { + Text(text = "参数", style = MaterialTheme.typography.titleLarge) + if(Build.VERSION.SDK_INT>=34&&(myDpm.isProfileOwnerApp("com.binbin.androidowner")||myDpm.isManagedProfile(myComponent))){ + val financed = myDpm.isDeviceFinanced + Text("Financed Device : $financed") + } + if (Build.VERSION.SDK_INT >= 28) { + val logoutable = myDpm.isLogoutEnabled + Text(text = "用户可以退出 : $logoutable") + val ephemeralUser = myDpm.isEphemeralUser(myComponent) + Text(text = "临时用户: $ephemeralUser") + Text("切换用户后或设备重启后会删除临时用户") + val affiliatedUser = myDpm.isAffiliatedUser + Text(text = "Affiliated User:$affiliatedUser") + } + } + } +} diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index 0e39428..e6726b7 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -40,6 +41,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ modifier = Modifier .verticalScroll(verticalScrolling) .padding(bottom = 20.dp) + .navigationBarsPadding() ) { Text("打开开关后会禁用对应的功能") @@ -217,7 +219,8 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes ) { Text( text = stringResource(itemName), - style = MaterialTheme.typography.titleLarge + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onTertiaryContainer ) if(restrictionDescription!=""){Text(text = restrictionDescription, color = MaterialTheme.colorScheme.onSecondaryContainer)} } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c105eb8..3b8e9ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -113,4 +113,5 @@ 密码历史记录长度 用户输入的密码不能与历史记录中的任何密码相同,0为无限制 历史记录长度 + USB信号 \ No newline at end of file