fix context problems

This commit is contained in:
BinTianqi
2024-01-24 10:23:20 +08:00
parent ecb05b35b6
commit e75a0946db
11 changed files with 177 additions and 66 deletions

View File

@@ -3,7 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/> <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"/> <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS"/> <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"/> <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"/>
@@ -32,8 +31,6 @@
<action android:name="android.app.action.MANAGED_PROFILE_PROVISIONED"/> <action android:name="android.app.action.MANAGED_PROFILE_PROVISIONED"/>
<action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/> <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.INFO"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@@ -12,6 +12,7 @@ import android.net.Uri
import android.os.Build.VERSION import android.os.Build.VERSION
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement 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
@@ -33,6 +34,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
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.content.ContextCompat.startActivity import androidx.core.content.ContextCompat.startActivity
@@ -41,7 +43,10 @@ import java.io.InputStream
@Composable @Composable
fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName,myContext:Context){ fun ApplicationManage(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
var pkgName by remember { mutableStateOf("") } var pkgName by remember { mutableStateOf("") }
Column( Column(
modifier = Modifier modifier = Modifier

View File

@@ -2,9 +2,9 @@ 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.os.Build.VERSION import android.os.Build.VERSION
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement 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
@@ -28,13 +28,17 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
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.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@Composable @Composable
fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myContext: Context){ fun DeviceControl(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
Column( Column(
modifier = Modifier modifier = Modifier
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())

View File

@@ -15,7 +15,9 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
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.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@@ -33,6 +35,7 @@ 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.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -47,14 +50,12 @@ 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 import com.google.accompanist.systemuicontroller.rememberSystemUiController
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val context = applicationContext
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
val adminComponent = ComponentName(context,MyDeviceAdminReceiver::class.java)
setContent { setContent {
val sysUiCtrl = rememberSystemUiController() val sysUiCtrl = rememberSystemUiController()
val useDarkIcon = !isSystemInDarkTheme() val useDarkIcon = !isSystemInDarkTheme()
@@ -63,16 +64,15 @@ class MainActivity : ComponentActivity() {
sysUiCtrl.setNavigationBarColor(Color.Transparent,useDarkIcon) sysUiCtrl.setNavigationBarColor(Color.Transparent,useDarkIcon)
sysUiCtrl.setStatusBarColor(Color.Transparent,useDarkIcon) sysUiCtrl.setStatusBarColor(Color.Transparent,useDarkIcon)
} }
MyScaffold(dpm,adminComponent,context) MyScaffold()
} }
} }
} }
} }
@OptIn(ExperimentalMaterial3Api::class) @ExperimentalMaterial3Api
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable @Composable
fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainContext:Context){ fun MyScaffold(){
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
val navCtrl = rememberNavController() val navCtrl = rememberNavController()
val backStackEntry by navCtrl.currentBackStackEntryAsState() val backStackEntry by navCtrl.currentBackStackEntryAsState()
@@ -83,7 +83,8 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
"UserManage" to R.string.user_manage, "UserManage" to R.string.user_manage,
"ApplicationManage" to R.string.app_manage, "ApplicationManage" to R.string.app_manage,
"UserRestriction" to R.string.user_restrict, "UserRestriction" to R.string.user_restrict,
"Password" to R.string.password "Password" to R.string.password,
"AppSetting" to R.string.setting
) )
val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name
Scaffold( Scaffold(
@@ -128,24 +129,28 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
.padding(top = it.calculateTopPadding()) .padding(top = it.calculateTopPadding())
.imePadding() .imePadding()
){ ){
composable(route = "HomePage", content = { HomePage(navCtrl,mainDpm,mainComponent)}) composable(route = "HomePage", content = { HomePage(navCtrl)})
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent,mainContext)}) composable(route = "DeviceControl", content = { DeviceControl()})
composable(route = "Permissions", content = { DpmPermissions(mainDpm,mainComponent,mainContext,navCtrl)}) composable(route = "Permissions", content = { DpmPermissions(navCtrl)})
composable(route = "ApplicationManage", content = { ApplicationManage(mainDpm,mainComponent,mainContext)}) composable(route = "ApplicationManage", content = { ApplicationManage()})
composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent,mainContext)}) composable(route = "UserRestriction", content = { UserRestriction()})
composable(route = "UserManage", content = { UserManage(mainDpm,mainComponent,mainContext)}) composable(route = "UserManage", content = { UserManage()})
composable(route = "Password", content = { Password(mainDpm,mainComponent,mainContext)}) composable(route = "Password", content = { Password()})
composable(route = "AppSetting", content = { AppSetting()})
} }
} }
} }
@Composable @Composable
fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:ComponentName){ fun HomePage(navCtrl:NavHostController){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
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 activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(isda){"Device Admin"}else{""} val activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(isda){"Device Admin"}else{""}
val isActivated = if(isdo||isda){"已激活"}else{"未激活"} val isActivated = if(isdo||isda){"已激活"}else{"未激活"}
Column { Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -185,6 +190,7 @@ fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:Com
HomePageItem(R.string.user_restrict, R.drawable.manage_accounts_fill0, R.string.user_restrict_desc, "UserRestriction", navCtrl) HomePageItem(R.string.user_restrict, R.drawable.manage_accounts_fill0, R.string.user_restrict_desc, "UserRestriction", navCtrl)
HomePageItem(R.string.user_manage,R.drawable.account_circle_fill0,R.string.user_manage_desc,"UserManage",navCtrl) HomePageItem(R.string.user_manage,R.drawable.account_circle_fill0,R.string.user_manage_desc,"UserManage",navCtrl)
HomePageItem(R.string.password, R.drawable.password_fill0,R.string.security_desc, "Password",navCtrl) HomePageItem(R.string.password, R.drawable.password_fill0,R.string.security_desc, "Password",navCtrl)
HomePageItem(R.string.setting, R.drawable.info_fill0, R.string.setting_desc, "AppSetting",navCtrl)
} }
} }

