Skip to content

Commit

Permalink
Add security section, backward compatible to API23
Browse files Browse the repository at this point in the history
  • Loading branch information
BinTianqi committed Jan 18, 2024
1 parent 0a60aff commit 587a14d
Show file tree
Hide file tree
Showing 12 changed files with 357 additions and 78 deletions.
6 changes: 3 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ android {

defaultConfig {
applicationId = "com.binbin.androidowner"
minSdk = 26
minSdk = 23
targetSdk = 34
versionCode = 2
versionName = "1.1"
versionCode = 3
versionName = "1.2"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand Down
65 changes: 51 additions & 14 deletions app/src/main/java/com/binbin/androidowner/ApplicationManage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager.NameNotFoundException
import android.net.Uri
import android.os.Build.VERSION
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -28,6 +31,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity


@Composable
Expand All @@ -47,32 +51,46 @@ fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName,myCon
},
label = { Text("包名") }
)
val isSuspended = {
try{
myDpm.isPackageSuspended(myComponent,pkgName)
}catch(e:NameNotFoundException){
false
if(VERSION.SDK_INT>=24){
val isSuspended = {
try{
myDpm.isPackageSuspended(myComponent,pkgName)
}catch(e:NameNotFoundException){
false
}
}
AppManageItem(R.string.suspend,R.string.place_holder,myDpm, isSuspended,
{b -> myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName) ,b)})
}
AppManageItem(R.string.hide,R.string.isapphidden_desc,myDpm, {myDpm.isApplicationHidden(myComponent,pkgName)},
{b -> myDpm.setApplicationHidden(myComponent,pkgName,b)})
AppManageItem(R.string.suspend,R.string.place_holder,myDpm, isSuspended,
{b -> myDpm.setPackagesSuspended(myComponent, arrayOf(pkgName) ,b)})
/*AppManageItem(R.string.block_unins,R.string.sometimes_not_avaliable,myDpm, {myDpm.isUninstallBlocked(myComponent,pkgName)},
if(VERSION.SDK_INT>=30){
AppManageItem(R.string.user_ctrl_disabled,R.string.user_ctrl_disabled_desc,myDpm, {pkgName in myDpm.getUserControlDisabledPackages(myComponent)},
{b->myDpm.setUserControlDisabledPackages(myComponent, mutableListOf(if(b){pkgName}else{null}))})
}
/*AppManageItem(R.string.block_unins,R.string.sometimes_not_available,myDpm, {myDpm.isUninstallBlocked(myComponent,pkgName)},
{b -> myDpm.setUninstallBlocked(myComponent,pkgName,b)})*/
Text("因为无法获取某个应用是否防卸载,无法使用开关控制防卸载")
Row {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(8.dp),
horizontalArrangement = Arrangement.SpaceAround
) {
Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,false)}) {
Text("取消防卸载")
}
Spacer(Modifier.padding(horizontal = 2.dp))
Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,true)}) {
Text("防卸载")
}
}
if(VERSION.SDK_INT>=30){
AppManageItem(R.string.user_ctrl_disabled,R.string.user_ctrl_disabled_desc,myDpm, {pkgName in myDpm.getUserControlDisabledPackages(myComponent)},
{b->myDpm.setUserControlDisabledPackages(myComponent, mutableListOf(if(b){pkgName}else{null}))})
Button(
onClick = {
uninstallApp(myContext,pkgName)
}) {
Text("卸载")
}
Spacer(Modifier.padding(5.dp))
}
Expand Down Expand Up @@ -119,3 +137,22 @@ private fun AppManageItem(
)
}
}

fun uninstallPkg(pkgName:String,myContext:Context){
val packageManager = myContext.packageManager
try {
val packageInfo = packageManager.getPackageInfo(pkgName, 0)
val intent = Intent(Intent.ACTION_DELETE)
intent.setData(Uri.parse("package:" + packageInfo.packageName))
startActivity(myContext,intent,null)
} catch (e: NameNotFoundException) {
Toast.makeText(myContext, "应用未安装", Toast.LENGTH_SHORT).show()
}
}

