beautify UI

This commit is contained in:
BinTianqi
2024-01-16 22:19:27 +08:00
parent 5777c232bb
commit 445446554f
13 changed files with 322 additions and 153 deletions

View File

@@ -1,3 +1,26 @@
# 简介
使用安卓的DeviceAdmin和DeviceOwner API管理你的设备
即将加入的功能:安装应用、卸载应用、清空应用数据
欢迎大家提交Issue
### 功能
- 添加用户限制
- 禁止使用蓝牙
- 禁止使用WiFi
- 禁止安装应用
- ......
- 管理应用
- 隐藏应用
- 停用应用
- 禁止卸载应用
- ......
- 设备控制
- 禁用相机
- 禁止截屏
- 隐藏状态栏
这个应用需要的权限十分敏感,如果操作不慎,可能会让你的设备丢失数据或者让你无法解锁你的设备
但是你无需担心,这个应用不是恶意软件

View File

@@ -4,6 +4,9 @@ import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.pm.PackageManager.NameNotFoundException
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.material3.Button
import androidx.compose.material3.Text
@@ -13,13 +16,19 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName){
var pkgName by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(8.dp)) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
var isAppHidden by remember{ mutableStateOf(false) }
var isAppSuspended by remember{ mutableStateOf(false) }
var isAppUninstallBlock by remember{ mutableStateOf(false) }
@@ -45,26 +54,33 @@ fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName){
}
Text("以下功能都需要DeviceOwner权限")
TextField(value = pkgName, onValueChange = {pkgName = it}, label = { Text("包名") })
Button(onClick = { myDpm.setApplicationHidden(myComponent,pkgName,true); isAppHidden = myDpm.isApplicationHidden(myComponent,pkgName) }) {
Text("隐藏")
}
Button(onClick = { myDpm.setApplicationHidden(myComponent,pkgName,false); isAppHidden = myDpm.isApplicationHidden(myComponent,pkgName) }) {
Text("显示")
Spacer(Modifier.padding(5.dp))
Row{
Button(onClick = { myDpm.setApplicationHidden(myComponent,pkgName,true); isAppHidden = myDpm.isApplicationHidden(myComponent,pkgName) },modifier = Modifier.padding(end = 8.dp)) {
Text("隐藏")
}
Button(onClick = { myDpm.setApplicationHidden(myComponent,pkgName,false); isAppHidden = myDpm.isApplicationHidden(myComponent,pkgName) }) {
Text("显示")
}
}
Text("应用隐藏:$isAppHidden ${if(isAppHidden){"(这个应用也许没有被安装)"}else{""}}")
Button(onClick = {myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName),true); isAppSuspended = myDpm.isPackageSuspended(myComponent,pkgName)}) {
Text("停用")
}
Button(onClick = {myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName),false); isAppSuspended = myDpm.isPackageSuspended(myComponent,pkgName)}) {
Text("启用")
Row{
Button(onClick = {myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName),true); isAppSuspended = myDpm.isPackageSuspended(myComponent,pkgName)},modifier = Modifier.padding(end = 8.dp)) {
Text("停用")
}
Button(onClick = {myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName),false); isAppSuspended = myDpm.isPackageSuspended(myComponent,pkgName)}) {
Text("启用")
}
}
Text("应用停用:$isAppSuspended $suspendedReply")
Text("阻止卸载功能有可能出问题")
Button(onClick = { myDpm.setUninstallBlocked(myComponent, pkgName, true); isAppUninstallBlock = myDpm.isUninstallBlocked(myComponent,pkgName) }) {
Text("阻止卸载")
}
Button(onClick = { myDpm.setUninstallBlocked(myComponent, pkgName, false); isAppUninstallBlock = myDpm.isUninstallBlocked(myComponent,pkgName)}) {
Text("允许卸载")
Row {
Button(onClick = { myDpm.setUninstallBlocked(myComponent, pkgName, true); isAppUninstallBlock = myDpm.isUninstallBlocked(myComponent,pkgName) },modifier = Modifier.padding(end = 8.dp)) {
Text("阻止卸载")
}
Button(onClick = { myDpm.setUninstallBlocked(myComponent, pkgName, false); isAppUninstallBlock = myDpm.isUninstallBlocked(myComponent,pkgName)}) {
Text("允许卸载")
}
}
Text("应用防卸载:$isAppUninstallBlock ${if(!isAppUninstallBlock){"(这个应用也许没有被安装)"}else{""}}")
}