View File

@@ -4,9 +4,9 @@ import android.app.KeyguardManager
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.FLAG_ACTIVITY_NEW_TASK
import android.os.Build.VERSION import android.os.Build.VERSION
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement 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
@@ -38,6 +38,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
@@ -46,7 +47,10 @@ import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity import androidx.core.content.ContextCompat.startActivity
@Composable @Composable
fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Context){ fun Password(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
var newPwd by remember{ mutableStateOf("") } var newPwd by remember{ mutableStateOf("") }
var confirmed by remember{ mutableStateOf(false) } var confirmed by remember{ mutableStateOf(false) }
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
@@ -151,7 +155,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
}else{ Toast.makeText(myContext, "需要4位数字或字母", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, "需要4位数字或字母", Toast.LENGTH_SHORT).show() }
}, },
modifier = Modifier.padding(end = 10.dp), modifier = Modifier.padding(end = 10.dp),
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm) enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm) || myDpm.isAdminActive(myComponent)
) { ) {
Text("确认密码") Text("确认密码")
} }
@@ -163,7 +167,6 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
confirmed=false confirmed=false
}, },
enabled = confirmed,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError) colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError)
) { ) {
Text("设置密码") Text("设置密码")
@@ -176,6 +179,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
confirmed=false confirmed=false
}, },
enabled = confirmed,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError) colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError)
) { ) {
Text("设置密码") Text("设置密码")
@@ -234,7 +238,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC to "数字字母各至少一个", DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC to "数字字母各至少一个",
DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK to "生物识别(弱)", DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK to "生物识别(弱)",
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX to "复杂数字(无连续性)", DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX to "复杂数字(无连续性)",
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX to "自定义", DevicePolicyManager.PASSWORD_QUALITY_COMPLEX to "自定义(暂不支持)",
).toList() ).toList()
var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) } var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) }
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
@@ -329,7 +333,6 @@ fun activateToken(myContext: Context){
val ACTIVATE_TOKEN_PROMPT = "在这里激活密码重置令牌" val ACTIVATE_TOKEN_PROMPT = "在这里激活密码重置令牌"
val keyguardManager = myContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager val keyguardManager = myContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, ACTIVATE_TOKEN_PROMPT) val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, ACTIVATE_TOKEN_PROMPT)
confirmIntent.setFlags(FLAG_ACTIVITY_NEW_TASK)
if (confirmIntent != null) { if (confirmIntent != null) {
startActivity(myContext,confirmIntent, null) startActivity(myContext,confirmIntent, null)
} else { } else {

View File

@@ -4,9 +4,9 @@ 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.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Build.VERSION import android.os.Build.VERSION
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement 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
@@ -30,6 +30,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
@@ -40,10 +41,12 @@ import androidx.navigation.NavHostController
@Composable @Composable
fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myContext:Context,navCtrl:NavHostController){ fun DpmPermissions(navCtrl:NavHostController){
//da:DeviceAdmin do:DeviceOwner //da:DeviceAdmin do:DeviceOwner
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val isda = myDpm.isAdminActive(myComponent) val isda = myDpm.isAdminActive(myComponent)
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
Column( Column(
modifier = Modifier.verticalScroll(rememberScrollState()), modifier = Modifier.verticalScroll(rememberScrollState()),
@@ -139,9 +142,9 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
) { ) {
Column { Column {
Text(text = "Device Owner", style = MaterialTheme.typography.titleLarge) Text(text = "Device Owner", style = MaterialTheme.typography.titleLarge)
Text(if(isdo){"已激活"}else{"未激活"}) Text(if(isDeviceOwner(myDpm)){"已激活"}else{"未激活"})
} }
if(isdo){ if(isDeviceOwner(myDpm)){
Button( Button(
onClick = { onClick = {
myDpm.clearDeviceOwnerApp("com.binbin.androidowner") myDpm.clearDeviceOwnerApp("com.binbin.androidowner")
@@ -156,14 +159,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
} }
} }
} }
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)){ if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
Text(
text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态",
color = MaterialTheme.colorScheme.onErrorContainer,
modifier = sections(MaterialTheme.colorScheme.errorContainer)
)
}
if(!isdo&&!isProfileOwner(myDpm)){
Column( Column(
modifier = sections(MaterialTheme.colorScheme.tertiaryContainer), modifier = sections(MaterialTheme.colorScheme.tertiaryContainer),
horizontalAlignment = Alignment.Start horizontalAlignment = Alignment.Start
@@ -178,6 +174,13 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
} }
} }
} }
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)){
Text(
text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态",
color = MaterialTheme.colorScheme.onErrorContainer,
modifier = sections(MaterialTheme.colorScheme.errorContainer)
)
}
if(VERSION.SDK_INT>=30){ if(VERSION.SDK_INT>=30){
Column( Column(
modifier = sections() modifier = sections()
@@ -205,7 +208,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
Text("(恢复出厂设置不变)") Text("(恢复出厂设置不变)")
if(specificId!=""){ if(specificId!=""){
Text(specificId) Text(specificId)
Button(onClick = {myDpm.setOrganizationId(specificId)}, enabled = specificId!="") { Button(onClick = {myDpm.setOrganizationId(specificId)}) {
Text("设置为组织ID") Text("设置为组织ID")
} }
}else{ }else{
@@ -259,7 +262,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
} }
} }
if(isdo&&VERSION.SDK_INT>=24){ if(isDeviceOwner(myDpm)&&VERSION.SDK_INT>=24){
DeviceOwnerInfo(R.string.owner_lockscr_info,R.string.place_holder,R.string.owner_lockscr_info,focusManager,myContext, DeviceOwnerInfo(R.string.owner_lockscr_info,R.string.place_holder,R.string.owner_lockscr_info,focusManager,myContext,
{myDpm.deviceOwnerLockScreenInfo},{content -> myDpm.setDeviceOwnerLockScreenInfo(myComponent,content)}) {myDpm.deviceOwnerLockScreenInfo},{content -> myDpm.setDeviceOwnerLockScreenInfo(myComponent,content)})
DeviceOwnerInfo(R.string.support_msg,R.string.support_msg_desc,R.string.message,focusManager,myContext, DeviceOwnerInfo(R.string.support_msg,R.string.support_msg_desc,R.string.message,focusManager,myContext,
@@ -326,6 +329,5 @@ fun activateDeviceAdmin(inputContext:Context,inputComponent:ComponentName){
val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN) val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, inputComponent) intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, inputComponent)
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "在这里激活Android Owner") intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "在这里激活Android Owner")
intent.setFlags(FLAG_ACTIVITY_NEW_TASK)
startActivity(inputContext,intent,null) startActivity(inputContext,intent,null)
} }

