diff --git a/Readme.md b/Readme.md index 9228e9d..530b83c 100644 --- a/Readme.md +++ b/Readme.md @@ -9,6 +9,8 @@ ### 功能 +已经适配手表,请在应用的设置里打开“Wear” + - 设备控制 - 禁用相机 - 禁止截屏 @@ -39,8 +41,6 @@ ### 即将加入的功能 -- Profile Owner相关 - Managed Profile,工作资料和多用户相关 - 安装/卸载应用,清除应用的缓存和存储空间 - 应用管理的包选择器(目前只能手动输入包名) -- 适配手表 \ No newline at end of file diff --git a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt index 1bcfd9b..6d23cdf 100644 --- a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt +++ b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt @@ -13,6 +13,7 @@ import android.os.Build.VERSION import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -49,6 +50,7 @@ fun ApplicationManage(){ val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java) var pkgName by remember { mutableStateOf("") } val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) + val isWear = sharedPref.getBoolean("isWear",false) Column( modifier = Modifier .fillMaxWidth() @@ -87,13 +89,16 @@ fun ApplicationManage(){ /*AppManageItem(R.string.block_unins,R.string.sometimes_not_available,myDpm, {myDpm.isUninstallBlocked(myComponent,pkgName)}, {b -> myDpm.setUninstallBlocked(myComponent,pkgName,b)})*/ Row( - modifier = sections(), - horizontalArrangement = if(!sharedPref.getBoolean("isWear",false)){Arrangement.SpaceAround}else{Arrangement.SpaceBetween} + horizontalArrangement = Arrangement.SpaceBetween, + modifier = if(isWear){sections().horizontalScroll(rememberScrollState())}else{ sections()} ) { - Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,false)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)) { + Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,false)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.48F)}) { Text("允许卸载") } - Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,true)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)) { + if(isWear){Spacer(Modifier.padding(horizontal = 3.dp))} + Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,true)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.92F)}) { Text("防卸载") } } diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index 59e218f..6b48a07 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -19,6 +19,7 @@ import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -73,17 +74,35 @@ fun DeviceControl(){ if(myDpm.canUsbDataSignalingBeDisabled()){ DeviceCtrlItem(R.string.usb_signal,R.string.place_holder,R.drawable.usb_fill0,myDpm,{myDpm.isUsbDataSignalingEnabled},{b -> myDpm.isUsbDataSignalingEnabled = b }) }else{ - Text(text = "你的设备不支持关闭USB信号", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + Text(text = "你的设备不支持关闭USB信号",modifier = Modifier.fillMaxWidth(), + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}, textAlign = TextAlign.Center) } } + if(VERSION.SDK_INT<24){ + Text(text = "重启和WiFi Mac需要API24",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + } + if(VERSION.SDK_INT<26){ + Text(text = "备份服务需要API26",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + } + if(VERSION.SDK_INT<30){ + Text(text = "自动设置时间和自动设置时区需要API30",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + } + if(VERSION.SDK_INT<31){Text(text = "关闭USB信号需API31",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium})} + if(VERSION.SDK_INT<34){ + Text(text = "隐藏状态栏需要API34",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + } if(VERSION.SDK_INT>=28){ Column(modifier = sections()) { - Text(text = "锁屏方式", style = MaterialTheme.typography.titleLarge) - Text(text = "禁用需要无密码") + Text(text = "锁屏方式", style = typography.titleLarge) + Text(text = "禁用需要无密码",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = if(!isWear){Arrangement.SpaceEvenly}else{Arrangement.SpaceBetween} + horizontalArrangement = Arrangement.SpaceBetween ) { Button( onClick = { @@ -93,11 +112,11 @@ fun DeviceControl(){ Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() } }, - enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser) + enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.48F)} ) { Text("禁用") } - if(!isWear){Spacer(Modifier.padding(horizontal = 5.dp))} Button( onClick = { if(myDpm.setKeyguardDisabled(myComponent,false)){ @@ -106,7 +125,8 @@ fun DeviceControl(){ Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() } }, - enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser) + enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.92F)} ) { Text("启用") } @@ -114,14 +134,16 @@ fun DeviceControl(){ } Row( - horizontalArrangement = if(!isWear){Arrangement.SpaceAround}else{Arrangement.SpaceBetween}, + horizontalArrangement = Arrangement.SpaceBetween, modifier = sections(), ) { if(VERSION.SDK_INT>=24){ - Button(onClick = {myDpm.reboot(myComponent)}, enabled = isDeviceOwner(myDpm)) { + Button(onClick = {myDpm.reboot(myComponent)}, enabled = isDeviceOwner(myDpm), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.48F)}) { Text("重启") } - Button(onClick = {myDpm.lockNow()}, enabled = myDpm.isAdminActive(myComponent)) { + Button(onClick = {myDpm.lockNow()}, enabled = myDpm.isAdminActive(myComponent), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.92F)}) { Text("锁屏") } } @@ -132,25 +154,7 @@ fun DeviceControl(){ }catch(e:SecurityException){ "没有权限" } - Text(text = "WiFi MAC: $wifimac",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center) - } - if(VERSION.SDK_INT<24){ - Text(text = "重启和WiFi Mac需要API24",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) - } - if(VERSION.SDK_INT<26){ - Text(text = "备份服务需要API26",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) - } - if(VERSION.SDK_INT<30){ - Text(text = "自动设置时间和自动设置时区需要API30",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) - } - if(VERSION.SDK_INT<31){Text(text = "关闭USB信号需API31",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})} - if(VERSION.SDK_INT<34){ - Text(text = "隐藏状态栏需要API34",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + Text(text = "WiFi MAC: $wifimac",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center,style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } Button( onClick = {myDpm.uninstallAllUserCaCerts(myComponent);Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()}, @@ -165,14 +169,14 @@ fun DeviceControl(){ Column(modifier = sections(MaterialTheme.colorScheme.errorContainer)) { var flag by remember{ mutableIntStateOf(0) } var confirmed by remember{ mutableStateOf(false) } - Text(text = "清除数据",style = MaterialTheme.typography.titleLarge,modifier = Modifier.padding(6.dp)) + Text(text = "清除数据",style = typography.titleLarge,modifier = Modifier.padding(6.dp)) RadioButtonItem("默认",{flag==0},{flag=0}) RadioButtonItem("WIPE_EXTERNAL_STORAGE",{flag==0x0001},{flag=0x0001}) RadioButtonItem("WIPE_RESET_PROTECTION_DATA",{flag==0x0002},{flag=0x0002}) RadioButtonItem("WIPE_EUICC",{flag==0x0004},{flag=0x0004}) RadioButtonItem("WIPE_SILENTLY",{flag==0x0008},{flag=0x0008}) Text(text = "清空数据的不能是系统用户", - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!sharedPref.getBoolean("isWear",false)){typography.bodyLarge}else{typography.bodyMedium}) Button( onClick = {confirmed=!confirmed}, colors = ButtonDefaults.buttonColors( @@ -183,7 +187,7 @@ fun DeviceControl(){ ) { Text(text = if(confirmed){"取消"}else{"确定"}) } - Row { + Row(horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = {myDpm.wipeData(flag)}, colors = ButtonDefaults.buttonColors( @@ -194,7 +198,6 @@ fun DeviceControl(){ ) { Text("WipeData") } - Spacer(Modifier.padding(horizontal = 5.dp)) if (VERSION.SDK_INT >= 34) { Button( onClick = {myDpm.wipeDevice(flag)}, @@ -224,13 +227,15 @@ private fun DeviceCtrlItem( ){ var isEnabled by remember{ mutableStateOf(false) } val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) + val isWear = sharedPref.getBoolean("isWear",false) Row( modifier = sections(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Row( - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, + modifier = if(isWear){Modifier.fillMaxWidth(0.65F)}else{Modifier.fillMaxWidth(0.75F)} ){ if(!sharedPref.getBoolean("isWear",false)){ Icon( @@ -242,7 +247,7 @@ private fun DeviceCtrlItem( Column { Text( text = stringResource(itemName), - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.titleLarge}else{MaterialTheme.typography.bodyLarge} + style = if(!sharedPref.getBoolean("isWear",false)){typography.titleLarge}else{typography.bodyLarge} ) if(itemDesc!=R.string.place_holder&&!sharedPref.getBoolean("isWear",false)){ Text(stringResource(itemDesc)) diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index 73479bb..0643c82 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -1,7 +1,6 @@ package com.binbin.androidowner import android.annotation.SuppressLint -import android.app.ActivityManager import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context @@ -180,7 +179,7 @@ fun HomePage(navCtrl:NavHostController){ val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) Column(modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally) { if(sharedPref.getBoolean("isWear",false)){ - Text(text = "Android owner", style = MaterialTheme.typography.titleLarge) + Spacer(Modifier.padding(vertical = 3.dp)) } Row( modifier = Modifier @@ -191,7 +190,7 @@ fun HomePage(navCtrl:NavHostController){ .clickable(onClick = { navCtrl.navigate("Permissions") }) .padding( horizontal = 5.dp, - vertical = if (!sharedPref.getBoolean("isWear", false)) { 14.dp } else { 1.dp } + vertical = if (!sharedPref.getBoolean("isWear", false)) { 14.dp } else { 2.dp } ), verticalAlignment = Alignment.CenterVertically ) { @@ -225,7 +224,7 @@ fun HomePage(navCtrl:NavHostController){ HomePageItem(R.string.user_manage,R.drawable.account_circle_fill0,R.string.user_manage_desc,"UserManage",navCtrl) HomePageItem(R.string.password, R.drawable.password_fill0,R.string.security_desc, "Password",navCtrl) HomePageItem(R.string.setting, R.drawable.info_fill0, R.string.setting_desc, "AppSetting",navCtrl) - Spacer(Modifier.padding(vertical = 15.dp)) + Spacer(Modifier.padding(vertical = 20.dp)) } } @@ -274,6 +273,7 @@ fun RadioButtonItem( val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier .fillMaxWidth() + .padding(vertical = if(sharedPref.getBoolean("isWear",false)){3.dp}else{0.dp}) .clip(RoundedCornerShape(25)) .clickable(onClick = operation) ) { diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index 7de22e5..98f7172 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -4,6 +4,7 @@ import android.app.KeyguardManager import android.app.admin.DevicePolicyManager 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 @@ -27,6 +28,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable @@ -67,24 +69,39 @@ fun Password(){ Text( text = "以下操作可能会造成不可挽回的损失,请先备份好数据。执行操作时一定要谨慎!!!", color = MaterialTheme.colorScheme.onErrorContainer, - modifier = sections(MaterialTheme.colorScheme.errorContainer) + modifier = sections(MaterialTheme.colorScheme.errorContainer), + style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium} ) + if(isWear){ + Text( + text = "警告!手表不支持带字母的密码,也不支持超过4位的PIN码!如果你设置了这样的密码(或密码复杂度要求),你将无法解锁你的手表!", + color = MaterialTheme.colorScheme.onErrorContainer, + modifier = sections(MaterialTheme.colorScheme.errorContainer), + style = typography.bodyMedium + ) + } if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){ Column( modifier = sections() ) { if(VERSION.SDK_INT>=29){ - val pwdComplex = myDpm.passwordComplexity - Text(text = "当前密码复杂度:$pwdComplex") + val passwordComplexity = mapOf( + DevicePolicyManager.PASSWORD_COMPLEXITY_NONE to "无(允许不设密码)", + DevicePolicyManager.PASSWORD_COMPLEXITY_LOW to "低(允许图案和连续性)", + DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM to "中(无连续性,至少4位)", + DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH to "高(无连续性,至少6位)" + ) + val pwdComplex = passwordComplexity[myDpm.passwordComplexity] + Text(text = "当前密码复杂度:$pwdComplex",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ - Text("密码达到要求:${myDpm.isActivePasswordSufficient}") + Text("密码达到要求:${myDpm.isActivePasswordSufficient}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts - Text(text = "密码已错误次数:$pwdFailedAttempts") + Text(text = "密码已错误次数:$pwdFailedAttempts",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) if(VERSION.SDK_INT>=28&&(myDpm.isManagedProfile(myComponent)||myDpm.isProfileOwnerApp("com.binbin.androidowner"))){ val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent) - Text("个人与工作应用密码一致:$unifiedPwd") + Text("个人与工作应用密码一致:$unifiedPwd",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } } @@ -93,7 +110,7 @@ fun Password(){ horizontalAlignment = Alignment.Start, modifier = sections() ) { - Text(text = "密码重置令牌", style = MaterialTheme.typography.titleLarge) + Text(text = "密码重置令牌", style = typography.titleLarge) Row(modifier = if(!isWear){Modifier}else{Modifier.horizontalScroll(rememberScrollState())}) { Button( onClick = { @@ -127,19 +144,13 @@ fun Password(){ Text("激活") } } - Text(text = "(可以水平滚动)") - Text("没有密码时会自动激活令牌") - Text("有可能无法设置密码重置令牌,因机而异") + if(isWear){ + Text(text = "(可以水平滚动)",style=typography.bodyMedium) + } + Text("没有密码时会自动激活令牌",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + Text("有可能无法设置密码重置令牌,因机而异",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } - if(isWear){ - Text( - text = "警告!手表不支持带字母的密码,也不支持超过4位的PIN码!如果你设置了这样的密码,你将无法解锁你的手表!", - color = MaterialTheme.colorScheme.onErrorContainer, - modifier = sections(MaterialTheme.colorScheme.errorContainer), - style = MaterialTheme.typography.bodyMedium - ) - } Column( modifier = sections() ) { @@ -151,13 +162,14 @@ fun Password(){ label = { Text("密码")}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + modifier = Modifier.fillMaxWidth() ) - Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 5.dp)) + Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 5.dp),style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) var resetPwdFlag by remember{ mutableIntStateOf(0) } - RadioButtonItem("RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT", + RadioButtonItem("开机时不要求密码(如果有指纹等其他解锁方式)", {resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}) - RadioButtonItem("RESET_PASSWORD_REQUIRE_ENTRY",{resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY}, + RadioButtonItem("要求立即输入新密码",{resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY}, {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY}) RadioButtonItem("无",{resetPwdFlag==0},{resetPwdFlag=0}) Row(modifier = if(!isWear){Modifier}else{Modifier.horizontalScroll(rememberScrollState())}) { @@ -196,7 +208,7 @@ fun Password(){ enabled = confirmed, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError) ) { - Text("应用(已弃用)") + Text("应用(旧)") } } } @@ -211,26 +223,26 @@ fun Password(){ if(VERSION.SDK_INT>=31){ Column(modifier = sections()) { val passwordComplexity = mapOf( - DevicePolicyManager.PASSWORD_COMPLEXITY_NONE to "无复杂度(允许不设密码)(0)", - DevicePolicyManager.PASSWORD_COMPLEXITY_LOW to "低复杂度(允许图案和连续性)(65536)", - DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM to "中复杂度(无连续性,至少4位)(196608)", - DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH to "高复杂度(无连续性,至少6位)(327680)" + DevicePolicyManager.PASSWORD_COMPLEXITY_NONE to "无(允许不设密码)", + DevicePolicyManager.PASSWORD_COMPLEXITY_LOW to "低(允许图案和连续性)", + DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM to "中(无连续性,至少4位)", + DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH to "高(无连续性,至少6位)" ).toList() var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) } if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.requiredPasswordComplexity } - Text(text = "密码复杂度要求", style = MaterialTheme.typography.titleLarge) + Text(text = "密码复杂度要求", style = typography.titleLarge) Text(text = "不是实际密码复杂度", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) Text(text = "设置密码复杂度将会取代密码质量", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) RadioButtonItem(passwordComplexity[0].second,{selectedItem==passwordComplexity[0].first},{selectedItem=passwordComplexity[0].first}) RadioButtonItem(passwordComplexity[1].second,{selectedItem==passwordComplexity[1].first},{selectedItem=passwordComplexity[1].first}) RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first}) RadioButtonItem(passwordComplexity[3].second,{selectedItem==passwordComplexity[3].first},{selectedItem=passwordComplexity[3].first}) Text(text = "连续性:密码重复(6666)或密码递增递减(4321、2468)", modifier = Modifier.padding(vertical = 3.dp), - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) Button( onClick = { myDpm.requiredPasswordComplexity = selectedItem @@ -240,12 +252,16 @@ fun Password(){ ) { Text("应用") } + Button(onClick = {myContext.startActivity(Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD))}) { + Text("要求设置新密码") + } } } Column( modifier = sections() ) { + var expanded by remember{ mutableStateOf(VERSION.SDK_INT < 31) } val passwordQuality = mapOf( DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED to "未指定", DevicePolicyManager.PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度", @@ -260,13 +276,15 @@ fun Password(){ if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.getPasswordQuality(myComponent) } - Text(text = "密码质量要求", style = MaterialTheme.typography.titleLarge) + Text(text = "密码质量要求", style = typography.titleLarge) + if(expanded){ Text(text = "不是实际密码质量", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium})} if(VERSION.SDK_INT>=31){ Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = MaterialTheme.colorScheme.error, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(expanded){ 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}) @@ -276,7 +294,7 @@ fun Password(){ RadioButtonItem(passwordQuality[6].second,{selectedItem==passwordQuality[6].first},{selectedItem=passwordQuality[6].first}) RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first}) Text(text = "连续性:密码重复(6666)或密码递增递减(4321、2468)", modifier = Modifier.padding(vertical = 3.dp), - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) Button( onClick = { myDpm.setPasswordQuality(myComponent,selectedItem) @@ -286,8 +304,16 @@ fun Password(){ ) { Text("应用") } + if(VERSION.SDK_INT<31){ + Button(onClick = {myContext.startActivity(Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD))}){ + Text("要求设置新密码") + }} + }else{ + Button(onClick = {expanded=true}) { + Text("展开") + } + } } - Spacer(Modifier.padding(vertical = 30.dp)) } } @@ -308,21 +334,15 @@ fun PasswordItem( var inputContentEdited by remember{ mutableStateOf(false) } var ableToApply by remember{ mutableStateOf(true) } val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) - Text(text = stringResource(itemName), style = MaterialTheme.typography.titleLarge) + Text(text = stringResource(itemName), style = typography.titleLarge) Text(text= stringResource(itemDesc),modifier=Modifier.padding(vertical = 2.dp), - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!sharedPref.getBoolean("isWear",false)){typography.bodyLarge}else{typography.bodyMedium}) Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier .fillMaxWidth() - .padding( - end = if (!sharedPref.getBoolean("isWear", false)) { - 8.dp - } else { - 0.dp - } - ) + .padding(end = if (!sharedPref.getBoolean("isWear", false)) { 8.dp } else { 0.dp }) ){ TextField( value = inputContent, @@ -338,7 +358,8 @@ fun PasswordItem( }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm), + modifier = if(sharedPref.getBoolean("isWear",false)){Modifier}else{Modifier.fillMaxWidth(0.8F)} ) if(!sharedPref.getBoolean("isWear",false)){ IconButton( diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index 2013a36..0aea415 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable @@ -99,10 +100,10 @@ fun DpmPermissions(navCtrl:NavHostController){ SelectionContainer { Text("adb shell dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", color = MaterialTheme.colorScheme.onTertiaryContainer, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } Text(text = "或者进入设置(原生安卓) -> 安全 -> 更多安全设置 -> 设备管理应用 -> Android Owner", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } Row( @@ -138,14 +139,14 @@ fun DpmPermissions(navCtrl:NavHostController){ SelectionContainer { Text("adb shell dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", color = MaterialTheme.colorScheme.onTertiaryContainer, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } Text(text = "Device owner和Profile owner不能同时存在,强烈建议激活Device owner", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(isDeviceOwner(myDpm)){ Text(text = "Device owner创建其他用户后,这个应用会成为新用户的Profile owner", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } } @@ -181,11 +182,11 @@ fun DpmPermissions(navCtrl:NavHostController){ SelectionContainer { Text(text = "adb shell dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", color = MaterialTheme.colorScheme.onTertiaryContainer, - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(!isda){ Text(text = "使用此命令也会激活Device Admin", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } } @@ -194,48 +195,60 @@ fun DpmPermissions(navCtrl:NavHostController){ text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态", color = MaterialTheme.colorScheme.onErrorContainer, modifier = sections(MaterialTheme.colorScheme.errorContainer), - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium} + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium} ) } if(VERSION.SDK_INT>=30){ Column( modifier = sections() ) { - Text(text = "设备信息", style = MaterialTheme.typography.titleLarge) + Text(text = "设备信息", style = typography.titleLarge) val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile - Text("由组织拥有的受管理资料设备:$orgDevice") + Text("由组织拥有的受管理资料设备:$orgDevice",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ - Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}") + Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){ val financed = myDpm.isDeviceFinanced - Text("企业资产 : $financed") + Text("企业资产 : $financed",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(VERSION.SDK_INT>=33){ - Text("最小WiFi安全等级:${myDpm.minimumRequiredWifiSecurityLevel}") - Text("设备策略管理器角色:${myDpm.devicePolicyManagementRoleHolderPackage}") + Text("最小WiFi安全等级:${myDpm.minimumRequiredWifiSecurityLevel}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + Text("设备策略管理器角色:${myDpm.devicePolicyManagementRoleHolderPackage}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + } + val encryptionStatus = mapOf( + DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE to "未使用", + DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE to "正在使用", + DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED to "不支持", + DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY to "使用默认密钥", + DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER to "每个用户分别加密", + DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING to "未知" + ) + Text("加密状态:${encryptionStatus[myDpm.storageEncryptionStatus]}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) + if(isDeviceOwner(myDpm)&&VERSION.SDK_INT>=34){ + Text("MTE策略:${myDpm.mtePolicy}",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } } if(VERSION.SDK_INT>=31&&(isProfileOwner(myDpm)|| isDeviceOwner(myDpm))){ Column(modifier = sections()) { val specificId:String = myDpm.enrollmentSpecificId - Text(text = "设备唯一标识码", style = MaterialTheme.typography.titleLarge) - Text("(恢复出厂设置不变)") + Text(text = "设备唯一标识码", style = typography.titleLarge) + Text("(恢复出厂设置不变)",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) if(specificId!=""){ Text(specificId) Button(onClick = {myDpm.setOrganizationId(specificId)}) { Text("设置为组织ID") } }else{ - Text("你的设备不支持") + Text("你的设备不支持",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } } if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ Column(modifier = sections()) { - Text(text = "不受控制的账号类型", style = MaterialTheme.typography.titleLarge) - Text("作用未知") + Text(text = "不受控制的账号类型", style = typography.titleLarge) + Text("作用未知",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) var noManageAccount = myDpm.accountTypesWithManagementDisabled?.toMutableList() var accountlist by remember{ mutableStateOf("") } val refreshList = { @@ -250,30 +263,48 @@ fun DpmPermissions(navCtrl:NavHostController){ if(accountlist!=""){ Text(accountlist) }else{ - Text("列表为空 \n") + Text("列表为空 \n",style=if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } var inputText by remember{ mutableStateOf("") } TextField( value = inputText, onValueChange = {inputText=it}, label = {Text("账号类型")}, - modifier = Modifier.padding(bottom = 4.dp), + modifier = Modifier.fillMaxWidth().padding(bottom = 4.dp), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusManager.clearFocus()}) ) + if(isWear){ Button(onClick={focusManager.clearFocus() myDpm.setAccountManagementDisabled(myComponent,inputText,true) noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList() refreshList() - }){ + },modifier = Modifier.fillMaxWidth()){ Text("添加至列表") } Button(onClick={focusManager.clearFocus() myDpm.setAccountManagementDisabled(myComponent,inputText,false) noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList() refreshList() - }){ + },modifier = Modifier.fillMaxWidth()){ Text("从列表中移除") + }}else{ + Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ + Button(onClick={focusManager.clearFocus() + myDpm.setAccountManagementDisabled(myComponent,inputText,true) + noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList() + refreshList() + },modifier = Modifier.fillMaxWidth(0.48f)){ + Text("添加至列表") + } + Button(onClick={focusManager.clearFocus() + myDpm.setAccountManagementDisabled(myComponent,inputText,false) + noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList() + refreshList() + },modifier = Modifier.fillMaxWidth(0.92F)){ + Text("从列表中移除") + } + } } } } @@ -334,7 +365,7 @@ fun DpmPermissions(navCtrl:NavHostController){ } } } - Spacer(Modifier.padding(vertical = 20.dp)) + Spacer(Modifier.padding(vertical = 30.dp)) } } @@ -350,11 +381,12 @@ fun DeviceOwnerInfo( ){ Column(modifier = sections()) { val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) - Text(text = stringResource(name), style = MaterialTheme.typography.titleLarge, softWrap = false) + val isWear = sharedPref.getBoolean("isWear",false) + Text(text = stringResource(name), style = typography.titleLarge, softWrap = false) if(desc!=R.string.place_holder){ Text( text = stringResource(desc),modifier = Modifier.padding(top = 6.dp), - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } var inputContent by remember{ mutableStateOf(input()) } TextField( @@ -366,7 +398,8 @@ fun DeviceOwnerInfo( .padding(vertical = 4.dp) ) Row( - modifier = Modifier.padding(vertical = 6.dp) + modifier = Modifier.padding(vertical = if(isWear){2.dp}else{6.dp}), + horizontalArrangement = Arrangement.SpaceBetween ) { Button( onClick = { @@ -374,7 +407,8 @@ fun DeviceOwnerInfo( inputContent= input() fm.clearFocus() Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() - } + }, + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.6F)} ) { Text(text = "应用") } @@ -385,7 +419,8 @@ fun DeviceOwnerInfo( inputContent = input() fm.clearFocus() Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() - } + }, + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.95F)} ) { Text(text = "重置") } diff --git a/app/src/main/java/com/binbin/androidowner/Setting.kt b/app/src/main/java/com/binbin/androidowner/Setting.kt index c458b71..afd0010 100644 --- a/app/src/main/java/com/binbin/androidowner/Setting.kt +++ b/app/src/main/java/com/binbin/androidowner/Setting.kt @@ -3,7 +3,6 @@ package com.binbin.androidowner import android.content.Context import android.content.Intent import android.net.Uri -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -12,7 +11,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -21,12 +19,12 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController @Composable @@ -41,7 +39,11 @@ fun AppSetting(navCtrl:NavHostController){ checked = sharedPref.getBoolean("isWear",false), onCheckedChange = { sharedPref.edit().putBoolean("isWear",!sharedPref.getBoolean("isWear",false)).apply() - navCtrl.navigate("HomePage") + navCtrl.navigate("HomePage") { + popUpTo( + navCtrl.graph.findStartDestination().id + ) { saveState = true } + } } ) } diff --git a/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt index 280b61f..ed67782 100644 --- a/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt +++ b/app/src/main/java/com/binbin/androidowner/SystemUpdatePolicy.kt @@ -96,7 +96,8 @@ fun SysUpdatePolicy(myDpm:DevicePolicyManager,myComponent:ComponentName,myContex } Button( onClick = {myDpm.setSystemUpdatePolicy(myComponent,policy);Toast.makeText(myContext, "成功!", Toast.LENGTH_SHORT).show()}, - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm), + modifier = Modifier.fillMaxWidth() ) { Text("应用") } diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt index 1318109..323ac27 100644 --- a/app/src/main/java/com/binbin/androidowner/User.kt +++ b/app/src/main/java/com/binbin/androidowner/User.kt @@ -9,6 +9,7 @@ import android.os.UserHandle import android.os.UserManager import android.widget.Toast import androidx.activity.ComponentActivity +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -49,6 +50,8 @@ fun UserManage(){ val focusMgr = LocalFocusManager.current val currentUser = android.os.Process.myUserHandle() val userList = Test.returnUsers(myContext) + val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) + val isWear = sharedPref.getBoolean("isWear",false) Column(modifier = sections()) { Text(text = "用户信息", style = MaterialTheme.typography.titleLarge) Text("用户个数:${userList.size}") @@ -127,7 +130,9 @@ fun UserManage(){ value = userName, onValueChange = {userName=it}, label = {Text("用户名")}, - modifier = Modifier.padding(vertical = 4.dp), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), enabled = isDeviceOwner(myDpm) ) var selectedFlag by remember{ mutableIntStateOf(0) } @@ -138,10 +143,13 @@ fun UserManage(){ RadioButtonItem("启用所有系统应用",{selectedFlag==DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED},{selectedFlag=DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED}) } var newUserHandle: UserHandle? by remember{ mutableStateOf(null) } - Row { + Row(modifier = if(isWear){Modifier.horizontalScroll(rememberScrollState())}else{Modifier}) { Button( onClick = {newUserHandle=myDpm.createAndManageUser(myComponent,userName,myComponent,null,selectedFlag);focusMgr.clearFocus()}, - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm), + modifier = if(!isWear){ + if(newUserHandle==null){Modifier.fillMaxWidth(1F)}else{Modifier.fillMaxWidth(0.48F)} + }else{Modifier} ) { Text("创建") } @@ -154,7 +162,8 @@ fun UserManage(){ } else{ Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() } - } + }, + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.92F)} ) { Text("切换至新用户") } @@ -190,6 +199,7 @@ fun UserSessionMessage( val focusMgr = LocalFocusManager.current var msg by remember{ mutableStateOf(if(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)){ if(get()==null){""}else{get().toString()} }else{""}) } val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) + val isWear = sharedPref.getBoolean("isWear",false) Text(text = text, style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onPrimaryContainer) TextField( value = msg, @@ -197,10 +207,12 @@ fun UserSessionMessage( label = {Text(textField)}, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), - modifier = Modifier.padding(vertical = 6.dp), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 6.dp), enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) ) - Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = if(!sharedPref.getBoolean("isWear",false)){Arrangement.SpaceAround}else{Arrangement.SpaceBetween}) { + Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { focusMgr.clearFocus() @@ -208,11 +220,11 @@ fun UserSessionMessage( msg = if(get()==null){""}else{get().toString()} Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) + enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.65F)} ) { Text("应用") } - if(!sharedPref.getBoolean("isWear",false)){Spacer(Modifier.padding(horizontal = 5.dp))} Button( onClick = { focusMgr.clearFocus() @@ -220,7 +232,8 @@ fun UserSessionMessage( msg = if(get()==null){""}else{get().toString()} Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) + enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner), + modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.95F)} ) { Text("默认") } diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index 7730514..c8b796a 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -64,14 +65,14 @@ fun UserRestriction(){ ){ items(1){ Text(text = "打开开关后会禁用对应的功能",modifier = Modifier.padding(3.dp), - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) if(isProfileOwner(myDpm)){ Text(text = "Profile owner无法更改部分功能", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } if(isWear){ Text(text = "部分功能在手表上无效", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } } @@ -119,20 +120,22 @@ fun UserRestriction(){ items(1){ Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT<24){ Text(text = "以下功能需要安卓7或以上:数据漫游、修改用户头像、更换壁纸", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<26){ Text(text = "以下功能需要安卓8或以上:蓝牙、自动填充服务、添加/移除工作资料", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<28){ Text(text = "以下功能需要安卓9或以上:飞行模式、位置信息、调整亮度、修改语言、修改日期时间、修改屏幕超时、打印、分享至工作应用、切换用户", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<29){ Text(text = "以下功能需要安卓10或以上:配置私人DNS、内容捕获、内容建议", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<31){ Text(text = "以下功能需要安卓12或以上:切换摄像头使用权限、切换麦克风使用权限", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<33){ Text(text = "以下功能需要安卓13或以上:添加WiFi配置、分享设备管理器配置的WiFi、WiFi共享", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } - if(VERSION.SDK_INT<34){ Text(text = "以下功能需要安卓14或以上:2G信号、启用设备管理器、超宽频段无线电", - style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}) } + Column(modifier = Modifier.padding(horizontal = if(!isWear){10.dp}else{3.dp})) { + if(VERSION.SDK_INT<24){ Text(text = "以下功能需要安卓7或以上:数据漫游、修改用户头像、更换壁纸", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<26){ Text(text = "以下功能需要安卓8或以上:蓝牙、自动填充服务、添加/移除工作资料", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<28){ Text(text = "以下功能需要安卓9或以上:飞行模式、位置信息、调整亮度、修改语言、修改日期时间、修改屏幕超时、打印、分享至工作应用、切换用户", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<29){ Text(text = "以下功能需要安卓10或以上:配置私人DNS、内容捕获、内容建议", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<31){ Text(text = "以下功能需要安卓12或以上:切换摄像头使用权限、切换麦克风使用权限", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<33){ Text(text = "以下功能需要安卓13或以上:添加WiFi配置、分享设备管理器配置的WiFi、WiFi共享", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + if(VERSION.SDK_INT<34){ Text(text = "以下功能需要安卓14或以上:2G信号、启用设备管理器、超宽频段无线电", + style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium}) } + } Spacer(Modifier.padding(vertical = 30.dp)) } } @@ -145,7 +148,7 @@ fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){ text = txt, color = if(getSection()){MaterialTheme.colorScheme.onTertiaryContainer}else{MaterialTheme.colorScheme.onPrimaryContainer}, textAlign = TextAlign.Center, - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.headlineMedium}else{MaterialTheme.typography.titleLarge}, + style = if(!sharedPref.getBoolean("isWear",false)){typography.headlineMedium}else{typography.titleLarge}, modifier = Modifier .fillMaxWidth() .padding(horizontal = if(!sharedPref.getBoolean("isWear",false)){8.dp}else{4.dp}, @@ -194,7 +197,7 @@ private fun UserRestrictionItem( ) { Text( text = stringResource(itemName), - style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.titleLarge}else{MaterialTheme.typography.bodyLarge}, + style = if(!sharedPref.getBoolean("isWear",false)){typography.titleLarge}else{typography.bodyLarge}, color = MaterialTheme.colorScheme.onTertiaryContainer ) if(restrictionDescription!=""){Text(text = restrictionDescription, color = MaterialTheme.colorScheme.onSecondaryContainer)} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index da7fc6e..579a724 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -27,9 +27,9 @@ UI控制 授权与取消授权DeviceAdmin或DeviceOwner - 控制一些软件、硬件 + 锁屏和重启等 非DeviceOwner勿入 - 限制一些功能 + 管理当前用户可用的功能 防卸载 有时候不能用 @@ -102,7 +102,7 @@ 移除工作资料 密码 - 锁屏密码相关操作 + 更改锁屏密码,设置密码复杂度 留空可以清除密码,纯数字将使用PIN码 最大密码错误次数 达到该限制会恢复出厂设置 @@ -122,7 +122,7 @@ 用户名 提供支持的长消息 都是显示短消息,长消息不知道在哪里显示 - 禁止蓝牙分享通讯录 + 禁止蓝牙分享联系人 系统更新策略 管理系统更新策略 禁止锁屏(需无密码) diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index daf5c27..2bbddc5 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -3,5 +3,6 @@ \ No newline at end of file