mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
use switch instead of button in 'UserRestriction' section
This commit is contained in:
3
Readme.md
Normal file
3
Readme.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# 简介
|
||||||
|
使用安卓的DeviceAdmin和DeviceOwner API管理你的设备!
|
||||||
|
即将加入的功能:安装应用、卸载应用、清空应用数据
|
||||||
@@ -61,6 +61,7 @@ dependencies {
|
|||||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
implementation("androidx.compose.material3:material3")
|
implementation("androidx.compose.material3:material3")
|
||||||
implementation("androidx.navigation:navigation-compose:2.7.6")
|
implementation("androidx.navigation:navigation-compose:2.7.6")
|
||||||
|
implementation("com.google.accompanist:accompanist-systemuicontroller:0.33.2-alpha")
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.AndroidOwner"
|
android:theme="@style/Theme.AndroidOwner"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:testOnly="true"
|
|
||||||
tools:targetApi="34">
|
tools:targetApi="34">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.binbin.androidowner
|
|||||||
|
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
import android.os.Build
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -10,8 +11,11 @@ import androidx.compose.material3.ButtonDefaults
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -23,35 +27,63 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
|
|||||||
}
|
}
|
||||||
Column {
|
Column {
|
||||||
Text("WiFi MAC: $wifimac")
|
Text("WiFi MAC: $wifimac")
|
||||||
Button(onClick = {myDpm.setCameraDisabled(myComponent, true)}) {
|
var isCameraDisabled by remember{ mutableStateOf(myDpm.getCameraDisabled(null)) }
|
||||||
|
Button(onClick = {myDpm.setCameraDisabled(myComponent, true);isCameraDisabled = myDpm.getCameraDisabled(null)}) {
|
||||||
Text("禁用相机")
|
Text("禁用相机")
|
||||||
}
|
}
|
||||||
Button(onClick = {myDpm.setCameraDisabled(myComponent, false)}) {
|
Button(onClick = {myDpm.setCameraDisabled(myComponent, false);isCameraDisabled = myDpm.getCameraDisabled(null)}) {
|
||||||
Text("启用相机")
|
Text("启用相机")
|
||||||
}
|
}
|
||||||
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,true)}) {
|
Text("AVD上没有相机,未测试")
|
||||||
|
Text("相机被禁用:$isCameraDisabled")
|
||||||
|
var isScrCapDisabled by remember{ mutableStateOf(myDpm.getScreenCaptureDisabled(null)) }
|
||||||
|
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,true);isScrCapDisabled = myDpm.getScreenCaptureDisabled(null)}) {
|
||||||
Text("禁止截屏")
|
Text("禁止截屏")
|
||||||
}
|
}
|
||||||
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,false)}) {
|
Button(onClick = {myDpm.setScreenCaptureDisabled(myComponent,false);isScrCapDisabled = myDpm.getScreenCaptureDisabled(null)}) {
|
||||||
Text("允许截屏")
|
Text("允许截屏")
|
||||||
}
|
}
|
||||||
|
Text("对AOSP的录屏也起作用")
|
||||||
|
Text("禁止截屏:$isScrCapDisabled")
|
||||||
Button(onClick = {myDpm.reboot(myComponent)}) {
|
Button(onClick = {myDpm.reboot(myComponent)}) {
|
||||||
Text("重启")
|
Text("重启")
|
||||||
}
|
}
|
||||||
Button(onClick = {myDpm.lockNow()}) {
|
Button(onClick = {myDpm.lockNow()}) {
|
||||||
Text("锁屏")
|
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("以下功能需要长按按钮,作者并未测试")
|
||||||
Button(
|
Button(
|
||||||
onClick = {},
|
onClick = {},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.combinedClickable(onClick = {}, onLongClick = {myDpm.wipeData(0)}),
|
.combinedClickable(onClick = {}, onLongClick = {myDpm.wipeData(0)}),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = MaterialTheme.colorScheme.errorContainer
|
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||||
|
contentColor = MaterialTheme.colorScheme.error
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text("WipeData")
|
||||||
text = "FACTORY_RESET!!!!! (长按)(未测试)",
|
}
|
||||||
color = MaterialTheme.colorScheme.error)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.combinedClickable(onClick = {}, onLongClick = {myDpm.wipeDevice(0)}),
|
||||||
|
onClick = {},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||||
|
contentColor = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("WipeDevice(API34)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,18 @@ import android.app.admin.DevicePolicyManager
|
|||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.CalendarContract.Colors
|
||||||
|
import android.view.View
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -24,25 +25,45 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
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.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
|
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
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)
|
||||||
|
//getWindow().setStatusBarColor(Color.White)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val context = applicationContext
|
val context = applicationContext
|
||||||
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
val adminComponent = ComponentName(context,MyDeviceAdminReceiver::class.java)
|
val adminComponent = ComponentName(context,MyDeviceAdminReceiver::class.java)
|
||||||
setContent {
|
setContent {
|
||||||
|
val sysUiCtrl = rememberSystemUiController()
|
||||||
|
val sf = MaterialTheme.colorScheme.surface
|
||||||
|
val useDarkIcon = !isSystemInDarkTheme()
|
||||||
|
SideEffect {
|
||||||
|
sysUiCtrl.run {
|
||||||
|
setNavigationBarColor(sf,useDarkIcon)
|
||||||
|
setStatusBarColor(Color.White.copy(alpha = 0F),useDarkIcon)
|
||||||
|
}
|
||||||
|
}
|
||||||
AndroidOwnerTheme {
|
AndroidOwnerTheme {
|
||||||
MyScaffold(dpm,adminComponent,context)
|
MyScaffold(dpm,adminComponent,context)
|
||||||
}
|
}
|
||||||
@@ -55,10 +76,25 @@ class MainActivity : ComponentActivity() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainContext:Context){
|
fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainContext:Context){
|
||||||
val navCtrl = rememberNavController()
|
val navCtrl = rememberNavController()
|
||||||
|
val backStackEntry by navCtrl.currentBackStackEntryAsState()
|
||||||
|
val topBarNameMap = mapOf(
|
||||||
|
"HomePage" to R.string.app_name,
|
||||||
|
"DeviceControl" to R.string.device_ctrl,
|
||||||
|
"Permissions" to R.string.permission,
|
||||||
|
"UIControl" to R.string.ui_ctrl,
|
||||||
|
"ApplicationManage" to R.string.app_manage,
|
||||||
|
"UserRestriction" to R.string.user_restrict
|
||||||
|
)
|
||||||
|
val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(text = "Android Owner",color = MaterialTheme.colorScheme.onSurface)},
|
title = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(topBarName) ,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface
|
||||||
|
)
|
||||||
|
},
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface
|
containerColor = MaterialTheme.colorScheme.surface
|
||||||
)
|
)
|
||||||
@@ -68,7 +104,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
|
|||||||
NavHost(
|
NavHost(
|
||||||
navController = navCtrl,
|
navController = navCtrl,
|
||||||
startDestination = "HomePage",
|
startDestination = "HomePage",
|
||||||
modifier = Modifier.padding(top = 70.dp)
|
modifier = Modifier.padding(top = it.calculateTopPadding())
|
||||||
){
|
){
|
||||||
composable(route = "HomePage", content = { HomePage(navCtrl)})
|
composable(route = "HomePage", content = { HomePage(navCtrl)})
|
||||||
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)})
|
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)})
|
||||||
@@ -83,8 +119,8 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
|
|||||||
@Composable
|
@Composable
|
||||||
fun HomePage(navCtrl:NavHostController){
|
fun HomePage(navCtrl:NavHostController){
|
||||||
Column {
|
Column {
|
||||||
HomePageItem(R.string.permission, R.drawable.info_fill0, R.string.permission_desc, "Permissions", navCtrl)
|
HomePageItem(R.string.permission, R.drawable.security_fill0, R.string.permission_desc, "Permissions", navCtrl)
|
||||||
HomePageItem(R.string.device_ctrl, R.drawable.info_fill0, R.string.device_ctrl_desc, "DeviceControl", 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.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.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.user_restrict, R.drawable.info_fill0, R.string.user_restrict_desc, "UserRestriction", navCtrl)
|
||||||
|
|||||||
@@ -3,14 +3,29 @@ package com.binbin.androidowner
|
|||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
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.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -18,29 +33,94 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
|
|||||||
//da:DeviceAdmin do:DeviceOwner
|
//da:DeviceAdmin do:DeviceOwner
|
||||||
val isda = myDpm.isAdminActive(myComponent)
|
val isda = myDpm.isAdminActive(myComponent)
|
||||||
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
|
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
|
||||||
|
val ispo = myDpm.isProfileOwnerApp("com.binbin.androidowner")
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(8.dp)
|
modifier = Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
|
Text("权限:DeviceAdmin < ProfileOwner < DeviceOwner")
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(8))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
Text(text = "Device Admin", style = MaterialTheme.typography.titleLarge)
|
||||||
Text("Device Admin: $isda")
|
Text("Device Admin: $isda")
|
||||||
Text("Device Owner: $isdo")
|
|
||||||
SelectionContainer {
|
SelectionContainer {
|
||||||
Column {
|
Text("dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver")
|
||||||
Text("设置DeviceAdmin命令:dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver")
|
|
||||||
Text("设置DeviceOwner命令:dpm set-device-owner 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\"")}) {
|
Button(onClick = {Runtime.getRuntime().exec("su -c \"dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"")}) {
|
||||||
Text("获取DeviceAdmin(需root,未测试)")
|
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")
|
||||||
|
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\"")}) {
|
Button(onClick = {Runtime.getRuntime().exec("su -c \"dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"")}) {
|
||||||
Text("获取DeviceOwner(需root,未测试)")
|
Text("获取DeviceOwner(需root,未测试)")
|
||||||
}
|
}
|
||||||
Text("注意!在这里清除权限不会清除配置。比如:被停用的应用会保持停用状态")
|
|
||||||
Button(onClick = {myDpm.clearDeviceOwnerApp("com.binbin.androidowner")}) {
|
Button(onClick = {myDpm.clearDeviceOwnerApp("com.binbin.androidowner")}) {
|
||||||
Text("不当Device Owner了")
|
Text("不当Device Owner了")
|
||||||
}
|
}
|
||||||
Button(onClick = {myDpm.removeActiveAdmin(myComponent)}) {
|
Text("注意!在这里清除权限不会清除配置。比如:被停用的应用会保持停用状态")
|
||||||
Text("不当Device Admin了(同时会取消DeviceOwner)")
|
var lockScrInfo by remember { mutableStateOf("") }
|
||||||
|
TextField(value = lockScrInfo, onValueChange = { lockScrInfo= it}, label = { Text("锁屏信息") })
|
||||||
|
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了")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ActivateDeviceAdmin(myDpm: DevicePolicyManager,myComponent: ComponentName,myContext: Context){
|
||||||
|
if (!myDpm.isAdminActive(myComponent)) {
|
||||||
|
val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, myComponent)
|
||||||
|
intent.putExtra(
|
||||||
|
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
|
||||||
|
"在这里激活Android Owner"
|
||||||
|
)
|
||||||
|
startActivity(myContext,intent,null)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(myContext, "已经激活", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,5 +21,6 @@ fun UIControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
|
|||||||
Button(onClick = {myDpm.setStatusBarDisabled(myComponent,false)}) {
|
Button(onClick = {myDpm.setStatusBarDisabled(myComponent,false)}) {
|
||||||
Text("显示状态栏")
|
Text("显示状态栏")
|
||||||
}
|
}
|
||||||
|
Text("也许只能控制状态栏上的通知图标")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package com.binbin.androidowner
|
|||||||
|
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
import android.os.Build
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -11,15 +13,18 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material.icons.outlined.Info
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -32,58 +37,78 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){
|
|||||||
UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",myComponent, myDpm)
|
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_CONFIG_WIFI,R.string.config_wifi,"",myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",myComponent, myDpm)
|
||||||
|
UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",myComponent, myDpm)
|
||||||
|
if(Build.VERSION.SDK_INT>=28){
|
||||||
UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",myComponent, myDpm)
|
||||||
|
UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",myComponent, myDpm)
|
||||||
|
}
|
||||||
UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",myComponent, myDpm)
|
|
||||||
UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",myComponent, myDpm)
|
||||||
|
if(Build.VERSION.SDK_INT>=31){
|
||||||
|
UserRestrictionItem(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",myComponent, myDpm)
|
||||||
|
}
|
||||||
UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",myComponent, myDpm)
|
||||||
UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),myComponent, myDpm)
|
UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),myComponent, myDpm)
|
||||||
|
UserRestrictionItem(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",myComponent, myDpm)
|
||||||
|
if(Build.VERSION.SDK_INT<28){
|
||||||
|
Text("以下功能需要安卓9或以上:飞行模式、位置信息、调整亮度")
|
||||||
|
}
|
||||||
|
if(Build.VERSION.SDK_INT<31){
|
||||||
|
Text("以下功能需要安卓12或以上:相机切换")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDescription:String, myComponent: ComponentName, myDpm: DevicePolicyManager){
|
private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDescription:String, myComponent: ComponentName, myDpm: DevicePolicyManager){
|
||||||
var strictState by remember{ mutableStateOf(myDpm.getUserRestrictions(myComponent).getBoolean(restriction)) }
|
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
|
||||||
Column(
|
var strictState by remember{ mutableStateOf(false) }
|
||||||
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 5.dp, horizontal = 8.dp)
|
.padding(vertical = 5.dp, horizontal = 8.dp)
|
||||||
.clip(RoundedCornerShape(10))
|
.clip(RoundedCornerShape(10))
|
||||||
.background(color = MaterialTheme.colorScheme.secondaryContainer)
|
.background(color = MaterialTheme.colorScheme.secondaryContainer)
|
||||||
.padding(5.dp)
|
.padding(5.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
){
|
){
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Info,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp)
|
||||||
|
)
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.align(Alignment.CenterVertically)
|
||||||
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(itemName),
|
text = stringResource(itemName),
|
||||||
style = MaterialTheme.typography.titleLarge
|
style = MaterialTheme.typography.titleLarge
|
||||||
)
|
)
|
||||||
if(restrictionDescription!=""){Text(restrictionDescription)}
|
if(restrictionDescription!=""){Text(restrictionDescription)}
|
||||||
Text(text = "禁止:$strictState")
|
|
||||||
Row {
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
myDpm.clearUserRestriction(myComponent,restriction)
|
|
||||||
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
|
||||||
},
|
|
||||||
modifier = Modifier.padding(3.dp)
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.allow))
|
|
||||||
}
|
}
|
||||||
Button(
|
}
|
||||||
onClick = {
|
if(isdo){
|
||||||
|
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
||||||
|
Switch(
|
||||||
|
checked = strictState,
|
||||||
|
onCheckedChange = {
|
||||||
|
strictState=it
|
||||||
|
if(strictState){
|
||||||
myDpm.addUserRestriction(myComponent,restriction)
|
myDpm.addUserRestriction(myComponent,restriction)
|
||||||
|
}else{
|
||||||
|
myDpm.clearUserRestriction(myComponent,restriction)
|
||||||
|
}
|
||||||
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
|
||||||
},
|
},
|
||||||
colors = ButtonDefaults.buttonColors(
|
enabled = isdo
|
||||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
)
|
||||||
contentColor = MaterialTheme.colorScheme.error
|
|
||||||
) ,
|
|
||||||
modifier = Modifier.padding(2.dp)
|
|
||||||
) {
|
|
||||||
Text(text = stringResource(R.string.disallow))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
app/src/main/res/drawable/mobile_phone_fill0.xml
Normal file
9
app/src/main/res/drawable/mobile_phone_fill0.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M15.5,1h-8C6.12,1 5,2.12 5,3.5v17C5,21.88 6.12,23 7.5,23h8c1.38,0 2.5,-1.12 2.5,-2.5v-17C18,2.12 16.88,1 15.5,1zM11.5,22c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM16,18L7,18L7,4h9v14z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/security_fill0.xml
Normal file
9
app/src/main/res/drawable/security_fill0.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/>
|
||||||
|
</vector>
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Android Owner</string>
|
<string name="app_name">Android Owner</string>
|
||||||
<string name="bluetooth">蓝牙</string>
|
<string name="bluetooth">蓝牙</string>
|
||||||
<string name="airplane_mode">飞行模式(需安卓9)</string>
|
<string name="airplane_mode">飞行模式</string>
|
||||||
<string name="config_wifi">配置Wi-Fi</string>
|
<string name="config_wifi">配置Wi-Fi</string>
|
||||||
<string name="debug_features">调试功能</string>
|
<string name="debug_features">调试功能</string>
|
||||||
<string name="config_location">配置位置信息(需安卓9)</string>
|
<string name="config_location">配置位置信息</string>
|
||||||
<string name="config_mobile_network">配置移动数据</string>
|
<string name="config_mobile_network">配置移动数据</string>
|
||||||
<string name="create_windows">创建窗口</string>
|
<string name="create_windows">创建窗口</string>
|
||||||
<string name="allow">允许</string>
|
<string name="allow">允许</string>
|
||||||
<string name="disallow">禁止</string>
|
<string name="disallow">禁止</string>
|
||||||
<string name="is_disallow">是否禁止:</string>
|
<string name="is_disallow">是否禁止:</string>
|
||||||
<string name="adjust_volume">调整音量</string>
|
<string name="adjust_volume">调整音量</string>
|
||||||
<string name="config_brightness">调整亮度(需安卓9)</string>
|
<string name="config_brightness">调整亮度</string>
|
||||||
<string name="install_apps">安装应用</string>
|
<string name="install_apps">安装应用</string>
|
||||||
<string name="sms">短信</string>
|
<string name="sms">短信</string>
|
||||||
<string name="apps_ctrl">控制应用</string>
|
<string name="apps_ctrl">控制应用</string>
|
||||||
@@ -28,4 +28,7 @@
|
|||||||
<string name="ui_ctrl_desc">目前没啥功能</string>
|
<string name="ui_ctrl_desc">目前没啥功能</string>
|
||||||
<string name="app_manage_desc">非DeviceOwner勿入</string>
|
<string name="app_manage_desc">非DeviceOwner勿入</string>
|
||||||
<string name="user_restrict_desc">限制一些功能</string>
|
<string name="user_restrict_desc">限制一些功能</string>
|
||||||
|
<string name="autofill">自动填充服务</string>
|
||||||
|
<string name="camera_toggle">切换相机</string>
|
||||||
|
<string name="bt_share">蓝牙分享</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user