View File

@@ -0,0 +1,78 @@
package com.binbin.androidowner
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
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
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun AppSetting(){
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
val myContext = LocalContext.current
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 4.dp)
.clip(RoundedCornerShape(14.dp))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(vertical = 6.dp)
) {
Column(
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 12.dp)
) {
Text(text = "Android owner", style = MaterialTheme.typography.headlineMedium, color = MaterialTheme.colorScheme.onPrimaryContainer)
Text(text = "使用安卓的Device admin、Device owner 、Profile owner全方位掌控你的设备")
Spacer(Modifier.padding(vertical = 4.dp))
Text("这个应用只在AOSP和LineageOS上测试过不确保每个功能都在其它系统可用尤其是国内的魔改系统。")
}
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable { shareLink(myContext, "https://github.com/BinTianqi/AndroidOwner") }
.padding(start = 8.dp, bottom = 4.dp)
) {
Icon(
painter = painterResource(id = R.drawable.open_in_new),
contentDescription = null,
modifier = Modifier.padding(start = 6.dp, end = 8.dp),
tint = MaterialTheme.colorScheme.primary
)
Column {
Text(text = "源代码", fontSize = 18.sp, fontWeight = FontWeight.SemiBold)
Text(text = "https://github.com/BinTianqi/AndroidOwner", color = MaterialTheme.colorScheme.onPrimaryContainer)
Text(text = "欢迎提交issue、给小星星")
}
}
}
}
}
fun shareLink(inputContext:Context,link:String){
val uri = Uri.parse(link)
val intent = Intent(Intent.ACTION_VIEW, uri)
inputContext.startActivity(Intent.createChooser(intent, "Hello"),null)
}