View File

@@ -3,19 +3,33 @@ package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.os.Build
import android.os.Build.VERSION
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
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.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -25,41 +39,31 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
}catch(e:SecurityException){
"没有权限"
}
Column {
Text("WiFi MAC: $wifimac")
var isCameraDisabled by remember{ mutableStateOf(myDpm.getCameraDisabled(null)) }
Button(onClick = {myDpm.setCameraDisabled(myComponent, true);isCameraDisabled = myDpm.getCameraDisabled(null)}) {
Text("禁用相机")
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(bottom = 20.dp)
) {
DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, myDpm,{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)})
DeviceCtrlItem(R.string.disable_scrcap,R.string.aosp_scrrec_also_work,myDpm,{myDpm.getScreenCaptureDisabled(null)},{b -> myDpm.setScreenCaptureDisabled(myComponent,b) })
if(VERSION.SDK_INT>=34){
DeviceCtrlItem(R.string.hide_status_bar,R.string.may_hide_notifi_icon_only,myDpm,{myDpm.isStatusBarDisabled},{b -> myDpm.setStatusBarDisabled(myComponent,b) })
}
Button(onClick = {myDpm.setCameraDisabled(myComponent, false);isCameraDisabled = myDpm.getCameraDisabled(null)}) {
Text("启用相机")
if(VERSION.SDK_INT>=30){
DeviceCtrlItem(R.string.auto_time,R.string.place_holder,myDpm,{myDpm.getAutoTimeEnabled(myComponent)},{b -> myDpm.setAutoTimeEnabled(myComponent,b) })
DeviceCtrlItem(R.string.auto_timezone,R.string.place_holder,myDpm,{myDpm.getAutoTimeZoneEnabled(myComponent)},{b -> myDpm.setAutoTimeZoneEnabled(myComponent,b) })
}
Text("AVD上没有相机未测试")
Text("相机被禁用:$isCameraDisabled")
var isScrCapDisabled by remember{ mutableStateOf(myDpm.getScreenCaptureDisabled(null)) }
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,true);isScrCapDisabled = myDpm.getScreenCaptureDisabled(null)}) {
Text("禁止截屏")
}
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,false);isScrCapDisabled = myDpm.getScreenCaptureDisabled(null)}) {
Text("允许截屏")
}
Text("对AOSP的录屏也起作用")
Text("禁止截屏:$isScrCapDisabled")
DeviceCtrlItem(R.string.master_mute,R.string.place_holder,myDpm,{myDpm.isMasterVolumeMuted(myComponent)},{b -> myDpm.setMasterVolumeMuted(myComponent,b) })
DeviceCtrlItem(R.string.backup_service,R.string.place_holder,myDpm,{myDpm.isBackupServiceEnabled(myComponent)},{b -> myDpm.setBackupServiceEnabled(myComponent,b) })
Text("隐藏状态栏需要API34")
Text("自动设置时间和自动设置时区需要API30")
Button(onClick = {myDpm.reboot(myComponent)}) {
Text("重启")
}
Button(onClick = {myDpm.lockNow()}) {
Text("锁屏")
}
var isMasterMuted by remember{ mutableStateOf(false) }
isMasterMuted = try{ myDpm.isMasterVolumeMuted(myComponent) }catch(e:SecurityException){ false }
Button(onClick = {myDpm.setMasterVolumeMuted(myComponent,true);isMasterMuted=myDpm.isMasterVolumeMuted(myComponent)}) {
Text("全部静音")
}
Button(onClick = {myDpm.setMasterVolumeMuted(myComponent,false);isMasterMuted=myDpm.isMasterVolumeMuted(myComponent)}) {
Text("取消静音")
}
Text("静音:$isMasterMuted")
Text("WiFi MAC: $wifimac")
Text("以下功能需要长按按钮,作者并未测试")
Button(
onClick = {},
@@ -72,7 +76,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
) {
Text("WipeData")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
if (VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
Button(
modifier = Modifier
.combinedClickable(onClick = {}, onLongClick = {myDpm.wipeDevice(0)}),
@@ -87,3 +91,44 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
}
}
}
@Composable
fun DeviceCtrlItem(
itemName:Int,
itemDesc:Int,
myDpm: DevicePolicyManager,
getMethod:()->Boolean,
setMethod:(b:Boolean)->Unit
){
var isEnabled by remember{ mutableStateOf(false) }
Row(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(8.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
text = stringResource(itemName),
style = MaterialTheme.typography.titleLarge
)
if(itemDesc!=R.string.place_holder){
Text(stringResource(itemDesc))
}
}
if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){
isEnabled = getMethod()
Switch(
checked = isEnabled,
onCheckedChange = {
setMethod(!isEnabled)
isEnabled=getMethod()
}
)
}
}
}

