mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
add some animations
This commit is contained in:
8
Guide.md
8
Guide.md
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
### Device admin
|
### 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包括主用户、工作资料和受管理用户中的Profile owner
|
||||||
|
|
||||||
|
每个用户都可以有一个Profile owner
|
||||||
|
|
||||||
#### 激活
|
#### 激活
|
||||||
|
|
||||||
- 使用ADB激活(不推荐,如果能使用ADB,建议激活Device 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
|
### Device owner
|
||||||
|
|
||||||
权限最高
|
权限最高,一个设备只能有一个
|
||||||
|
|
||||||
#### 激活
|
#### 激活
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ android {
|
|||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 17
|
versionCode = 17
|
||||||
versionName = "4.0-Beta"
|
versionName = "4.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import android.provider.Settings
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
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.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
@@ -172,12 +175,8 @@ fun ApplicationManage(){
|
|||||||
Text(text = "禁止用户控制", style = typography.titleLarge, color = titleColor)
|
Text(text = "禁止用户控制", style = typography.titleLarge, color = titleColor)
|
||||||
Text(text = "用户将无法清除应用的存储空间和缓存", style = bodyTextStyle)
|
Text(text = "用户将无法清除应用的存储空间和缓存", style = bodyTextStyle)
|
||||||
Text(text = "应用列表:")
|
Text(text = "应用列表:")
|
||||||
if(listText!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = listText, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -266,8 +265,6 @@ fun ApplicationManage(){
|
|||||||
) {
|
) {
|
||||||
Text("由用户决定")
|
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)}
|
var inited by remember{mutableStateOf(false)}
|
||||||
if(!inited){refresh();inited=true}
|
if(!inited){refresh();inited=true}
|
||||||
if(list!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(list==""){"无"}else{list}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = list, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -329,12 +322,8 @@ fun ApplicationManage(){
|
|||||||
if(!inited){refresh();inited=true}
|
if(!inited){refresh();inited=true}
|
||||||
Text(text = "跨资料微件", style = typography.titleLarge, color = titleColor)
|
Text(text = "跨资料微件", style = typography.titleLarge, color = titleColor)
|
||||||
Text(text = "(跨资料桌面小部件提供者)", style = bodyTextStyle)
|
Text(text = "(跨资料桌面小部件提供者)", style = bodyTextStyle)
|
||||||
if(list!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(list==""){"无"}else{list}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = list, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -385,7 +374,9 @@ fun ApplicationManage(){
|
|||||||
AnimatedVisibility(policyType!=-1) {
|
AnimatedVisibility(policyType!=-1) {
|
||||||
Column {
|
Column {
|
||||||
Text("应用列表")
|
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){
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -447,12 +438,8 @@ fun ApplicationManage(){
|
|||||||
if(getList!=null){ permittedAccessibility = getList }
|
if(getList!=null){ permittedAccessibility = getList }
|
||||||
refreshList(); inited=true
|
refreshList(); inited=true
|
||||||
}
|
}
|
||||||
if(listText!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = listText, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -497,12 +484,8 @@ fun ApplicationManage(){
|
|||||||
if(getList!=null){ permittedIme = getList }
|
if(getList!=null){ permittedIme = getList }
|
||||||
refreshList();inited=true
|
refreshList();inited=true
|
||||||
}
|
}
|
||||||
if(imeListText!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(imeListText==""){"无"}else{imeListText}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = imeListText, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -548,12 +531,8 @@ fun ApplicationManage(){
|
|||||||
if(getList!=null){ keepUninstallPkg = getList }
|
if(getList!=null){ keepUninstallPkg = getList }
|
||||||
refresh(); inited=true
|
refresh(); inited=true
|
||||||
}
|
}
|
||||||
if(listText!=""){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){
|
||||||
SelectionContainer {
|
Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle, color = titleColor)
|
||||||
Text(text = listText, style = bodyTextStyle)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
Text(text = "无", style = bodyTextStyle)
|
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
Button(
|
Button(
|
||||||
@@ -670,27 +649,27 @@ fun ApplicationManage(){
|
|||||||
) {
|
) {
|
||||||
Text("选择APK...")
|
Text("选择APK...")
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
var selected by remember{mutableStateOf(false)}
|
||||||
Button(
|
LaunchedEffect(selected){apkSelected{selected = apkUri!=null}}
|
||||||
onClick = { uriToStream(myContext, apkUri){stream -> installPackage(myContext,stream)} },
|
AnimatedVisibility(selected) {
|
||||||
modifier = Modifier.fillMaxWidth(0.49F)
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
) {
|
Button(
|
||||||
Text("静默安装")
|
onClick = { uriToStream(myContext, apkUri){stream -> installPackage(myContext,stream)} },
|
||||||
}
|
modifier = Modifier.fillMaxWidth(0.49F)
|
||||||
Button(
|
) {
|
||||||
onClick = {
|
Text("静默安装")
|
||||||
if(apkUri!=null){
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
|
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
|
||||||
intent.setData(apkUri)
|
intent.setData(apkUri)
|
||||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
myContext.startActivity(intent)
|
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 out = session.openWrite("COSU", 0, -1)
|
||||||
val buffer = ByteArray(65536)
|
val buffer = ByteArray(65536)
|
||||||
var c: Int
|
var c: Int
|
||||||
while(inputStream.read(buffer).also{c = it}!=-1) {
|
while(inputStream.read(buffer).also{c = it}!=-1) { out.write(buffer, 0, c) }
|
||||||
out.write(buffer, 0, c)
|
|
||||||
}
|
|
||||||
session.fsync(out)
|
session.fsync(out)
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
out.close()
|
out.close()
|
||||||
val pendingIntent = PendingIntent.getBroadcast(context, sessionId, Intent(context,PackageInstallerReceiver::class.java), PendingIntent.FLAG_IMMUTABLE).intentSender
|
val pendingIntent = PendingIntent.getBroadcast(context, sessionId, Intent(context,PackageInstallerReceiver::class.java), PendingIntent.FLAG_IMMUTABLE).intentSender
|
||||||
session.commit(pendingIntent)
|
session.commit(pendingIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun apkSelected(operation:()->Unit){
|
||||||
|
while(true){
|
||||||
|
delay(500)
|
||||||
|
operation()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ 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.os.Binder
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.util.Log
|
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.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SystemManage(){
|
fun SystemManage(){
|
||||||
@@ -427,7 +427,7 @@ fun SystemManage(){
|
|||||||
isEmpty = caCert.isEmpty()
|
isEmpty = caCert.isEmpty()
|
||||||
exist = if(!isEmpty){ myDpm.hasCaCertInstalled(myComponent, caCert) }else{ false }
|
exist = if(!isEmpty){ myDpm.hasCaCertInstalled(myComponent, caCert) }else{ false }
|
||||||
}
|
}
|
||||||
LaunchedEffect(exist){ launch{isCaCertSelected(600){refresh()}} }
|
LaunchedEffect(exist){ isCaCertSelected(600){refresh()} }
|
||||||
Column(modifier = sections()){
|
Column(modifier = sections()){
|
||||||
Text(text = "Ca证书", style = typography.titleLarge, color = titleColor)
|
Text(text = "Ca证书", style = typography.titleLarge, color = titleColor)
|
||||||
if(isEmpty){ Text(text = "请选择Ca证书(.0)") }else{ Text(text = "证书已安装:$exist") }
|
if(isEmpty){ Text(text = "请选择Ca证书(.0)") }else{ Text(text = "证书已安装:$exist") }
|
||||||
@@ -442,28 +442,30 @@ fun SystemManage(){
|
|||||||
) {
|
) {
|
||||||
Text("选择证书...")
|
Text("选择证书...")
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
AnimatedVisibility(!isEmpty) {
|
||||||
Button(
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||||
onClick = {
|
Button(
|
||||||
val result = myDpm.installCaCert(myComponent, caCert)
|
onClick = {
|
||||||
Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show()
|
val result = myDpm.installCaCert(myComponent, caCert)
|
||||||
refresh()
|
Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show()
|
||||||
},
|
refresh()
|
||||||
modifier = Modifier.fillMaxWidth(0.49F)
|
},
|
||||||
) {
|
modifier = Modifier.fillMaxWidth(0.49F)
|
||||||
Text("安装")
|
) {
|
||||||
}
|
Text("安装")
|
||||||
Button(
|
}
|
||||||
onClick = {
|
Button(
|
||||||
if(exist){
|
onClick = {
|
||||||
myDpm.uninstallCaCert(myComponent, caCert)
|
if(exist){
|
||||||
exist = myDpm.hasCaCertInstalled(myComponent, caCert)
|
myDpm.uninstallCaCert(myComponent, caCert)
|
||||||
Toast.makeText(myContext, if(exist){"失败"}else{"成功"}, Toast.LENGTH_SHORT).show()
|
exist = myDpm.hasCaCertInstalled(myComponent, caCert)
|
||||||
}else{ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() }
|
Toast.makeText(myContext, if(exist){"失败"}else{"成功"}, Toast.LENGTH_SHORT).show()
|
||||||
},
|
}else{ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() }
|
||||||
modifier = Modifier.fillMaxWidth(0.96F)
|
},
|
||||||
) {
|
modifier = Modifier.fillMaxWidth(0.96F)
|
||||||
Text("卸载")
|
) {
|
||||||
|
Text("卸载")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
@@ -598,7 +600,7 @@ fun SystemManage(){
|
|||||||
if(VERSION.SDK_INT>=24&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
|
if(VERSION.SDK_INT>=24&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
|
||||||
Text(text = "将会删除工作资料", style = bodyTextStyle)
|
Text(text = "将会删除工作资料", style = bodyTextStyle)
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT>=34){
|
if(VERSION.SDK_INT>=34&&Binder.getCallingUid()/100000==0){
|
||||||
Text(text = "API34或以上将不能在系统用户中使用WipeData", style = bodyTextStyle)
|
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){
|
while(true){
|
||||||
delay(delay)
|
delay(delay)
|
||||||
operation()
|
operation()
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package com.binbin.androidowner
|
|||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.app.admin.DevicePolicyManager.*
|
import android.app.admin.DevicePolicyManager.*
|
||||||
import android.content.*
|
import android.content.*
|
||||||
|
import android.os.Binder
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
@@ -75,16 +77,22 @@ fun ManagedProfile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile){
|
if(VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile){
|
||||||
Column(modifier = sections(colorScheme.tertiaryContainer)){
|
var expand by remember{mutableStateOf(false)}
|
||||||
Text(text = "成为组织拥有的工作资料", color = titleColor)
|
Column(modifier = sections(colorScheme.tertiaryContainer,{expand=true},!expand).animateContentSize(animationSpec = scrollAnim())){
|
||||||
Text(text = "首先在“用户管理”中查看UserID,然后使用ADB执行下面这条命令", style = bodyTextStyle)
|
if(expand){
|
||||||
SelectionContainer {
|
Text(text = "组织拥有的工作资料", color = colorScheme.onTertiaryContainer, style = typography.titleLarge)
|
||||||
Text(
|
SelectionContainer {
|
||||||
text = "adb shell “dpm mark-profile-owner-on-organization-owned-device --user USER_ID com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver”",
|
Text(text = "使用ADB执行以下命令,或者使用Shizuku")
|
||||||
color = colorScheme.onTertiaryContainer, style = bodyTextStyle
|
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))){
|
if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))){
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.os.Build.VERSION
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
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.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Password(){
|
fun Password(){
|
||||||
@@ -43,9 +45,10 @@ fun Password(){
|
|||||||
val isWear = sharedPref.getBoolean("isWear",false)
|
val isWear = sharedPref.getBoolean("isWear",false)
|
||||||
val titleColor = colorScheme.onPrimaryContainer
|
val titleColor = colorScheme.onPrimaryContainer
|
||||||
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
|
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
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)) }
|
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(
|
Text(
|
||||||
@@ -353,8 +356,16 @@ fun Password(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(modifier = sections()) {
|
var passwordQualityExpand by remember{mutableStateOf(VERSION.SDK_INT < 31)}
|
||||||
var expanded 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(
|
val passwordQuality = mapOf(
|
||||||
PASSWORD_QUALITY_UNSPECIFIED to "未指定",
|
PASSWORD_QUALITY_UNSPECIFIED to "未指定",
|
||||||
PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度",
|
PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度",
|
||||||
@@ -366,18 +377,14 @@ fun Password(){
|
|||||||
PASSWORD_QUALITY_COMPLEX to "自定义(暂不支持)",
|
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)){ selectedItem=myDpm.getPasswordQuality(myComponent) }
|
||||||
selectedItem=myDpm.getPasswordQuality(myComponent)
|
|
||||||
}
|
|
||||||
Text(text = "密码质量要求", style = typography.titleLarge,color = titleColor)
|
Text(text = "密码质量要求", style = typography.titleLarge,color = titleColor)
|
||||||
if(expanded){
|
if(passwordQualityExpand){
|
||||||
Text(text = "不是实际密码质量", style = bodyTextStyle)
|
Text(text = "不是实际密码质量", style = bodyTextStyle)
|
||||||
Text(text = "设置密码复杂度将会取代密码质量", style = bodyTextStyle)
|
Text(text = "设置密码复杂度将会取代密码质量", style = bodyTextStyle)
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT>=31){
|
if(VERSION.SDK_INT>=31){ Text(text = "已弃用,请使用上面的”密码复杂度要求“。点击展开", color = colorScheme.error, style = bodyTextStyle) }
|
||||||
Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = colorScheme.error, style = bodyTextStyle)
|
if(passwordQualityExpand){
|
||||||
}
|
|
||||||
if(expanded){
|
|
||||||
RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first})
|
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[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first})
|
||||||
RadioButtonItem(passwordQuality[2].second,{selectedItem==passwordQuality[2].first},{selectedItem=passwordQuality[2].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))}){
|
Button(onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}){
|
||||||
Text("要求设置新密码")
|
Text("要求设置新密码")
|
||||||
}}
|
}}
|
||||||
}else{
|
|
||||||
Button(onClick = {expanded=true}) {
|
|
||||||
Text("展开")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
Spacer(Modifier.padding(vertical = 30.dp))
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.content.Intent
|
|||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
@@ -47,6 +48,7 @@ fun DpmPermissions(navCtrl:NavHostController){
|
|||||||
val isWear = sharedPref.getBoolean("isWear",false)
|
val isWear = sharedPref.getBoolean("isWear",false)
|
||||||
val titleColor = colorScheme.onPrimaryContainer
|
val titleColor = colorScheme.onPrimaryContainer
|
||||||
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
|
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
|
||||||
|
var expandCommandBlock by remember{mutableStateOf("")}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState()),
|
modifier = Modifier.verticalScroll(rememberScrollState()),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
@@ -91,9 +93,17 @@ fun DpmPermissions(navCtrl:NavHostController){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!isda&&!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
|
if(!isda&&!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
|
||||||
SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){
|
SelectionContainer(
|
||||||
Text("激活命令:\nadb shell dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
|
modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="admin"},expandCommandBlock!="admin").animateContentSize(animationSpec = scrollAnim())
|
||||||
color = colorScheme.onTertiaryContainer, style = bodyTextStyle)
|
){
|
||||||
|
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(text = "Profile Owner", fontSize = if(!isWear){22.sp}else{20.sp},color = titleColor)
|
||||||
Text(if(isProfileOwner(myDpm)){"已激活"}else{"未激活"})
|
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(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
myDpm.clearProfileOwner(myComponent)
|
myDpm.clearProfileOwner(myComponent)
|
||||||
@@ -120,9 +130,17 @@ fun DpmPermissions(navCtrl:NavHostController){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
|
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
|
||||||
SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){
|
SelectionContainer(
|
||||||
Text("激活命令:\nadb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
|
modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="profile"},expandCommandBlock!="profile").animateContentSize(animationSpec = scrollAnim())
|
||||||
color = colorScheme.onTertiaryContainer, style = bodyTextStyle)
|
){
|
||||||
|
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)){
|
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
|
||||||
SelectionContainer(modifier = sections(colorScheme.tertiaryContainer)){
|
SelectionContainer(
|
||||||
Text(text = "激活命令:\nadb shell dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
|
modifier = sections(colorScheme.tertiaryContainer,{expandCommandBlock="device"},expandCommandBlock!="device").animateContentSize(animationSpec = scrollAnim())
|
||||||
color = colorScheme.onTertiaryContainer, style = bodyTextStyle)
|
){
|
||||||
|
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){
|
if(VERSION.SDK_INT>=30){
|
||||||
@@ -166,10 +192,10 @@ fun DpmPermissions(navCtrl:NavHostController){
|
|||||||
}
|
}
|
||||||
if(VERSION.SDK_INT>=33){
|
if(VERSION.SDK_INT>=33){
|
||||||
val dpmRole = myDpm.devicePolicyManagementRoleHolderPackage
|
val dpmRole = myDpm.devicePolicyManagementRoleHolderPackage
|
||||||
Text("设备策略管理器角色:${if(dpmRole==null){"null"}else{""}}",style=bodyTextStyle)
|
Text("设备策略管理器角色(DPMRH):${if(dpmRole==null){"无"}else{""}}",style=bodyTextStyle)
|
||||||
if(dpmRole!=null){
|
if(dpmRole!=null){
|
||||||
Row(modifier = Modifier.fillMaxWidth().horizontalScroll(rememberScrollState())){
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){
|
||||||
SelectionContainer { Text(dpmRole) }
|
Text(text = dpmRole, style = bodyTextStyle, color = colorScheme.onPrimaryContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,9 +230,8 @@ fun DpmPermissions(navCtrl:NavHostController){
|
|||||||
Column(modifier = sections()) {
|
Column(modifier = sections()) {
|
||||||
val specificId = myDpm.enrollmentSpecificId
|
val specificId = myDpm.enrollmentSpecificId
|
||||||
Text(text = "设备唯一标识码", style = typography.titleLarge,color = titleColor)
|
Text(text = "设备唯一标识码", style = typography.titleLarge,color = titleColor)
|
||||||
Text(text = "(恢复出厂设置不变)",style=bodyTextStyle)
|
|
||||||
if(specificId!=""){
|
if(specificId!=""){
|
||||||
SelectionContainer{ Text(specificId, style = bodyTextStyle) }
|
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ Text(specificId, style = bodyTextStyle, softWrap = false) }
|
||||||
}else{
|
}else{
|
||||||
Text("需要设置组织ID",style=bodyTextStyle)
|
Text("需要设置组织ID",style=bodyTextStyle)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user