private fun uninstallApp(context: Context, packageName: String) {
val packageUri = Uri.parse("package:$packageName")
val uninstallIntent = Intent(Intent.ACTION_DELETE, packageUri)
uninstallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(uninstallIntent)
}
38 changes: 26 additions & 12 deletions app/src/main/java/com/binbin/androidowner/DeviceControl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ import androidx.compose.ui.unit.dp
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
val wifimac = try {
myDpm.getWifiMacAddress(myComponent).toString()
}catch(e:SecurityException){
"没有权限"
}
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
Expand All @@ -54,16 +49,35 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
DeviceCtrlItem(R.string.auto_timezone,R.string.place_holder,myDpm,{myDpm.getAutoTimeZoneEnabled(myComponent)},{b -> myDpm.setAutoTimeZoneEnabled(myComponent,b) })
}
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("重启")
if(VERSION.SDK_INT>=26){
DeviceCtrlItem(R.string.backup_service,R.string.place_holder,myDpm,{myDpm.isBackupServiceEnabled(myComponent)},{b -> myDpm.setBackupServiceEnabled(myComponent,b) })
}
if(VERSION.SDK_INT>=24){
Button(onClick = {myDpm.reboot(myComponent)}) {
Text("重启")
}
val wifimac = try {
myDpm.getWifiMacAddress(myComponent).toString()
}catch(e:SecurityException){
"没有权限"
}
Text("WiFi MAC: $wifimac")
}
if(VERSION.SDK_INT<24){
Text("重启和WiFi Mac需要API24")
}
if(VERSION.SDK_INT<26){
Text("备份服务需要API26")
}
if(VERSION.SDK_INT<30){
Text("自动设置时间和自动设置时区需要API30")
}
if(VERSION.SDK_INT<34){
Text("隐藏状态栏需要API34")
}
Button(onClick = {myDpm.lockNow()}) {
Text("锁屏")
}
Text("WiFi MAC: $wifimac")
Text("以下功能需要长按按钮,作者并未测试")
Button(
onClick = {},
Expand All @@ -76,7 +90,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName){
) {
Text("WipeData")
}
if (VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
if (VERSION.SDK_INT >= 34) {
Button(
modifier = Modifier
.combinedClickable(onClick = {}, onLongClick = {myDpm.wipeDevice(0)}),
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/com/binbin/androidowner/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
"Permissions" to R.string.permission,
"UIControl" to R.string.ui_ctrl,
"ApplicationManage" to R.string.app_manage,
"UserRestriction" to R.string.user_restrict
"UserRestriction" to R.string.user_restrict,
"Security" to R.string.security
)
val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name
Scaffold(
Expand Down Expand Up @@ -125,13 +126,16 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon
NavHost(
navController = navCtrl,
startDestination = "HomePage",
modifier = Modifier.padding(top = it.calculateTopPadding()).navigationBarsPadding()
modifier = Modifier
.padding(top = it.calculateTopPadding())
.navigationBarsPadding()
){
composable(route = "HomePage", content = { HomePage(navCtrl,mainDpm,mainComponent)})
composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent)})
composable(route = "Permissions", content = { DpmPermissions(mainDpm,mainComponent,mainContext,navCtrl)})
composable(route = "ApplicationManage", content = { ApplicationManage(mainDpm,mainComponent,mainContext)})
composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent)})
composable(route = "Security", content = { Security(mainDpm,mainComponent,mainContext)})
}
}
}
Expand Down Expand Up @@ -174,10 +178,10 @@ fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:Com
)
}
}
//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.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)
HomePageItem(R.string.security, R.drawable.security_fill0,R.string.security_desc, "Security",navCtrl)
}
}

Expand Down
18 changes: 8 additions & 10 deletions app/src/main/java/com/binbin/androidowner/Permissions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.provider.Settings.Global
import android.os.Build.VERSION
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -30,7 +30,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.core.app.ActivityCompat.startActivityForResult
import androidx.core.content.ContextCompat.startActivity
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
Expand Down Expand Up @@ -130,16 +129,15 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
Text("使用此命令也会激活Device Admin")
}
}
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信息")
}
}
if(isdo&&VERSION.SDK_INT>=24){
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信息")
}
}

}
}

Expand Down
Loading

0 comments on commit 587a14d

Please sign in to comment.