View File

@@ -5,7 +5,6 @@ import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.os.Bundle
import android.provider.CalendarContract.Colors
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -15,8 +14,11 @@ 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.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
@@ -31,11 +33,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@@ -47,8 +49,8 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
getWindow().decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
getWindow().decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
window.decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
window.decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
//getWindow().setStatusBarColor(Color.White)
super.onCreate(savedInstanceState)
val context = applicationContext
@@ -97,19 +99,37 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface
)
),
navigationIcon = {
if(topBarName!=R.string.app_name){
Icon(
imageVector = Icons.Outlined.ArrowBack,
contentDescription = "Back",
modifier = Modifier
.padding(horizontal = 6.dp)
.clip(RoundedCornerShape(50))
.clickable(onClick = {
navCtrl.navigate("HomePage") {
popUpTo(
navCtrl.graph.findStartDestination().id
) { saveState = true }
}
})
.padding(5.dp)
)
}
}
)
}
) {
NavHost(
navController = navCtrl,
startDestination = "HomePage",
modifier = Modifier.padding(top = it.calculateTopPadding())
modifier = Modifier.padding(top = it.calculateTopPadding()).navigationBarsPadding()
){
composable(route = "HomePage", content = { HomePage(navCtrl)})
composable(route = "HomePage", content = { HomePage(navCtrl,mainDpm,mainComponent)})
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)})
composable(route = "Permissions", content = { DpmPermissions(mainDpm,mainComponent,mainContext)})
composable(route = "UIControl", content = { UIControl(mainDpm,mainComponent)})
composable(route = "ApplicationManage", content = { ApplicationManage(mainDpm,mainComponent)})
composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent)})
}
@@ -117,13 +137,47 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
}
@Composable
fun HomePage(navCtrl:NavHostController){
fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:ComponentName){
val isda = myDpm.isAdminActive(myComponent)
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
val activated = if(isdo){"Device Owner 已激活"}else if(isda){"Device Admin已激活"}else{""} + "未激活"
Column {
HomePageItem(R.string.permission, R.drawable.security_fill0, R.string.permission_desc, "Permissions", navCtrl)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 5.dp, horizontal = 8.dp)
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.tertiaryContainer)
.clickable(onClick = { navCtrl.navigate("Permissions") })
.padding(horizontal = 5.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = if(isda){
painterResource(R.drawable.check_fill0)
}else{
painterResource(R.drawable.block_fill0)
},
contentDescription = null,
modifier = Modifier.padding(horizontal = 13.dp),
tint = MaterialTheme.colorScheme.tertiary
)
Column {
Text(
text = stringResource(R.string.permission),
style = MaterialTheme.typography.headlineSmall,
color = MaterialTheme.colorScheme.onTertiaryContainer
)
Text(
text = activated,
color = MaterialTheme.colorScheme.onTertiaryContainer
)
}
}
//HomePageItem(R.string.permission, R.drawable.security_fill0, R.string.permission_desc, "Permissions", navCtrl)
HomePageItem(R.string.device_ctrl, R.drawable.mobile_phone_fill0, R.string.device_ctrl_desc, "DeviceControl", navCtrl)
HomePageItem(R.string.ui_ctrl, R.drawable.info_fill0, R.string.ui_ctrl_desc, "UIControl", navCtrl)
HomePageItem(R.string.app_manage, R.drawable.info_fill0, R.string.apps_ctrl_description, "ApplicationManage", navCtrl)
HomePageItem(R.string.user_restrict, R.drawable.info_fill0, R.string.user_restrict_desc, "UserRestriction", navCtrl)
HomePageItem(R.string.app_manage, R.drawable.apps_fill0, R.string.apps_ctrl_description, "ApplicationManage", navCtrl)
HomePageItem(R.string.user_restrict, R.drawable.manage_accounts_fill0, R.string.user_restrict_desc, "UserRestriction", navCtrl)
}
}
@@ -136,7 +190,7 @@ fun HomePageItem(name:Int, imgVector:Int, description:Int, navTo:String, myNav:N
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.clickable(onClick = { myNav.navigate(navTo) })
.padding(5.dp),
.padding(6.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(

View File

@@ -6,8 +6,11 @@ import android.content.Context
import android.content.Intent
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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -22,6 +25,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.unit.dp
@@ -33,80 +37,76 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
//da:DeviceAdmin do:DeviceOwner
val isda = myDpm.isAdminActive(myComponent)
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
val ispo = myDpm.isProfileOwnerApp("com.binbin.androidowner")
Column(
modifier = Modifier
.padding(8.dp)
.verticalScroll(rememberScrollState())
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("权限DeviceAdmin < ProfileOwner < DeviceOwner")
Column(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)
.clip(RoundedCornerShape(8))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(10.dp)
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(text = "Device Admin", style = MaterialTheme.typography.titleLarge)
Text("Device Admin: $isda")
Column {
Text(text = "Device Admin", style = MaterialTheme.typography.titleLarge)
Text(if(isda){"已激活"}else{"未激活"})
}
if(isda){
Button(onClick = {myDpm.removeActiveAdmin(myComponent)}) {
Text("撤销")
}
}else{
Button(onClick = { ActivateDeviceAdmin(myDpm, myComponent, myContext) }) {
Text("激活")
}
}
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)
.clip(RoundedCornerShape(8))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(text = "Device Owner", style = MaterialTheme.typography.titleLarge)
Text(if(isda){"已激活"}else{"未激活"})
}
if(isdo){
Button(onClick = {myDpm.clearDeviceOwnerApp("com.binbin.androidowner")}) {
Text("撤销")
}
}
}
if(isdo||isda){Text("注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态")}
Spacer(Modifier.padding(5.dp))
if(!isda){
SelectionContainer {
Text("dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver")
}
Button(onClick = {Runtime.getRuntime().exec("su -c \"dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"")}) {
Text("获取DeviceAdmin需root未测试")
}
Button(onClick = { ActivateDeviceAdmin(myDpm, myComponent, myContext) }) {
Text("在设置中激活DeviceAdmin")
}
Button(onClick = {myDpm.removeActiveAdmin(myComponent)}) {
Text("不当Device Admin了")
}
}
Spacer(modifier = Modifier.padding(6.dp))
Column(
modifier = Modifier
.clip(RoundedCornerShape(8))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(10.dp)
) {
Text(text = "Device Owner", style = MaterialTheme.typography.titleLarge)
Text("Device Owner: $isdo")
if(!isdo){
SelectionContainer {
Text("dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver")
}
Button(onClick = {Runtime.getRuntime().exec("su -c \"dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"")}) {
Text("获取DeviceOwner需root未测试")
}
Button(onClick = {myDpm.clearDeviceOwnerApp("com.binbin.androidowner")}) {
Text("不当Device Owner了")
}
Text("注意!在这里清除权限不会清除配置。比如:被停用的应用会保持停用状态")
}
if(isdo){
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信息")
}
}
Spacer(modifier = Modifier.padding(6.dp))
Column(
modifier = Modifier
.clip(RoundedCornerShape(8))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(10.dp)
) {
Text("Profile Owner是一个过时的功能目前在这个应用里没啥用。")
Text(text = "Profile Owner", style = MaterialTheme.typography.titleLarge)
Text("Profile Owner: $ispo")
SelectionContainer {
Text("dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver")
}
Button(onClick = {Runtime.getRuntime().exec("su -c \"dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"")}) {
Text("获取ProfileOwner需root未测试")
}
Button(onClick = {myDpm.clearProfileOwner(myComponent)}) {
Text("不当Profile Owner了")
}
}
}
}
@@ -122,5 +122,4 @@ fun ActivateDeviceAdmin(myDpm: DevicePolicyManager,myComponent: ComponentName,my
} else {
Toast.makeText(myContext, "已经激活", Toast.LENGTH_SHORT).show()
}
}

View File

@@ -1,26 +0,0 @@
package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun UIControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
Column(
modifier = Modifier.padding(8.dp)
) {
Button(onClick = {myDpm.setStatusBarDisabled(myComponent,true)}) {
Text("隐藏状态栏")
}
Button(onClick = {myDpm.setStatusBarDisabled(myComponent,false)}) {
Text("显示状态栏")
}
Text("也许只能控制状态栏上的通知图标")
}
}

View File

@@ -33,7 +33,11 @@ import androidx.compose.ui.unit.dp
@Composable
fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){
val verticalScrolling = rememberScrollState()
Column(modifier = Modifier.verticalScroll(verticalScrolling)) {
Column(
modifier = Modifier
.verticalScroll(verticalScrolling)
.padding(bottom = 20.dp)
) {
UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",myComponent, myDpm)
UserRestrictionItem(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",myComponent, myDpm)
UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",myComponent, myDpm)
@@ -96,19 +100,19 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes
}
if(isdo){
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
Switch(
checked = strictState,
onCheckedChange = {
strictState=it
if(strictState){
myDpm.addUserRestriction(myComponent,restriction)
}else{
myDpm.clearUserRestriction(myComponent,restriction)
}
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
},
enabled = isdo
)
}
Switch(
checked = strictState,
onCheckedChange = {
strictState=it
if(strictState){
myDpm.addUserRestriction(myComponent,restriction)
}else{
myDpm.clearUserRestriction(myComponent,restriction)
}
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
},
enabled = isdo
)
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M240,800q-33,0 -56.5,-23.5T160,720q0,-33 23.5,-56.5T240,640q33,0 56.5,23.5T320,720q0,33 -23.5,56.5T240,800ZM480,800q-33,0 -56.5,-23.5T400,720q0,-33 23.5,-56.5T480,640q33,0 56.5,23.5T560,720q0,33 -23.5,56.5T480,800ZM720,800q-33,0 -56.5,-23.5T640,720q0,-33 23.5,-56.5T720,640q33,0 56.5,23.5T800,720q0,33 -23.5,56.5T720,800ZM240,560q-33,0 -56.5,-23.5T160,480q0,-33 23.5,-56.5T240,400q33,0 56.5,23.5T320,480q0,33 -23.5,56.5T240,560ZM480,560q-33,0 -56.5,-23.5T400,480q0,-33 23.5,-56.5T480,400q33,0 56.5,23.5T560,480q0,33 -23.5,56.5T480,560ZM720,560q-33,0 -56.5,-23.5T640,480q0,-33 23.5,-56.5T720,400q33,0 56.5,23.5T800,480q0,33 -23.5,56.5T720,560ZM240,320q-33,0 -56.5,-23.5T160,240q0,-33 23.5,-56.5T240,160q33,0 56.5,23.5T320,240q0,33 -23.5,56.5T240,320ZM480,320q-33,0 -56.5,-23.5T400,240q0,-33 23.5,-56.5T480,160q33,0 56.5,23.5T560,240q0,33 -23.5,56.5T480,320ZM720,320q-33,0 -56.5,-23.5T640,240q0,-33 23.5,-56.5T720,160q33,0 56.5,23.5T800,240q0,33 -23.5,56.5T720,320Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M480,880q-83,0 -156,-31.5T197,763q-54,-54 -85.5,-127T80,480q0,-83 31.5,-156T197,197q54,-54 127,-85.5T480,80q83,0 156,31.5T763,197q54,54 85.5,127T880,480q0,83 -31.5,156T763,763q-54,54 -127,85.5T480,880ZM480,800q54,0 104,-17.5t92,-50.5L228,284q-33,42 -50.5,92T160,480q0,134 93,227t227,93ZM732,676q33,-42 50.5,-92T800,480q0,-134 -93,-227t-227,-93q-54,0 -104,17.5T284,228l448,448Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M382,720 L154,492l57,-57 171,171 367,-367 57,57 -424,424Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M400,480q-66,0 -113,-47t-47,-113q0,-66 47,-113t113,-47q66,0 113,47t47,113q0,66 -47,113t-113,47ZM80,800v-112q0,-33 17,-62t47,-44q51,-26 115,-44t141,-18h14q6,0 12,2 -8,18 -13.5,37.5T404,600h-4q-71,0 -127.5,18T180,654q-9,5 -14.5,14t-5.5,20v32h252q6,21 16,41.5t22,38.5L80,800ZM640,840 L628,780q-12,-5 -22.5,-10.5T584,756l-58,18 -40,-68 46,-40q-2,-14 -2,-26t2,-26l-46,-40 40,-68 58,18q11,-8 21.5,-13.5T628,500l12,-60h80l12,60q12,5 22.5,11t21.5,15l58,-20 40,70 -46,40q2,12 2,25t-2,25l46,40 -40,68 -58,-18q-11,8 -21.5,13.5T732,780l-12,60h-80ZM680,720q33,0 56.5,-23.5T760,640q0,-33 -23.5,-56.5T680,560q-33,0 -56.5,23.5T600,640q0,33 23.5,56.5T680,720ZM400,400q33,0 56.5,-23.5T480,320q0,-33 -23.5,-56.5T400,240q-33,0 -56.5,23.5T320,320q0,33 23.5,56.5T400,400ZM400,320ZM412,720Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M504,480 L320,296l56,-56 240,240 -240,240 -56,-56 184,-184Z"/>
</vector>

View File

@@ -31,4 +31,13 @@
<string name="autofill">自动填充服务</string>
<string name="camera_toggle">切换相机</string>
<string name="bt_share">蓝牙分享</string>
<string name="disable_cam">禁用相机</string>
<string name="disable_scrcap">禁止截屏</string>
<string name="master_mute">全局静音</string>
<string name="aosp_scrrec_also_work">对AOSP的录屏也起作用</string>
<string name="hide_status_bar">隐藏状态栏</string>
<string name="may_hide_notifi_icon_only">也许只能隐藏状态栏上的通知图标</string>
<string name="auto_time">自动设置时间</string>
<string name="auto_timezone">自动设置时区</string>
<string name="backup_service">备份服务</string>
</resources>