ShortSupportMessage can be modified

This commit is contained in:
BinTianqi
2024-01-19 19:50:45 +08:00
parent c8af8f054f
commit 62c3144a76
9 changed files with 171 additions and 13 deletions

View File

@@ -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 {

View File

@@ -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 = {

View File

@@ -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")
}

View File

@@ -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)})

View File

@@ -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()) })

View File

@@ -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 = "默认")
}
}
}
}
}

View File

@@ -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")
}
}
}
}

View File

@@ -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)}
}

View File

@@ -113,4 +113,5 @@
<string name="pwd_history">密码历史记录长度</string>
<string name="pwd_history_desc">用户输入的密码不能与历史记录中的任何密码相同0为无限制</string>
<string name="pwd_history_textfield">历史记录长度</string>
<string name="usb_signal">USB信号</string>
</resources>