From 1f52a8920cadbbbd589c27f69cd5ec621abbc1b6 Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Sat, 20 Jan 2024 18:41:32 +0800 Subject: [PATCH] wipe data with flags, set SystemUpdatePolicy --- app/src/main/AndroidManifest.xml | 1 + .../com/binbin/androidowner/DeviceControl.kt | 96 +++++++++--- .../com/binbin/androidowner/MainActivity.kt | 20 ++- .../java/com/binbin/androidowner/Password.kt | 19 ++- .../com/binbin/androidowner/Permissions.kt | 145 ++++++++--------- .../java/com/binbin/androidowner/Receiver.kt | 23 +-- .../binbin/androidowner/SystemUpdatePolicy.kt | 148 ++++++++++++++++++ .../com/binbin/androidowner/UserRestrict.kt | 18 +-- app/src/main/res/values/colors.xml | 10 -- app/src/main/res/values/strings.xml | 14 +- 10 files changed, 353 insertions(+), 141 deletions(-) create mode 100644 app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt delete mode 100644 app/src/main/res/values/colors.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 35d5d93..48efe20 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ =26){ 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(myDpm.canUsbDataSignalingBeDisabled()){ DeviceCtrlItem(R.string.usb_signal,R.string.place_holder,R.drawable.usb_fill0,myDpm,{myDpm.isUsbDataSignalingEnabled},{b -> myDpm.isUsbDataSignalingEnabled = b }) @@ -63,6 +65,23 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){ Text("你的设备不支持关闭USB信号") } } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 6.dp, vertical = 4.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + Button(onClick = {myDpm.setKeyguardDisabled(myComponent,true)}) { + Text("禁用锁屏(需无密码)") + } + Spacer(Modifier.padding(horizontal = 5.dp)) + Button(onClick = {myDpm.setKeyguardDisabled(myComponent,false)}) { + Text("启用锁屏") + } + } if(VERSION.SDK_INT>=24){ Button(onClick = {myDpm.reboot(myComponent)}) { Text("重启") @@ -90,29 +109,60 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){ Button(onClick = {myDpm.lockNow()}) { Text("锁屏") } - Text("以下功能需要长按按钮,作者并未测试") - Button( - onClick = {}, - modifier = Modifier - .combinedClickable(onClick = {}, onLongClick = {myDpm.wipeData(0)}), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.error - ) - ) { - Text("WipeData") + Button(onClick = {myDpm.uninstallAllUserCaCerts(myComponent)}) { + Text(text = "清除用户Ca证书") } - if (VERSION.SDK_INT >= 34) { + SysUpdatePolicy(myDpm,myComponent,myContext) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 6.dp) + .clip(RoundedCornerShape(16.dp)) + .background(color = MaterialTheme.colorScheme.errorContainer) + .padding(8.dp) + ) { + var flag by remember{ mutableIntStateOf(0) } + var confirmed by remember{ mutableStateOf(false) } + Text(text = "清除数据",style = MaterialTheme.typography.titleLarge,modifier = Modifier.padding(6.dp)) + RadioButtonItem("默认",{flag==0},{flag=0}) + RadioButtonItem("WIPE_EXTERNAL_STORAGE",{flag==0x0001},{flag=0x0001}) + RadioButtonItem("WIPE_RESET_PROTECTION_DATA",{flag==0x0002},{flag=0x0002}) + RadioButtonItem("WIPE_EUICC",{flag==0x0004},{flag=0x0004}) + RadioButtonItem("WIPE_SILENTLY",{flag==0x0008},{flag=0x0008}) + Text("清空数据的不能是系统用户") Button( - modifier = Modifier - .combinedClickable(onClick = {}, onLongClick = {myDpm.wipeDevice(0)}), - onClick = {}, + onClick = {confirmed=!confirmed}, colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.error + containerColor = if(confirmed){MaterialTheme.colorScheme.primary}else{MaterialTheme.colorScheme.error}, + contentColor = if(confirmed){MaterialTheme.colorScheme.onPrimary}else{MaterialTheme.colorScheme.onError} ) ) { - Text("WipeDevice(API34)") + Text(text = if(confirmed){"取消"}else{"确定"}) + } + Row { + Button( + onClick = {myDpm.wipeData(flag)}, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.error, + contentColor = MaterialTheme.colorScheme.onError + ), + enabled = confirmed + ) { + Text("WipeData") + } + Spacer(Modifier.padding(horizontal = 5.dp)) + if (VERSION.SDK_INT >= 34) { + Button( + onClick = {myDpm.wipeDevice(flag)}, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.error, + contentColor = MaterialTheme.colorScheme.onError + ), + enabled = confirmed + ) { + Text("WipeDevice(API34)") + } + } } } } diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index 571da91..2d41993 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -2,6 +2,7 @@ package com.binbin.androidowner import android.annotation.SuppressLint import android.app.admin.DevicePolicyManager +import android.app.admin.SystemUpdatePolicy import android.content.ComponentName import android.content.Context import android.os.Bundle @@ -21,6 +22,7 @@ import androidx.compose.material.icons.outlined.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar @@ -124,7 +126,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon .imePadding() ){ composable(route = "HomePage", content = { HomePage(navCtrl,mainDpm,mainComponent)}) - composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)}) + 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)}) @@ -212,3 +214,19 @@ fun HomePageItem(name:Int, imgVector:Int, description:Int, navTo:String, myNav:N } } } + +@Composable +fun RadioButtonItem( + text:String, + selected:()->Boolean, + operation:()->Unit +){ + Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(25)) + .clickable(onClick = operation) + ) { + RadioButton(selected = selected(), onClick = operation) + Text(text) + } +} diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index d43c0b7..510bee6 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -13,7 +13,6 @@ 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.imePadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState @@ -68,15 +67,15 @@ 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(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 4.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { if(VERSION.SDK_INT>=29){ val pwdComplex = myDpm.passwordComplexity Text(text = "密码复杂度:$pwdComplex") diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index d9a61be..0c4f178 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -30,7 +30,9 @@ 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.focus.FocusManager import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity import androidx.navigation.NavGraph.Companion.findStartDestination @@ -143,87 +145,74 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon } } if(isdo&&VERSION.SDK_INT>=24){ - 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 = "默认") - } - } + DeviceOwnerInfo(R.string.owner_lockscr_info,R.string.place_holder,R.string.owner_lockscr_info,focusManager,myContext, + {myDpm.deviceOwnerLockScreenInfo},{content -> myDpm.setDeviceOwnerLockScreenInfo(myComponent,content)}) + DeviceOwnerInfo(R.string.support_msg,R.string.support_msg_desc,R.string.message,focusManager,myContext, + {myDpm.getShortSupportMessage(myComponent)},{content -> myDpm.setShortSupportMessage(myComponent,content)}) + DeviceOwnerInfo(R.string.long_support_msg,R.string.long_support_msg_desc,R.string.message,focusManager,myContext, + {myDpm.getLongSupportMessage(myComponent)},{content -> myDpm.setLongSupportMessage(myComponent,content)}) + } + DeviceOwnerInfo(R.string.profile_name,R.string.unknown_feature,R.string.profile_name,focusManager,myContext, + {null},{content -> myDpm.setProfileName(myComponent,content)}) + Spacer(Modifier.padding(vertical = 20.dp)) + } +} +@Composable +fun DeviceOwnerInfo( + name:Int, + desc:Int, + textfield:Int, + fm:FocusManager, + myContext:Context, + input:()->CharSequence?, + output:(content:String?)->Unit +){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 10.dp) + .clip(RoundedCornerShape(12.dp)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(10.dp) + ) { + Text(text = stringResource(name), style = MaterialTheme.typography.titleLarge) + if(desc!=R.string.place_holder){Text(text = stringResource(desc),modifier = Modifier.padding(top = 6.dp))} + var inputContent by remember{ mutableStateOf(input()) } + TextField( + value = if(inputContent!=null){ inputContent.toString() }else{""}, + label = {Text(stringResource(textfield))}, + onValueChange = { inputContent=it }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp) + ) + Row( + modifier = Modifier.padding(vertical = 6.dp) + ) { + Button( + onClick = { + output(inputContent.toString()) + inputContent= input() + fm.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + } + ) { + Text(text = "应用") + } + Spacer(Modifier.padding(horizontal = 4.dp)) + Button( + onClick = { + output(null) + inputContent = input() + fm.clearFocus() + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + } + ) { + Text(text = "重置") } } + } } diff --git a/app/src/main/java/com/binbin/androidowner/Receiver.kt b/app/src/main/java/com/binbin/androidowner/Receiver.kt index a6149fd..caa2d72 100644 --- a/app/src/main/java/com/binbin/androidowner/Receiver.kt +++ b/app/src/main/java/com/binbin/androidowner/Receiver.kt @@ -3,25 +3,30 @@ package com.binbin.androidowner import android.app.admin.DeviceAdminReceiver import android.content.Context import android.content.Intent -import android.util.Log +import android.os.Build +import android.widget.Toast class MyDeviceAdminReceiver : DeviceAdminReceiver() { - val TAG = "MyDeviceAdminReceiver" override fun onEnabled(context: Context, intent: Intent) { super.onEnabled(context, intent) - Log.e(">>>>>>>>>", "onEnabled") + Toast.makeText(context, "已启用", Toast.LENGTH_SHORT).show() } override fun onReceive(context: Context, intent: Intent) { super.onReceive(context, intent) - Log.e(">>>>>>>>>", "onReceive") + Toast.makeText(context, "已接收", Toast.LENGTH_SHORT).show() } - override fun onDisableRequested(context: Context, intent: Intent): CharSequence? { - val strResult = "这是取消时的提示" - Log.e(">>>>>>>>>", "onDisableRequested") - return strResult + override fun onDisableRequested(context: Context, intent: Intent): CharSequence { + Toast.makeText(context, "撤销授权", Toast.LENGTH_SHORT).show() + return "这是取消时的提示" } override fun onDisabled(context: Context, intent: Intent) { super.onDisabled(context, intent) - Log.e(">>>>>>>>>", "onDisabled") + Toast.makeText(context, "已禁用", Toast.LENGTH_SHORT).show() + } + override fun onSystemUpdatePending(context: Context, intent: Intent, receivedTime: Long) { + if (Build.VERSION.SDK_INT < 26) { + return + } + Toast.makeText(context, "新的系统更新!", Toast.LENGTH_SHORT).show() } } \ No newline at end of file diff --git a/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt new file mode 100644 index 0000000..50a9222 --- /dev/null +++ b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt @@ -0,0 +1,148 @@ +package com.binbin.androidowner + +import android.app.admin.DevicePolicyManager +import android.app.admin.SystemUpdateInfo +import android.app.admin.SystemUpdatePolicy +import android.content.ComponentName +import android.content.Context +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 +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import java.util.Date + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SysUpdatePolicy(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Context){ + val focusMgr = LocalFocusManager.current + Column { + Spacer(Modifier.padding(vertical = 5.dp)) + if(VERSION.SDK_INT>=26){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 6.dp) + .clip(RoundedCornerShape(10.dp)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { + val sysUpdateInfo = myDpm.getPendingSystemUpdate(myComponent) + if(sysUpdateInfo!=null){ + Text("Update first available: ${Date(sysUpdateInfo.receivedTime)}") + Text("Hash code: ${sysUpdateInfo.hashCode()}") + val securityStateDesc = when(sysUpdateInfo.securityPatchState){ + SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN->"SECURITY_PATCH_STATE_UNKNOWN" + SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE->"SECURITY_PATCH_STATE_TRUE" + else->"SECURITY_PATCH_STATE_FALSE" + } + Text("Security patch state: $securityStateDesc") + }else{ + Text("暂无更新信息") + } + } + } + Spacer(Modifier.padding(vertical = 5.dp)) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 6.dp) + .clip(RoundedCornerShape(16.dp)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { + var selectedPolicy by remember{ mutableStateOf(myDpm.systemUpdatePolicy?.policyType) } + Text(text = "系统更新策略", style = MaterialTheme.typography.titleLarge) + RadioButtonItem("准备好后立即更新",{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC}) + RadioButtonItem("在某段时间里更新",{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_WINDOWED},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_WINDOWED}) + RadioButtonItem("延迟30天",{selectedPolicy==SystemUpdatePolicy.TYPE_POSTPONE},{selectedPolicy=SystemUpdatePolicy.TYPE_POSTPONE}) + RadioButtonItem("无",{selectedPolicy == null},{selectedPolicy=null}) + var windowedPolicyStart by remember{ mutableStateOf("") } + var windowedPolicyEnd by remember{ mutableStateOf("") } + if(selectedPolicy==2){ + Spacer(Modifier.padding(vertical = 3.dp)) + Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { + TextField( + value = windowedPolicyStart, + label = { Text("开始时间")}, + onValueChange = {windowedPolicyStart=it}, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + modifier = Modifier.fillMaxWidth(0.5F) + ) + Spacer(Modifier.padding(horizontal = 3.dp)) + TextField( + value = windowedPolicyEnd, + onValueChange = {windowedPolicyEnd=it}, + label = {Text("结束时间")}, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + modifier = Modifier.fillMaxWidth() + ) + } + Spacer(Modifier.padding(vertical = 3.dp)) + Text("请输入一天中的分钟(0~1440)") + } + val policy = + when(selectedPolicy){ + SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC->SystemUpdatePolicy.createAutomaticInstallPolicy() + SystemUpdatePolicy.TYPE_INSTALL_WINDOWED->SystemUpdatePolicy.createWindowedInstallPolicy(windowedPolicyStart.toInt(),windowedPolicyEnd.toInt()) + SystemUpdatePolicy.TYPE_POSTPONE->SystemUpdatePolicy.createPostponeInstallPolicy() + else->null + } + Button( + onClick = {myDpm.setSystemUpdatePolicy(myComponent,policy);Toast.makeText(myContext, "成功!", Toast.LENGTH_SHORT).show()}, + enabled = myDpm.isDeviceOwnerApp("com.binbin.androidowner") + ) { + Text("应用") + } + } + /*val policy = myDpm.systemUpdatePolicy + if(VERSION.SDK_INT>=28&&policy!=null){ + Column { + var dateState = rememberDateRangePickerState() + DateRangePicker(state = dateState) + val frzPeriod = FreezePeriod( + MonthDay.of(6, 1), + MonthDay.of(7, 31)) + policy.freezePeriods = listOf(frzPeriod) + Button( + onClick = { + try{ + myDpm.setSystemUpdatePolicy(myComponent, policy) + }catch (e:SystemUpdatePolicy.ValidationFailedException){ + Toast.makeText(myContext, "正在冷却期", Toast.LENGTH_SHORT).show() + } + } + ) { + Text("设置更新冻结期") + } + + } + }*/ + Spacer(Modifier.padding(vertical = 5.dp)) + } +} diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index e6726b7..82d78b1 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -45,7 +45,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ ) { Text("打开开关后会禁用对应的功能") - SectionTab("网络和互联网") { currentSection = if(currentSection==1){ 0 }else{ 1 } } + 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)} @@ -72,7 +72,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ UserRestrictionItem(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0,myComponent, myDpm) } - SectionTab("其他连接") { currentSection = if(currentSection==6){ 0 }else{ 6 } } + 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) @@ -85,7 +85,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ 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)} } - SectionTab("应用") { currentSection = if(currentSection==2){ 0 }else{ 2 } } + 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)} @@ -95,7 +95,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0,myComponent, myDpm) } } - SectionTab("显示与音量") { currentSection = if(currentSection==3){ 0 }else{ 3 } } + 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) @@ -110,7 +110,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ } } - SectionTab("用户与工作资料") { currentSection = if(currentSection==4){ 0 }else{ 4 } } + 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) @@ -127,7 +127,7 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ } } - SectionTab("杂项") { currentSection = if(currentSection==5){ 0 }else{ 5 } } + 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) @@ -175,17 +175,17 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ } @Composable -fun SectionTab(txt:String,setSection:()->Unit){ +fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){ Text( text = txt, - color = MaterialTheme.colorScheme.onTertiaryContainer, + color = if(getSection()){MaterialTheme.colorScheme.onTertiaryContainer}else{MaterialTheme.colorScheme.onPrimaryContainer}, textAlign = TextAlign.Center, style = MaterialTheme.typography.headlineMedium, modifier = Modifier .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 6.dp) .clip(RoundedCornerShape(15)) - .background(color = MaterialTheme.colorScheme.tertiaryContainer) + .background(color = if(getSection()){MaterialTheme.colorScheme.tertiaryContainer}else{MaterialTheme.colorScheme.primaryContainer}) .clickable(onClick = setSection) .padding(vertical = 8.dp) ) diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml deleted file mode 100644 index f8c6127..0000000 --- a/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b8e9ad..8f780a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,7 +21,7 @@ 允许 禁止 是否禁止: - 包括清空存储空间、清空缓存 + 可以隐藏、停用应用 包括Toast和浮动通知 权限 UI控制 @@ -114,4 +114,16 @@ 用户输入的密码不能与历史记录中的任何密码相同,0为无限制 历史记录长度 USB信号 + + 锁屏信息 + 提供支持的短消息 + 如果你禁用了某个功能,用户尝试使用这个功能时会看见这个消息(可多行) + 消息 + 预设名 + 提供支持的长消息 + 都是显示短消息,长消息不知道在哪里显示 + 禁止蓝牙分享通讯录 + 系统更新策略 + 管理系统更新策略 + 禁止锁屏(需无密码) \ No newline at end of file