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