optimize activate and deactivate logic

This commit is contained in:
BinTianqi
2024-05-02 17:01:25 +08:00
parent 83a924378d
commit 3d09eb958b
6 changed files with 135 additions and 146 deletions

View File

@@ -1,74 +1,46 @@
package com.bintianqi.owndroid
import android.annotation.SuppressLint
import android.app.admin.DeviceAdminReceiver
import android.app.admin.DevicePolicyManager
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInstaller.*
import android.os.Build.VERSION
import android.os.PersistableBundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import com.bintianqi.owndroid.dpm.isDeviceOwner
import com.bintianqi.owndroid.dpm.isProfileOwner
class Receiver : DeviceAdminReceiver() {
override fun onEnabled(context: Context, intent: Intent) {
super.onEnabled(context, intent)
Toast.makeText(context, "已启用", Toast.LENGTH_SHORT).show()
val myDpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(context, this::class.java)
if(myDpm.isAdminActive(myComponent)||isProfileOwner(myDpm)||isDeviceOwner(myDpm)){
Toast.makeText(context, context.getString(R.string.onEnabled), Toast.LENGTH_SHORT).show()
if(myDpm.isAdminActive(myComponent)&&!isProfileOwner(myDpm)&&!isDeviceOwner(myDpm)){ backToHome=true }
}
}
override fun onTransferOwnershipComplete(context: Context, bundle: PersistableBundle?) {
super.onTransferOwnershipComplete(context, bundle)
if(bundle!=null){
Toast.makeText(context,"转移所有权完毕,附加内容长度:${bundle.size()}",Toast.LENGTH_SHORT).show()
Log.d("TransferOwnerShip",bundle.toString())
}else{
Toast.makeText(context,"转移所有权完毕,无附加内容}",Toast.LENGTH_SHORT).show()
}
override fun onDisabled(context: Context, intent: Intent) {
super.onDisabled(context, intent)
Toast.makeText(context, context.getString(R.string.onDisabled), Toast.LENGTH_SHORT).show()
}
override fun onProfileProvisioningComplete(context: Context, intent: Intent) {
super.onProfileProvisioningComplete(context, intent)
Toast.makeText(context, "创建工作资料完成", Toast.LENGTH_SHORT).show()
Toast.makeText(context, context.getString(R.string.create_work_profile_success), Toast.LENGTH_SHORT).show()
}
@SuppressLint("UnsafeProtectedBroadcastReceiver")
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
}
override fun onNetworkLogsAvailable(context: Context, intent: Intent, batchToken: Long, networkLogsCount: Int) {
super.onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount)
Toast.makeText(context,"可以收集网络日志",Toast.LENGTH_SHORT).show()
Log.e("","网络日志可用")
}
override fun onSecurityLogsAvailable(context: Context, intent: Intent) {
super.onSecurityLogsAvailable(context, intent)
Toast.makeText(context,"可以收集安全日志",Toast.LENGTH_SHORT).show()
Log.e("","安全日志可用")
}
override fun onDisableRequested(context: Context, intent: Intent): CharSequence {
Toast.makeText(context, "撤销授权", Toast.LENGTH_SHORT).show()
return "这是取消时的提示"
}
override fun onDisabled(context: Context, intent: Intent) {
super.onDisabled(context, intent)
Toast.makeText(context, "已禁用", Toast.LENGTH_SHORT).show()
}
override fun onSystemUpdatePending(context: Context, intent: Intent, receivedTime: Long) {
if (VERSION.SDK_INT < 26) { return }
Toast.makeText(context, "新的系统更新!", Toast.LENGTH_SHORT).show()
}
}
class PackageInstallerReceiver:BroadcastReceiver(){
override fun onReceive(context: Context, intent: Intent) {
val toastText = when(intent.getIntExtra(EXTRA_STATUS,666)){
STATUS_PENDING_USER_ACTION->"等待用户交互"
STATUS_SUCCESS->"成功"
STATUS_FAILURE->"失败"
STATUS_SUCCESS->context.getString(R.string.success)
STATUS_FAILURE->context.getString(R.string.fail)
STATUS_FAILURE_BLOCKED->"失败:被阻止"
STATUS_FAILURE_ABORTED->"失败:被打断"
STATUS_FAILURE_INVALID->"失败:无效"
@@ -76,8 +48,8 @@ class PackageInstallerReceiver:BroadcastReceiver(){
STATUS_FAILURE_STORAGE->"失败:空间不足"
STATUS_FAILURE_INCOMPATIBLE->"失败:不兼容"
STATUS_FAILURE_TIMEOUT->"失败:超时"
else->"未知"
else->context.getString(R.string.unknown)
}
Log.e("静默安装","${intent.getIntExtra(EXTRA_STATUS,666)}:$toastText")
Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show()
}
}

View File

@@ -53,14 +53,6 @@ fun Set<Any>.toText():String{
fun writeClipBoard(context: Context, string: String):Boolean{
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
try {
if(VERSION.SDK_INT>=23){
val hasPermission: Boolean = clipboardManager.hasPrimaryClip()
if(!hasPermission) {
val intent = Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS)
intent.setData(Uri.parse("package:"+context.packageName))
startActivity(context,intent,null)
}
}
clipboardManager.setPrimaryClip(ClipData.newPlainText("", string))
}catch(e:Exception){
return false

View File

@@ -9,6 +9,7 @@ import android.content.Intent
import android.os.Build.VERSION
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions
@@ -191,34 +192,34 @@ private fun DeviceAdmin(navCtrl: NavHostController){
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,Receiver::class.java)
val co = rememberCoroutineScope()
var showDeactivateButton by remember{mutableStateOf(myDpm.isAdminActive(myComponent))}
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.device_admin), style = typography.headlineLarge)
Text(text = stringResource(if(myDpm.isAdminActive(myComponent)) { R.string.activated } else { R.string.deactivated }), style = typography.titleLarge)
Spacer(Modifier.padding(vertical = 5.dp))
if(myDpm.isAdminActive(myComponent)) {
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)) {
Button(
onClick = {
myDpm.removeActiveAdmin(myComponent)
co.launch{ delay(600); if(!myDpm.isAdminActive(myComponent)){navCtrl.navigateUp()} }
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError)
) {
Text(stringResource(R.string.deactivate))
}
}
} else {
Button(onClick = {activateDeviceAdmin(myContext, myComponent)}, modifier = Modifier.fillMaxWidth()) {
Text(stringResource(R.string.activate))
AnimatedVisibility(showDeactivateButton) {
Button(
onClick = {
myDpm.removeActiveAdmin(myComponent)
co.launch{ delay(400); showDeactivateButton=myDpm.isAdminActive(myComponent) }
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError)
) {
Text(stringResource(R.string.deactivate))
}
}
Spacer(Modifier.padding(vertical = 5.dp))
if(!myDpm.isAdminActive(myComponent)) {
SelectionContainer {
Text(text = stringResource(R.string.activate_device_admin_command))
AnimatedVisibility(!showDeactivateButton) {
Column {
Button(onClick = {activateDeviceAdmin(myContext, myComponent)}, modifier = Modifier.fillMaxWidth()) {
Text(stringResource(R.string.activate_jump))
}
Spacer(Modifier.padding(vertical = 5.dp))
SelectionContainer {
Text(text = stringResource(R.string.activate_device_admin_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_device_admin_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_device_admin_command))
}
}
}
@@ -228,28 +229,33 @@ private fun ProfileOwner(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,Receiver::class.java)
var showDeactivateButton by remember{mutableStateOf(isProfileOwner(myDpm))}
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.profile_owner), style = typography.headlineLarge)
Text(stringResource(if(isProfileOwner(myDpm)){R.string.activated}else{R.string.deactivated}), style = typography.titleLarge)
Spacer(Modifier.padding(vertical = 5.dp))
if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24){
val co = rememberCoroutineScope()
Button(
onClick = {
myDpm.clearProfileOwner(myComponent)
co.launch { delay(600); if(!isProfileOwner(myDpm)){ backToHome=true } }
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError)
) {
Text(stringResource(R.string.deactivate))
if(VERSION.SDK_INT>=24){
AnimatedVisibility(showDeactivateButton) {
val co = rememberCoroutineScope()
Button(
onClick = {
myDpm.clearProfileOwner(myComponent)
co.launch { delay(400); showDeactivateButton=isProfileOwner(myDpm) }
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError)
) {
Text(stringResource(R.string.deactivate))
}
}
}
if(!isProfileOwner(myDpm)){
SelectionContainer{
Text(text = stringResource(R.string.activate_profile_owner_command))
AnimatedVisibility(!showDeactivateButton) {
Column {
SelectionContainer{
Text(text = stringResource(R.string.activate_profile_owner_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_profile_owner_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_profile_owner_command))
}
}
}
@@ -259,27 +265,30 @@ private fun DeviceOwner(navCtrl: NavHostController){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val co = rememberCoroutineScope()
var showDeactivateButton by remember{mutableStateOf(isDeviceOwner(myDpm))}
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.device_owner), style = typography.headlineLarge)
Text(text = stringResource(if(isDeviceOwner(myDpm)){R.string.activated}else{R.string.deactivated}), style = typography.titleLarge)
Spacer(Modifier.padding(vertical = 5.dp))
if(isDeviceOwner(myDpm)){
AnimatedVisibility(showDeactivateButton) {
Button(
onClick = {
myDpm.clearDeviceOwnerApp(myContext.packageName)
co.launch{ delay(600); if(!isDeviceOwner(myDpm)){ backToHome=true } }
co.launch{ delay(400); showDeactivateButton=isDeviceOwner(myDpm) }
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError)
) {
Text(text = stringResource(R.string.deactivate))
}
}
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
SelectionContainer{
Text(text = stringResource(R.string.activate_device_owner_command))
AnimatedVisibility(!showDeactivateButton) {
Column {
SelectionContainer{
Text(text = stringResource(R.string.activate_device_owner_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_device_owner_command))
}
CopyTextButton(myContext, R.string.copy_command, stringResource(R.string.activate_device_owner_command))
}
}
}

View File

@@ -32,7 +32,6 @@ import androidx.compose.ui.unit.dp
import com.bintianqi.owndroid.IUserService
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.Receiver
import com.bintianqi.owndroid.backToHome
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import rikka.shizuku.Shizuku
@@ -49,6 +48,10 @@ fun ShizukuActivate(){
var enabled by remember{ mutableStateOf(false) }
var bindShizuku by remember{ mutableStateOf(false) }
var outputText by remember{mutableStateOf("")}
var showDeviceAdminButton by remember{mutableStateOf(!myDpm.isAdminActive(myComponent))}
var showProfileOwnerButton by remember{mutableStateOf(!isProfileOwner(myDpm))}
var showDeviceOwnerButton by remember{mutableStateOf(!isDeviceOwner(myDpm))}
var showOrgProfileOwnerButton by remember{mutableStateOf(true)}
LaunchedEffect(Unit){
if(service==null){userServiceControl(myContext, true)}
while(true){
@@ -104,59 +107,58 @@ fun ShizukuActivate(){
}
Spacer(Modifier.padding(vertical = 5.dp))
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
Column {
if(!myDpm.isAdminActive(myComponent)){
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_da_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(600)
if(myDpm.isAdminActive(myComponent)){backToHome=true}
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_device_admin))
AnimatedVisibility(showDeviceAdminButton&&showProfileOwnerButton&&showDeviceOwnerButton) {
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_da_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(500)
showDeviceAdminButton = !myDpm.isAdminActive(myComponent)
}
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_device_admin))
}
}
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_po_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(600)
if(isProfileOwner(myDpm)){backToHome=true}
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_profile_owner))
}
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_do_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(600)
if(isDeviceOwner(myDpm)){backToHome=true}
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_device_owner))
}
AnimatedVisibility(showProfileOwnerButton&&showDeviceOwnerButton) {
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_po_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(600)
showProfileOwnerButton = !isProfileOwner(myDpm)
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_profile_owner))
}
}
AnimatedVisibility(showDeviceOwnerButton&&showProfileOwnerButton) {
Button(
onClick = {
coScope.launch{
outputText = service!!.execute(myContext.getString(R.string.dpm_activate_do_command))
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(500)
showDeviceOwnerButton = !isDeviceOwner(myDpm)
}
},
enabled = enabled
) {
Text(text = stringResource(R.string.activate_device_owner))
}
}
if(
VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)
VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile
){
Column {
AnimatedVisibility(showOrgProfileOwnerButton) {
Button(
onClick = {
coScope.launch{
@@ -165,6 +167,8 @@ fun ShizukuActivate(){
"dpm mark-profile-owner-on-organization-owned-device --user $userID com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver"
)
outputTextScrollState.animateScrollTo(0, scrollAnim())
delay(500)
showOrgProfileOwnerButton = !myDpm.isOrganizationOwnedDeviceWithManagedProfile
}
},
enabled = enabled

View File

@@ -46,6 +46,7 @@
<!--Permissions-->
<string name="click_to_activate">点击以激活</string>
<string name="device_admin">Device admin</string>
<string name="activate_jump" tools:ignore="TypographyEllipsis">激活...</string>
<string name="profile_owner">Profile owner</string>
<string name="device_owner">Device owner</string>
<string name="activate_device_admin">激活Device admin</string>
@@ -75,6 +76,11 @@
<string name="transform">转移</string>
<string name="activate_device_admin_here">在这里激活Device admin</string>
<!--Receiver-->
<string name="onEnabled">OwnDroid已启用</string>
<string name="onDisabled">OwnDroid已禁用</string>
<string name="create_work_profile_success">OwnDroid创建工作资料成功</string>
<!--Shizuku-->
<string name="check_shizuku">检查Shizuku</string>
<string name="list_owners">列出Owners</string>

View File

@@ -49,6 +49,7 @@
<!--Permissions-->
<string name="click_to_activate">Click to activate</string>
<string name="device_admin">Device admin</string>
<string name="activate_jump" tools:ignore="TypographyEllipsis">Activate...</string>
<string name="profile_owner">Profile owner</string>
<string name="device_owner">Device owner</string>
<string name="activate_device_admin">Activate Device admin</string>
@@ -82,6 +83,11 @@
<string name="transform">Transform</string>
<string name="activate_device_admin_here">Activate Device admin here. </string>
<!--Receiver-->
<string name="onEnabled">OwnDroid: Enabled</string>
<string name="onDisabled">OwnDroid: Disabled</string>
<string name="create_work_profile_success">OwnDroid: Create work profile success</string>
<!--Shizuku-->
<string name="shizuku" translatable="false">Shizuku</string>
<string name="check_shizuku">Check permission</string>