View File

@@ -4,12 +4,11 @@ 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.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.UserHandle import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
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.Spacer import androidx.compose.foundation.layout.Spacer
@@ -29,19 +28,23 @@ 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.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity
import androidx.core.os.UserManagerCompat import androidx.core.os.UserManagerCompat
@Composable @Composable
fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Context){ fun UserManage(){
Column( Column(
modifier = Modifier.verticalScroll(rememberScrollState()) modifier = Modifier.verticalScroll(rememberScrollState())
) { ) {
//val myUM = myContext.getSystemService(Context.USER_SERVICE) //val myUM = myContext.getSystemService(Context.USER_SERVICE)
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val focusMgr = LocalFocusManager.current
val currentUser = android.os.Process.myUserHandle() val currentUser = android.os.Process.myUserHandle()
val userList = Test.returnUsers(myContext) val userList = Test.returnUsers(myContext)
Column(modifier = sections()) { Column(modifier = sections()) {
@@ -108,7 +111,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
) { ) {
Text("移除用户") Text("移除用户")
} }
Button(onClick = { createWorkProfile(myContext,myComponent) }) { Button(onClick = { createWorkProfile(myContext)}) {
Text("创建工作资料") Text("创建工作资料")
} }
Text("可能无法创建工作资料") Text("可能无法创建工作资料")
@@ -135,7 +138,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
var newUserHandle: UserHandle? by remember{ mutableStateOf(null) } var newUserHandle: UserHandle? by remember{ mutableStateOf(null) }
Row { Row {
Button( Button(
onClick = {newUserHandle=myDpm.createAndManageUser(myComponent,userName,myComponent,null,selectedFlag)}, onClick = {newUserHandle=myDpm.createAndManageUser(myComponent,userName,myComponent,null,selectedFlag);focusMgr.clearFocus()},
enabled = isDeviceOwner(myDpm) enabled = isDeviceOwner(myDpm)
) { ) {
Text("创建") Text("创建")
@@ -232,20 +235,17 @@ fun userOperationResultCode(result:Int): String {
} }
} }
private fun createWorkProfile(myContext: Context,myComponent: ComponentName) { private fun createWorkProfile(myContext: Context) {
val intent = Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) val intent = Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE)
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, "com.binbin.androidowner") intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, ComponentName(myContext,MyDeviceAdminReceiver::class.java))
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, myComponent) intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, myContext.packageName)
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) { if (VERSION.SDK_INT >= 33) { intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE,true) }
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE, true)
}
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"hello") intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"hello")
/* myContext.startActivity(intent)
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_CONSENT, false) }
val adminExtras = PersistableBundle()
if (adminExtras.size() > 0) { private fun createManagedDevice(myContext: Context) {
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtras) val intent = Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE)
}*/ intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, ComponentName(myContext,MyDeviceAdminReceiver::class.java))
intent.setFlags(FLAG_ACTIVITY_NEW_TASK) myContext.startActivity(intent)
startActivity(myContext,intent,null)
} }

View File

@@ -6,6 +6,7 @@ import android.content.Context
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.UserManager import android.os.UserManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -31,6 +32,7 @@ import androidx.compose.runtime.setValue
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.platform.LocalContext
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.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -45,7 +47,10 @@ private data class Restriction(
@Composable @Composable
fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName,myContext: Context){ fun UserRestriction(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
var internetVisible by remember{ mutableStateOf(false) } var internetVisible by remember{ mutableStateOf(false) }
var connectivityVisible by remember{ mutableStateOf(false) } var connectivityVisible by remember{ mutableStateOf(false) }
var applicationVisible by remember{ mutableStateOf(false) } var applicationVisible by remember{ mutableStateOf(false) }

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h280v80L200,200v560h560v-280h80v280q0,33 -23.5,56.5T760,840L200,840ZM388,628 L332,572 704,200L560,200v-80h280v280h-80v-144L388,628Z"/>
</vector>

View File

@@ -128,4 +128,6 @@
<string name="disable_keyguard">禁止锁屏(需无密码)</string> <string name="disable_keyguard">禁止锁屏(需无密码)</string>
<string name="user_manage">用户管理</string> <string name="user_manage">用户管理</string>
<string name="user_manage_desc">查看用户状态,添加用户</string> <string name="user_manage_desc">查看用户状态,添加用户</string>
<string name="setting">设置</string>
<string name="setting_desc">关于此应用</string>
</resources> </resources>