From 445446554fa2785b0869a1655f8e49416daff9dd Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Tue, 16 Jan 2024 22:19:27 +0800 Subject: [PATCH] beautify UI --- Readme.md | 25 +++- .../binbin/androidowner/ApplicationManage.kt | 48 +++++--- .../com/binbin/androidowner/DeviceControl.kt | 101 ++++++++++++----- .../com/binbin/androidowner/MainActivity.kt | 82 +++++++++++--- .../com/binbin/androidowner/Permissions.kt | 107 +++++++++--------- .../java/com/binbin/androidowner/UIControl.kt | 26 ----- .../com/binbin/androidowner/UserRestrict.kt | 32 +++--- app/src/main/res/drawable/apps_fill0.xml | 9 ++ app/src/main/res/drawable/block_fill0.xml | 9 ++ app/src/main/res/drawable/check_fill0.xml | 9 ++ .../res/drawable/manage_accounts_fill0.xml | 9 ++ .../main/res/drawable/navigate_next_fill0.xml | 9 ++ app/src/main/res/values/strings.xml | 9 ++ 13 files changed, 322 insertions(+), 153 deletions(-) delete mode 100644 app/src/main/java/com/binbin/androidowner/UIControl.kt create mode 100644 app/src/main/res/drawable/apps_fill0.xml create mode 100644 app/src/main/res/drawable/block_fill0.xml create mode 100644 app/src/main/res/drawable/check_fill0.xml create mode 100644 app/src/main/res/drawable/manage_accounts_fill0.xml create mode 100644 app/src/main/res/drawable/navigate_next_fill0.xml diff --git a/Readme.md b/Readme.md index 5ce03f1..135076e 100644 --- a/Readme.md +++ b/Readme.md @@ -1,3 +1,26 @@ # 简介 + 使用安卓的DeviceAdmin和DeviceOwner API管理你的设备! -即将加入的功能:安装应用、卸载应用、清空应用数据 \ No newline at end of file + +欢迎大家提交Issue + +### 功能 + +- 添加用户限制 + - 禁止使用蓝牙 + - 禁止使用WiFi + - 禁止安装应用 + - ...... +- 管理应用 + - 隐藏应用 + - 停用应用 + - 禁止卸载应用 + - ...... +- 设备控制 + - 禁用相机 + - 禁止截屏 + - 隐藏状态栏 + +这个应用需要的权限十分敏感,如果操作不慎,可能会让你的设备丢失数据或者让你无法解锁你的设备 + +但是你无需担心,这个应用不是恶意软件 diff --git a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt index bc0c86e..cbdf106 100644 --- a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt +++ b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt @@ -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{""}}") } diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index 4186374..b110770 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -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() + } + ) + } + } +} diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index 0810fd4..dc5a781 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -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( diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index b16c596..87e1ced 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -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() } - } diff --git a/app/src/main/java/com/binbin/androidowner/UIControl.kt b/app/src/main/java/com/binbin/androidowner/UIControl.kt deleted file mode 100644 index 949a7a8..0000000 --- a/app/src/main/java/com/binbin/androidowner/UIControl.kt +++ /dev/null @@ -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("也许只能控制状态栏上的通知图标") - } -} diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index 5cd72ae..99bb2c0 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -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 + ) } } diff --git a/app/src/main/res/drawable/apps_fill0.xml b/app/src/main/res/drawable/apps_fill0.xml new file mode 100644 index 0000000..88a2661 --- /dev/null +++ b/app/src/main/res/drawable/apps_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/block_fill0.xml b/app/src/main/res/drawable/block_fill0.xml new file mode 100644 index 0000000..2c8f676 --- /dev/null +++ b/app/src/main/res/drawable/block_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/check_fill0.xml b/app/src/main/res/drawable/check_fill0.xml new file mode 100644 index 0000000..f97e17d --- /dev/null +++ b/app/src/main/res/drawable/check_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/manage_accounts_fill0.xml b/app/src/main/res/drawable/manage_accounts_fill0.xml new file mode 100644 index 0000000..8abd154 --- /dev/null +++ b/app/src/main/res/drawable/manage_accounts_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/navigate_next_fill0.xml b/app/src/main/res/drawable/navigate_next_fill0.xml new file mode 100644 index 0000000..76c4b34 --- /dev/null +++ b/app/src/main/res/drawable/navigate_next_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de53b39..8d5942f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,4 +31,13 @@ 自动填充服务 切换相机 蓝牙分享 + 禁用相机 + 禁止截屏 + 全局静音 + 对AOSP的录屏也起作用 + 隐藏状态栏 + 也许只能隐藏状态栏上的通知图标 + 自动设置时间 + 自动设置时区 + 备份服务 \ No newline at end of file