diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9107b5a..05dac6e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,6 +11,8 @@
+
+
=28&&isDeviceOwner(myDpm)){
+ Column(modifier = sections()){
+ val lockTaskPolicyList = mutableListOf(
+ LOCK_TASK_FEATURE_NONE,
+ LOCK_TASK_FEATURE_SYSTEM_INFO,
+ LOCK_TASK_FEATURE_NOTIFICATIONS,
+ LOCK_TASK_FEATURE_HOME,
+ LOCK_TASK_FEATURE_OVERVIEW,
+ LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
+ LOCK_TASK_FEATURE_KEYGUARD
+ )
+ var sysInfo by remember{mutableStateOf(false)}
+ var notifications by remember{mutableStateOf(false)}
+ var home by remember{mutableStateOf(false)}
+ var overview by remember{mutableStateOf(false)}
+ var globalAction by remember{mutableStateOf(false)}
+ var keyGuard by remember{mutableStateOf(false)}
+ var blockAct by remember{mutableStateOf(false)}
+ if(VERSION.SDK_INT>=30){lockTaskPolicyList.add(LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK)}
+ val refreshFeature = {
+ var calculate = myDpm.getLockTaskFeatures(myComponent)
+ if(VERSION.SDK_INT>=30&&calculate-lockTaskPolicyList[7]>=0){blockAct=true;calculate-=lockTaskPolicyList[7]}
+ if(calculate-lockTaskPolicyList[6]>=0){keyGuard=true;calculate-=lockTaskPolicyList[6]}
+ if(calculate-lockTaskPolicyList[5]>=0){globalAction=true;calculate-=lockTaskPolicyList[5]}
+ if(calculate-lockTaskPolicyList[4]>=0){overview=true;calculate-=lockTaskPolicyList[4]}
+ if(calculate-lockTaskPolicyList[3]>=0){home=true;calculate-=lockTaskPolicyList[3]}
+ if(calculate-lockTaskPolicyList[2]>=0){notifications=true;calculate-=lockTaskPolicyList[2]}
+ if(calculate-lockTaskPolicyList[1]>=0){sysInfo=true;calculate-=lockTaskPolicyList[1]}
+ }
+ Text(text = "锁定任务模式", style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
+ var inited by remember{mutableStateOf(false)}
+ var custom by remember{mutableStateOf(false)}
+ if(!inited){ refreshFeature();custom=myDpm.getLockTaskFeatures(myComponent)!=0;inited=true }
+ Text(text = "在锁定任务模式下:", style = bodyTextStyle)
+ RadioButtonItem("禁用全部",{!custom},{custom=false})
+ RadioButtonItem("自定义",{custom},{custom=true})
+ AnimatedVisibility(custom) {
+ Column {
+ CheckBoxItem("允许状态栏信息",{sysInfo},{sysInfo=!sysInfo})
+ CheckBoxItem("允许通知",{notifications},{notifications=!notifications})
+ CheckBoxItem("允许返回主屏幕",{home},{home=!home})
+ CheckBoxItem("允许打开后台应用概览",{overview},{overview=!overview})
+ CheckBoxItem("允许全局行为(比如长按电源键对话框)",{globalAction},{globalAction=!globalAction})
+ CheckBoxItem("允许锁屏(如果没有选择此项,即使有密码也不会锁屏)",{keyGuard},{keyGuard=!keyGuard})
+ if(VERSION.SDK_INT>=30){ CheckBoxItem("阻止启动未允许的应用",{blockAct},{blockAct=!blockAct}) }
+ }
+ }
+ Button(
+ modifier = Modifier.fillMaxWidth(),
+ onClick = {
+ var result = lockTaskPolicyList[0]
+ if(custom){
+ if(blockAct&&VERSION.SDK_INT>=30){result+=lockTaskPolicyList[7]}
+ if(keyGuard){result+=lockTaskPolicyList[6]}
+ if(globalAction){result+=lockTaskPolicyList[5]}
+ if(overview){result+=lockTaskPolicyList[4]}
+ if(home){result+=lockTaskPolicyList[3]}
+ if(notifications){result+=lockTaskPolicyList[2]}
+ if(sysInfo){result+=lockTaskPolicyList[1]}
+ }
+ myDpm.setLockTaskFeatures(myComponent,result)
+ refreshFeature()
+ Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
+ }
+ ) {
+ Text("应用")
+ }
+ Spacer(Modifier.padding(vertical = 4.dp))
+ val whitelist = myDpm.getLockTaskPackages(myComponent).toMutableList()
+ var listText by remember{mutableStateOf("")}
+ var inputPkg by remember{mutableStateOf("")}
+ val refreshWhitelist = {
+ listText=""
+ var currentItem = whitelist.size
+ for(each in whitelist){
+ currentItem-=1
+ listText += each
+ if(currentItem>0){listText += "\n"}
+ }
+ }
+ refreshWhitelist()
+ Text(text = "白名单应用", style = typography.titleLarge)
+ if(listText!=""){ Text(listText) }else{ Text(("无")) }
+ TextField(
+ value = inputPkg,
+ onValueChange = {inputPkg=it},
+ label = {Text("包名")},
+ keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
+ keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
+ modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
+ )
+ Button(
+ onClick = {
+ whitelist.add(inputPkg)
+ myDpm.setLockTaskPackages(myComponent,whitelist.toTypedArray())
+ Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
+ refreshWhitelist()
+ },
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text("加入白名单")
+ }
+ Button(
+ onClick = {
+ if(inputPkg in whitelist){
+ whitelist.remove(inputPkg)
+ myDpm.setLockTaskPackages(myComponent,whitelist.toTypedArray())
+ Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
+ }else{
+ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show()
+ }
+ refreshWhitelist()
+ },
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text("从白名单中移除")
+ }
+ }
+ }
+
if(VERSION.SDK_INT>=29&&isDeviceOwner(myDpm)){
Column(modifier = sections()){
Text(text = "私人DNS", style = typography.titleLarge)
@@ -245,6 +366,8 @@ fun DeviceControl(){
Toast.makeText(myContext, operationResult[result], Toast.LENGTH_SHORT).show()
}catch(e:IllegalArgumentException){
Toast.makeText(myContext, "无效主机名", Toast.LENGTH_SHORT).show()
+ }catch(e:SecurityException){
+ Toast.makeText(myContext, "安全错误", Toast.LENGTH_SHORT).show()
}finally {
status = dnsStatus[myDpm.getGlobalPrivateDnsMode(myComponent)]
}
diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt
index 024917f..3673779 100644
--- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt
+++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt
@@ -4,9 +4,13 @@ import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
+import android.content.Intent
+import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -34,12 +38,21 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
+/*lateinit var getOtaPackage: ActivityResultLauncher
+var installOta = false
+lateinit var otaUri:Uri*/
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
+ /*otaUri = Uri.EMPTY
+ getOtaPackage = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ val data = it.data?.data
+ installOta = true
+ otaUri = data ?: Uri.EMPTY
+ }*/
setContent {
AndroidOwnerTheme {
MyScaffold()
diff --git a/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt
index 6e481c6..c21545d 100644
--- a/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt
+++ b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt
@@ -1,9 +1,12 @@
package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback
import android.app.admin.SystemUpdateInfo
import android.app.admin.SystemUpdatePolicy
import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
import android.os.Build.VERSION
import android.widget.Toast
import androidx.activity.ComponentActivity
@@ -23,6 +26,7 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import java.util.Date
+import java.util.concurrent.Executors
@Composable
fun SysUpdatePolicy(){
@@ -30,21 +34,24 @@ fun SysUpdatePolicy(){
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val focusMgr = LocalFocusManager.current
+ val sharedPref = myContext.getSharedPreferences("data", Context.MODE_PRIVATE)
+ val isWear = sharedPref.getBoolean("isWear",false)
+ val bodyTextStyle = if(isWear){ typography.bodyMedium}else{typography.bodyLarge}
Column {
- if(VERSION.SDK_INT>=26){
+ if(VERSION.SDK_INT>=26&&isDeviceOwner(myDpm)){
+ val sysUpdateInfo = myDpm.getPendingSystemUpdate(myComponent)
Column(modifier = sections()) {
- val sysUpdateInfo = if(isDeviceOwner(myDpm)){myDpm.getPendingSystemUpdate(myComponent)}else{null}
if(sysUpdateInfo!=null){
- Text("Update first available: ${Date(sysUpdateInfo.receivedTime)}")
- Text("Hash code: ${sysUpdateInfo.hashCode()}")
+ Text(text = "Update first available: ${Date(sysUpdateInfo.receivedTime)}", style = bodyTextStyle)
+ Text(text = "Hash code: ${sysUpdateInfo.hashCode()}", style = bodyTextStyle)
val securityStateDesc = when(sysUpdateInfo.securityPatchState){
SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN->"SECURITY_PATCH_STATE_UNKNOWN"
SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE->"SECURITY_PATCH_STATE_TRUE"
else->"SECURITY_PATCH_STATE_FALSE"
}
- Text("Security patch state: $securityStateDesc")
+ Text(text = "Security patch state: $securityStateDesc", style = bodyTextStyle)
}else{
- Text("暂无更新信息")
+ Text(text = "暂无系统更新", style = bodyTextStyle)
}
}
}
@@ -80,7 +87,7 @@ fun SysUpdatePolicy(){
)
}
Spacer(Modifier.padding(vertical = 3.dp))
- Text("请输入一天中的分钟(0~1440)")
+ Text(text = "请输入一天中的分钟(0~1440)", style = bodyTextStyle)
}
val policy =
when(selectedPolicy){
@@ -97,5 +104,43 @@ fun SysUpdatePolicy(){
Text("应用")
}
}}
+ /*if(VERSION.SDK_INT>=29){
+ Column(modifier = sections()){
+ var resultUri by remember{mutableStateOf(otaUri)}
+ Text(text = "安装系统更新", style = typography.titleLarge)
+ Button(
+ onClick = {
+ val getUri = Intent(Intent.ACTION_GET_CONTENT)
+ getUri.setType("application/zip")
+ getUri.addCategory(Intent.CATEGORY_OPENABLE)
+ getOtaPackage.launch(getUri)
+ },
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm)
+ ) {
+ Text("选择OTA包")
+ }
+ Button(
+ onClick = {resultUri = otaUri},
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm)
+ ) {
+ Text("查看OTA包详情")
+ }
+ Text("URI: $resultUri")
+ if(installOta){
+ Button(
+ onClick = {
+ val sysUpdateExecutor = Executors.newCachedThreadPool()
+ val sysUpdateCallback:InstallSystemUpdateCallback = InstallSystemUpdateCallback
+ myDpm.installSystemUpdate(myComponent,resultUri,sysUpdateExecutor,sysUpdateCallback)
+ },
+ enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm)
+ ){
+ Text("安装")
+ }
+ }
+ }
+ }*/
}
}