From a36dbc5fee89398d3a382aa121b38e2d18c103ec Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Sun, 25 Feb 2024 18:58:10 +0800 Subject: [PATCH] add some animations --- Guide.md | 8 +- app/build.gradle.kts | 2 +- .../binbin/androidowner/ApplicationManage.kt | 102 ++++++++---------- .../com/binbin/androidowner/DeviceControl.kt | 54 +++++----- .../com/binbin/androidowner/ManagedProfile.kt | 26 +++-- .../java/com/binbin/androidowner/Password.kt | 33 +++--- .../com/binbin/androidowner/Permissions.kt | 55 +++++++--- 7 files changed, 152 insertions(+), 128 deletions(-) diff --git a/Guide.md b/Guide.md index 2f30b1b..07ca65b 100644 --- a/Guide.md +++ b/Guide.md @@ -29,7 +29,7 @@ ### Device admin -权限最小 +权限最小,数量不限 #### 激活 @@ -58,6 +58,8 @@ adb shell dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.M 如无特别说明,Profile owner包括主用户、工作资料和受管理用户中的Profile owner +每个用户都可以有一个Profile owner + #### 激活 - 使用ADB激活(不推荐,如果能使用ADB,建议激活Device owner),只能有一个Profile owner @@ -73,7 +75,7 @@ adb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner. #### 停用 -主用户:”权限“界面中停用 +主用户:”权限“界面中停用~~或ADB停用~~ 工作资料:”设备控制“界面中的”清除数据“,会删除工作资料 @@ -81,7 +83,7 @@ adb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner. ### Device owner -权限最高 +权限最高,一个设备只能有一个 #### 激活 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3d9de24..4e8db25 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,7 +12,7 @@ android { minSdk = 21 targetSdk = 34 versionCode = 17 - versionName = "4.0-Beta" + versionName = "4.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt index 520f78c..36cfa26 100644 --- a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt +++ b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt @@ -21,7 +21,9 @@ import android.provider.Settings import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.focusable +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions @@ -43,6 +45,7 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity +import kotlinx.coroutines.delay import java.io.IOException import java.io.InputStream import java.util.concurrent.Executors @@ -172,12 +175,8 @@ fun ApplicationManage(){ Text(text = "禁止用户控制", style = typography.titleLarge, color = titleColor) Text(text = "用户将无法清除应用的存储空间和缓存", style = bodyTextStyle) Text(text = "应用列表:") - if(listText!=""){ - SelectionContainer { - Text(text = listText, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -266,8 +265,6 @@ fun ApplicationManage(){ ) { Text("由用户决定") } - Text(text ="设为允许或拒绝后,用户不能改变状态", style = bodyTextStyle) - if(VERSION.SDK_INT>=31){Text(text = "可以修改传感器相关权限:${myDpm.canAdminGrantSensorsPermissions()}", style = bodyTextStyle)} } } @@ -283,12 +280,8 @@ fun ApplicationManage(){ } var inited by remember{mutableStateOf(false)} if(!inited){refresh();inited=true} - if(list!=""){ - SelectionContainer { - Text(text = list, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(list==""){"无"}else{list}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -329,12 +322,8 @@ fun ApplicationManage(){ if(!inited){refresh();inited=true} Text(text = "跨资料微件", style = typography.titleLarge, color = titleColor) Text(text = "(跨资料桌面小部件提供者)", style = bodyTextStyle) - if(list!=""){ - SelectionContainer { - Text(text = list, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(list==""){"无"}else{list}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -385,7 +374,9 @@ fun ApplicationManage(){ AnimatedVisibility(policyType!=-1) { Column { Text("应用列表") - Text(text = if(credentialListText!=""){ credentialListText }else{ "无" }, style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(credentialListText!=""){ credentialListText }else{ "无" }, style = bodyTextStyle, color = titleColor) + } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Button( onClick = { @@ -447,12 +438,8 @@ fun ApplicationManage(){ if(getList!=null){ permittedAccessibility = getList } refreshList(); inited=true } - if(listText!=""){ - SelectionContainer { - Text(text = listText, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -497,12 +484,8 @@ fun ApplicationManage(){ if(getList!=null){ permittedIme = getList } refreshList();inited=true } - if(imeListText!=""){ - SelectionContainer { - Text(text = imeListText, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(imeListText==""){"无"}else{imeListText}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -548,12 +531,8 @@ fun ApplicationManage(){ if(getList!=null){ keepUninstallPkg = getList } refresh(); inited=true } - if(listText!=""){ - SelectionContainer { - Text(text = listText, style = bodyTextStyle) - } - }else{ - Text(text = "无", style = bodyTextStyle) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ + Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor) } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Button( @@ -670,27 +649,27 @@ fun ApplicationManage(){ ) { Text("选择APK...") } - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ - Button( - onClick = { uriToStream(myContext, apkUri){stream -> installPackage(myContext,stream)} }, - modifier = Modifier.fillMaxWidth(0.49F) - ) { - Text("静默安装") - } - Button( - onClick = { - if(apkUri!=null){ + var selected by remember{mutableStateOf(false)} + LaunchedEffect(selected){apkSelected{selected = apkUri!=null}} + AnimatedVisibility(selected) { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Button( + onClick = { uriToStream(myContext, apkUri){stream -> installPackage(myContext,stream)} }, + modifier = Modifier.fillMaxWidth(0.49F) + ) { + Text("静默安装") + } + Button( + onClick = { val intent = Intent(Intent.ACTION_INSTALL_PACKAGE) intent.setData(apkUri) intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) myContext.startActivity(intent) - }else{ - Toast.makeText(myContext, "请先选择APK", Toast.LENGTH_SHORT).show() - } - }, - modifier = Modifier.fillMaxWidth(0.96F) - ) { - Text("请求安装") + }, + modifier = Modifier.fillMaxWidth(0.96F) + ) { + Text("请求安装") + } } } } @@ -735,12 +714,17 @@ private fun installPackage(context: Context, inputStream: InputStream){ val out = session.openWrite("COSU", 0, -1) val buffer = ByteArray(65536) var c: Int - while(inputStream.read(buffer).also{c = it}!=-1) { - out.write(buffer, 0, c) - } + while(inputStream.read(buffer).also{c = it}!=-1) { out.write(buffer, 0, c) } session.fsync(out) inputStream.close() out.close() val pendingIntent = PendingIntent.getBroadcast(context, sessionId, Intent(context,PackageInstallerReceiver::class.java), PendingIntent.FLAG_IMMUTABLE).intentSender session.commit(pendingIntent) } + +private suspend fun apkSelected(operation:()->Unit){ + while(true){ + delay(500) + operation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index a970bda..4ebcbd1 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -5,6 +5,7 @@ import android.app.admin.DevicePolicyManager.* import android.content.ComponentName import android.content.Context import android.content.Intent +import android.os.Binder import android.os.Build.VERSION import android.os.UserManager import android.util.Log @@ -35,7 +36,6 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import kotlinx.coroutines.delay -import kotlinx.coroutines.launch @Composable fun SystemManage(){ @@ -427,7 +427,7 @@ fun SystemManage(){ isEmpty = caCert.isEmpty() exist = if(!isEmpty){ myDpm.hasCaCertInstalled(myComponent, caCert) }else{ false } } - LaunchedEffect(exist){ launch{isCaCertSelected(600){refresh()}} } + LaunchedEffect(exist){ isCaCertSelected(600){refresh()} } Column(modifier = sections()){ Text(text = "Ca证书", style = typography.titleLarge, color = titleColor) if(isEmpty){ Text(text = "请选择Ca证书(.0)") }else{ Text(text = "证书已安装:$exist") } @@ -442,28 +442,30 @@ fun SystemManage(){ ) { Text("选择证书...") } - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ - Button( - onClick = { - val result = myDpm.installCaCert(myComponent, caCert) - Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() - refresh() - }, - modifier = Modifier.fillMaxWidth(0.49F) - ) { - Text("安装") - } - Button( - onClick = { - if(exist){ - myDpm.uninstallCaCert(myComponent, caCert) - exist = myDpm.hasCaCertInstalled(myComponent, caCert) - Toast.makeText(myContext, if(exist){"失败"}else{"成功"}, Toast.LENGTH_SHORT).show() - }else{ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() } - }, - modifier = Modifier.fillMaxWidth(0.96F) - ) { - Text("卸载") + AnimatedVisibility(!isEmpty) { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Button( + onClick = { + val result = myDpm.installCaCert(myComponent, caCert) + Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() + refresh() + }, + modifier = Modifier.fillMaxWidth(0.49F) + ) { + Text("安装") + } + Button( + onClick = { + if(exist){ + myDpm.uninstallCaCert(myComponent, caCert) + exist = myDpm.hasCaCertInstalled(myComponent, caCert) + Toast.makeText(myContext, if(exist){"失败"}else{"成功"}, Toast.LENGTH_SHORT).show() + }else{ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() } + }, + modifier = Modifier.fillMaxWidth(0.96F) + ) { + Text("卸载") + } } } Button( @@ -598,7 +600,7 @@ fun SystemManage(){ if(VERSION.SDK_INT>=24&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){ Text(text = "将会删除工作资料", style = bodyTextStyle) } - if(VERSION.SDK_INT>=34){ + if(VERSION.SDK_INT>=34&&Binder.getCallingUid()/100000==0){ Text(text = "API34或以上将不能在系统用户中使用WipeData", style = bodyTextStyle) } } @@ -655,7 +657,7 @@ fun DeviceCtrlItem( } } -suspend fun isCaCertSelected(delay:Long,operation:()->Unit){ +private suspend fun isCaCertSelected(delay:Long,operation:()->Unit){ while(true){ delay(delay) operation() diff --git a/app/src/main/java/com/binbin/androidowner/ManagedProfile.kt b/app/src/main/java/com/binbin/androidowner/ManagedProfile.kt index 3bfc71f..a5f90b7 100644 --- a/app/src/main/java/com/binbin/androidowner/ManagedProfile.kt +++ b/app/src/main/java/com/binbin/androidowner/ManagedProfile.kt @@ -3,10 +3,12 @@ package com.binbin.androidowner import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.* import android.content.* +import android.os.Binder import android.os.Build.VERSION import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.focusable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState @@ -75,16 +77,22 @@ fun ManagedProfile() { } if(VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile){ - Column(modifier = sections(colorScheme.tertiaryContainer)){ - Text(text = "成为组织拥有的工作资料", color = titleColor) - Text(text = "首先在“用户管理”中查看UserID,然后使用ADB执行下面这条命令", style = bodyTextStyle) - SelectionContainer { - Text( - text = "adb shell “dpm mark-profile-owner-on-organization-owned-device --user USER_ID com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver”", - color = colorScheme.onTertiaryContainer, style = bodyTextStyle - ) + var expand by remember{mutableStateOf(false)} + Column(modifier = sections(colorScheme.tertiaryContainer,{expand=true},!expand).animateContentSize(animationSpec = scrollAnim())){ + if(expand){ + Text(text = "组织拥有的工作资料", color = colorScheme.onTertiaryContainer, style = typography.titleLarge) + SelectionContainer { + Text(text = "使用ADB执行以下命令,或者使用Shizuku") + Text( + text = "adb shell \"dpm mark-profile-owner-on-organization-owned-device --user ${Binder.getCallingUid()/100000}" + + " com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"", + color = colorScheme.onTertiaryContainer, style = bodyTextStyle + ) + } + }else{ + Text(text = "成为组织拥有的工作资料", color = colorScheme.onTertiaryContainer) + Text(text = "点击展开", style = bodyTextStyle) } - Text(text = "把上面命令中的USER_ID替换成你的UserID", style = bodyTextStyle) } } if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))){ diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index 273e8b2..3db204b 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -10,6 +10,7 @@ import android.os.Build.VERSION import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape @@ -31,6 +32,7 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity +import kotlinx.coroutines.delay @Composable fun Password(){ @@ -43,9 +45,10 @@ fun Password(){ val isWear = sharedPref.getBoolean("isWear",false) val titleColor = colorScheme.onPrimaryContainer val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge} + val scrollState = rememberScrollState() Column( horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState()).navigationBarsPadding() + modifier = Modifier.fillMaxWidth().verticalScroll(scrollState) ) { val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } Text( @@ -353,8 +356,16 @@ fun Password(){ } } - Column(modifier = sections()) { - var expanded by remember{ mutableStateOf(VERSION.SDK_INT < 31) } + var passwordQualityExpand by remember{mutableStateOf(VERSION.SDK_INT < 31)} + var launchScrollDown by remember{mutableStateOf(false)} + LaunchedEffect(launchScrollDown){ + if(launchScrollDown){ + delay(10) + scrollState.animateScrollTo((scrollState.value+myContext.resources.displayMetrics.heightPixels*0.4).toInt(), scrollAnim()) + launchScrollDown=false + } + } + Column(modifier = sections(onClick = {passwordQualityExpand=true;launchScrollDown=true}, clickable = !passwordQualityExpand).animateContentSize(animationSpec = scrollAnim())) { val passwordQuality = mapOf( PASSWORD_QUALITY_UNSPECIFIED to "未指定", PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度", @@ -366,18 +377,14 @@ fun Password(){ PASSWORD_QUALITY_COMPLEX to "自定义(暂不支持)", ).toList() var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) } - if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ - selectedItem=myDpm.getPasswordQuality(myComponent) - } + if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.getPasswordQuality(myComponent) } Text(text = "密码质量要求", style = typography.titleLarge,color = titleColor) - if(expanded){ + if(passwordQualityExpand){ Text(text = "不是实际密码质量", style = bodyTextStyle) Text(text = "设置密码复杂度将会取代密码质量", style = bodyTextStyle) } - if(VERSION.SDK_INT>=31){ - Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = colorScheme.error, style = bodyTextStyle) - } - if(expanded){ + if(VERSION.SDK_INT>=31){ Text(text = "已弃用,请使用上面的”密码复杂度要求“。点击展开", color = colorScheme.error, style = bodyTextStyle) } + if(passwordQualityExpand){ RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first}) RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first}) RadioButtonItem(passwordQuality[2].second,{selectedItem==passwordQuality[2].first},{selectedItem=passwordQuality[2].first}) @@ -401,10 +408,6 @@ fun Password(){ Button(onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}){ Text("要求设置新密码") }} - }else{ - Button(onClick = {expanded=true}) { - Text("展开") - } } } Spacer(Modifier.padding(vertical = 30.dp)) diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index 1b9a837..6d31727 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -8,6 +8,7 @@ import android.content.Intent import android.os.Build.VERSION import android.widget.Toast import androidx.activity.ComponentActivity +import androidx.compose.animation.animateContentSize import androidx.compose.foundation.focusable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.* @@ -47,6 +48,7 @@ fun DpmPermissions(navCtrl:NavHostController){ val isWear = sharedPref.getBoolean("isWear",false) val titleColor = colorScheme.onPrimaryContainer val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge} + var expandCommandBlock by remember{mutableStateOf("")} Column( modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally @@ -91,9 +93,17 @@ fun DpmPermissions(navCtrl:NavHostController){ } } if(!isda&&!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){ - SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){ - Text("激活命令:\nadb shell dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", - color = colorScheme.onTertiaryContainer, style = bodyTextStyle) + SelectionContainer( + modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="admin"},expandCommandBlock!="admin").animateContentSize(animationSpec = scrollAnim()) + ){ + if(expandCommandBlock=="admin"){ + Text( + text = "adb shell dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", + color = colorScheme.onTertiaryContainer, style = bodyTextStyle + ) + }else{ + Text(text = "点击查看激活命令", style = bodyTextStyle) + } } } @@ -107,7 +117,7 @@ fun DpmPermissions(navCtrl:NavHostController){ Text(text = "Profile Owner", fontSize = if(!isWear){22.sp}else{20.sp},color = titleColor) Text(if(isProfileOwner(myDpm)){"已激活"}else{"未激活"}) } - if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24&&!isWear){ + if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24&&!isWear&&!myDpm.isManagedProfile(myComponent)){ Button( onClick = { myDpm.clearProfileOwner(myComponent) @@ -120,9 +130,17 @@ fun DpmPermissions(navCtrl:NavHostController){ } } if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){ - SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){ - Text("激活命令:\nadb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", - color = colorScheme.onTertiaryContainer, style = bodyTextStyle) + SelectionContainer( + modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="profile"},expandCommandBlock!="profile").animateContentSize(animationSpec = scrollAnim()) + ){ + if(expandCommandBlock=="profile"){ + Text( + text = "adb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", + color = colorScheme.onTertiaryContainer, style = bodyTextStyle + ) + }else{ + Text(text = "点击查看激活命令", style = bodyTextStyle) + } } } @@ -150,9 +168,17 @@ fun DpmPermissions(navCtrl:NavHostController){ } if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){ - SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){ - Text(text = "激活命令:\nadb shell dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", - color = colorScheme.onTertiaryContainer, style = bodyTextStyle) + SelectionContainer( + modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="device"},expandCommandBlock!="device").animateContentSize(animationSpec = scrollAnim()) + ){ + if(expandCommandBlock=="device"){ + Text( + text = "adb shell dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", + color = colorScheme.onTertiaryContainer, style = bodyTextStyle + ) + }else{ + Text(text = "点击查看激活命令", style = bodyTextStyle) + } } } if(VERSION.SDK_INT>=30){ @@ -166,10 +192,10 @@ fun DpmPermissions(navCtrl:NavHostController){ } if(VERSION.SDK_INT>=33){ val dpmRole = myDpm.devicePolicyManagementRoleHolderPackage - Text("设备策略管理器角色:${if(dpmRole==null){"null"}else{""}}",style=bodyTextStyle) + Text("设备策略管理器角色(DPMRH):${if(dpmRole==null){"无"}else{""}}",style=bodyTextStyle) if(dpmRole!=null){ - Row(modifier = Modifier.fillMaxWidth().horizontalScroll(rememberScrollState())){ - SelectionContainer { Text(dpmRole) } + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ + Text(text = dpmRole, style = bodyTextStyle, color = colorScheme.onPrimaryContainer) } } } @@ -204,9 +230,8 @@ fun DpmPermissions(navCtrl:NavHostController){ Column(modifier = sections()) { val specificId = myDpm.enrollmentSpecificId Text(text = "设备唯一标识码", style = typography.titleLarge,color = titleColor) - Text(text = "(恢复出厂设置不变)",style=bodyTextStyle) if(specificId!=""){ - SelectionContainer{ Text(specificId, style = bodyTextStyle) } + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ Text(specificId, style = bodyTextStyle, softWrap = false) } }else{ Text("需要设置组织ID",style=bodyTextStyle) }