adapt for wearables, change app icon

This commit is contained in:
BinTianqi
2024-01-24 15:52:27 +08:00
parent e75a0946db
commit 1f79994161
34 changed files with 379 additions and 163 deletions

View File

@@ -11,8 +11,8 @@ android {
applicationId = "com.binbin.androidowner"
minSdk = 23
targetSdk = 34
versionCode = 6
versionName = "1.5"
versionCode = 7
versionName = "2.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {

View File

@@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"/>
<uses-permission android:name="android.permission.REQUEST_PASSWORD_COMPLEXITY"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS"/>
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS"/>
<application

View File

@@ -48,6 +48,7 @@ fun ApplicationManage(){
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
var pkgName by remember { mutableStateOf("") }
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(
modifier = Modifier
.fillMaxWidth()
@@ -87,10 +88,10 @@ fun ApplicationManage(){
{b -> myDpm.setUninstallBlocked(myComponent,pkgName,b)})*/
Row(
modifier = sections(),
horizontalArrangement = Arrangement.SpaceAround
horizontalArrangement = if(!sharedPref.getBoolean("isWear",false)){Arrangement.SpaceAround}else{Arrangement.SpaceBetween}
) {
Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,false)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)) {
Text("取消防卸载")
Text("允许卸载")
}
Button(onClick = {myDpm.setUninstallBlocked(myComponent,pkgName,true)}, enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)) {
Text("防卸载")
@@ -155,6 +156,8 @@ private fun AppManageItem(
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
isEnabled = getMethod()
}
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
if(!sharedPref.getBoolean("isWear",false)){
Row(
modifier = sections(),
horizontalArrangement = Arrangement.SpaceBetween,
@@ -177,6 +180,28 @@ private fun AppManageItem(
},
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
)
}}else{
Column(
modifier = sections()
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
Text(
text = stringResource(itemName)
)
Switch(
checked = isEnabled,
onCheckedChange = {
setMethod(!isEnabled)
isEnabled = getMethod()
},
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
)
}
if(itemDesc!=R.string.place_holder){
Text(text = stringResource(itemDesc),
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
}
}

View File

@@ -2,6 +2,7 @@ package com.binbin.androidowner
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.os.Build.VERSION
import android.widget.Toast
import androidx.activity.ComponentActivity
@@ -39,6 +40,8 @@ fun DeviceControl(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false)
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
@@ -70,13 +73,17 @@ 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("你的设备不支持关闭USB信号")
Text(text = "你的设备不支持关闭USB信号",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
if(VERSION.SDK_INT>=28){
Column(modifier = sections()) {
Text(text = "锁屏方式", style = MaterialTheme.typography.titleLarge)
Text(text = "禁用需要无密码")
Row(
modifier = sections(),
horizontalArrangement = Arrangement.SpaceEvenly
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = if(!isWear){Arrangement.SpaceEvenly}else{Arrangement.SpaceBetween}
) {
Button(
onClick = {
@@ -88,9 +95,9 @@ fun DeviceControl(){
},
enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser)
) {
Text("禁用锁屏(需无密码)")
Text("禁用")
}
Spacer(Modifier.padding(horizontal = 5.dp))
if(!isWear){Spacer(Modifier.padding(horizontal = 5.dp))}
Button(
onClick = {
if(myDpm.setKeyguardDisabled(myComponent,false)){
@@ -101,13 +108,13 @@ fun DeviceControl(){
},
enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser)
) {
Text("启用锁屏")
}
Text("启用")
}
}}
}
Row(
horizontalArrangement = Arrangement.SpaceAround,
horizontalArrangement = if(!isWear){Arrangement.SpaceAround}else{Arrangement.SpaceBetween},
modifier = sections(),
) {
if(VERSION.SDK_INT>=24){
@@ -128,20 +135,25 @@ fun DeviceControl(){
Text(text = "WiFi MAC: $wifimac",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center)
}
if(VERSION.SDK_INT<24){
Text("重启和WiFi Mac需要API24")
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("备份服务需要API26")
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("自动设置时间和自动设置时区需要API30")
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("关闭USB信号需API31")}
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("隐藏状态栏需要API34")
Text(text = "隐藏状态栏需要API34",modifier=Modifier.fillMaxWidth(), textAlign = TextAlign.Center,
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
Button(
onClick = {myDpm.uninstallAllUserCaCerts(myComponent)},
onClick = {myDpm.uninstallAllUserCaCerts(myComponent);Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()},
modifier = Modifier.align(Alignment.CenterHorizontally),
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
) {
@@ -159,7 +171,8 @@ fun DeviceControl(){
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(text = "清空数据的不能是系统用户",
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Button(
onClick = {confirmed=!confirmed},
colors = ButtonDefaults.buttonColors(
@@ -210,6 +223,7 @@ private fun DeviceCtrlItem(
setMethod:(b:Boolean)->Unit
){
var isEnabled by remember{ mutableStateOf(false) }
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Row(
modifier = sections(),
horizontalArrangement = Arrangement.SpaceBetween,
@@ -218,18 +232,19 @@ private fun DeviceCtrlItem(
Row(
verticalAlignment = Alignment.CenterVertically
){
if(!sharedPref.getBoolean("isWear",false)){
Icon(
painter = painterResource(leadIcon),
contentDescription = null,
tint = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.padding(start = 5.dp, end = 9.dp)
)
)}
Column {
Text(
text = stringResource(itemName),
style = MaterialTheme.typography.titleLarge
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.titleLarge}else{MaterialTheme.typography.bodyLarge}
)
if(itemDesc!=R.string.place_holder){
if(itemDesc!=R.string.place_holder&&!sharedPref.getBoolean("isWear",false)){
Text(stringResource(itemDesc))
}
}

View File

@@ -1,6 +1,7 @@
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
@@ -12,15 +13,19 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
@@ -50,11 +55,11 @@ import androidx.navigation.compose.rememberNavController
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
setContent {
val sysUiCtrl = rememberSystemUiController()
@@ -87,8 +92,10 @@ fun MyScaffold(){
"AppSetting" to R.string.setting
)
val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Scaffold(
topBar = {
if(!sharedPref.getBoolean("isWear",false)){
TopAppBar(
title = {
Text(
@@ -121,6 +128,26 @@ fun MyScaffold(){
}
)
}
},
floatingActionButton = {
if(sharedPref.getBoolean("isWear",false)&&topBarName!=R.string.app_name){
FloatingActionButton(
onClick = {
navCtrl.navigate("HomePage") {
popUpTo(
navCtrl.graph.findStartDestination().id
) { saveState = true }
}
focusMgr.clearFocus()
},
modifier = Modifier.size(35.dp),
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.tertiary
) {
Icon(imageVector = Icons.Outlined.Home, contentDescription = null)
}
}
}
) {
NavHost(
navController = navCtrl,
@@ -136,7 +163,7 @@ fun MyScaffold(){
composable(route = "UserRestriction", content = { UserRestriction()})
composable(route = "UserManage", content = { UserManage()})
composable(route = "Password", content = { Password()})
composable(route = "AppSetting", content = { AppSetting()})
composable(route = "AppSetting", content = { AppSetting(navCtrl)})
}
}
}
@@ -150,15 +177,22 @@ fun HomePage(navCtrl:NavHostController){
val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner")
val activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(isda){"Device Admin"}else{""}
val isActivated = if(isdo||isda){"已激活"}else{"未激活"}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
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)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 5.dp, horizontal = 8.dp)
.padding(vertical = if (!sharedPref.getBoolean("isWear", false)) { 5.dp } else { 2.dp }, horizontal = if (!sharedPref.getBoolean("isWear", false)) { 8.dp } else { 4.dp })
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.tertiaryContainer)
.clickable(onClick = { navCtrl.navigate("Permissions") })
.padding(horizontal = 5.dp, vertical = 14.dp),
.padding(
horizontal = 5.dp,
vertical = if (!sharedPref.getBoolean("isWear", false)) { 14.dp } else { 1.dp }
),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -168,7 +202,7 @@ fun HomePage(navCtrl:NavHostController){
painterResource(R.drawable.block_fill0)
},
contentDescription = null,
modifier = Modifier.padding(horizontal = 13.dp),
modifier = Modifier.padding(horizontal = if(!sharedPref.getBoolean("isWear",false)){10.dp}else{6.dp}),
tint = MaterialTheme.colorScheme.tertiary
)
Column {
@@ -191,25 +225,28 @@ 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))
}
}
@Composable
fun HomePageItem(name:Int, imgVector:Int, description:Int, navTo:String, myNav:NavHostController){
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 5.dp, horizontal = 8.dp)
.padding(vertical = if (!sharedPref.getBoolean("isWear", false)) { 5.dp } else { 2.dp }, horizontal = if (!sharedPref.getBoolean("isWear", false)) { 8.dp } else { 4.dp })
.clip(RoundedCornerShape(15))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.clickable(onClick = { myNav.navigate(navTo) })
.padding(6.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(imgVector),
contentDescription = null,
modifier = Modifier.padding(horizontal = 10.dp),
modifier = Modifier.padding(horizontal = if(!sharedPref.getBoolean("isWear",false)){10.dp}else{6.dp}),
tint = MaterialTheme.colorScheme.primary
)
Column {
@@ -218,12 +255,14 @@ fun HomePageItem(name:Int, imgVector:Int, description:Int, navTo:String, myNav:N
style = MaterialTheme.typography.headlineSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
if(!sharedPref.getBoolean("isWear",false)){
Text(
text = stringResource(description),
color = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
}
}
@Composable
@@ -232,13 +271,14 @@ fun RadioButtonItem(
selected:()->Boolean,
operation:()->Unit
){
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(25))
.clickable(onClick = operation)
) {
RadioButton(selected = selected(), onClick = operation)
Text(text)
RadioButton(selected = selected(), onClick = operation,modifier=if(sharedPref.getBoolean("isWear",false)){Modifier.size(28.dp)}else{Modifier})
Text(text = text, style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
@@ -253,10 +293,19 @@ fun isProfileOwner(dpm:DevicePolicyManager): Boolean {
@SuppressLint("ModifierFactoryExtensionFunction")
@Composable
fun sections(bgColor:Color=MaterialTheme.colorScheme.primaryContainer):Modifier{
return Modifier
return if(!LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE).getBoolean("isWear",false)){
Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 4.dp)
.clip(RoundedCornerShape(14.dp))
.background(color = bgColor)
.padding(vertical = 6.dp, horizontal = 10.dp)
}else{
Modifier
.fillMaxWidth()
.padding(horizontal = 3.dp, vertical = 3.dp)
.clip(RoundedCornerShape(10.dp))
.background(color = bgColor)
.padding(vertical = 2.dp, horizontal = 3.dp)
}
}

View File

@@ -7,6 +7,7 @@ import android.content.Context
import android.os.Build.VERSION
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
@@ -51,9 +52,10 @@ fun Password(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
var newPwd by remember{ mutableStateOf("") }
var confirmed by remember{ mutableStateOf(false) }
val focusMgr = LocalFocusManager.current
val isWear = sharedPref.getBoolean("isWear",false)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
@@ -92,7 +94,7 @@ fun Password(){
modifier = sections()
) {
Text(text = "密码重置令牌", style = MaterialTheme.typography.titleLarge)
Row {
Row(modifier = if(!isWear){Modifier}else{Modifier.horizontalScroll(rememberScrollState())}) {
Button(
onClick = {
if(myDpm.clearResetPasswordToken(myComponent)){ Toast.makeText(myContext, "清除成功", Toast.LENGTH_SHORT).show()
@@ -125,13 +127,23 @@ fun Password(){
Text("激活")
}
}
Text(text = "(可以水平滚动)")
Text("没有密码时会自动激活令牌")
Text("有可能无法设置密码重置令牌,因机而异AVD上能用")
Text("有可能无法设置密码重置令牌,因机而异")
}
}
if(isWear){
Text(
text = "警告手表不支持带字母的密码也不支持超过4位的PIN码如果你设置了这样的密码你将无法解锁你的手表",
color = MaterialTheme.colorScheme.onErrorContainer,
modifier = sections(MaterialTheme.colorScheme.errorContainer),
style = MaterialTheme.typography.bodyMedium
)
}
Column(
modifier = sections()
) {
var confirmed by remember{ mutableStateOf(false) }
TextField(
value = newPwd,
onValueChange = {newPwd=it},
@@ -141,23 +153,23 @@ fun Password(){
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
)
Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 5.dp))
var resetPwdFlag by remember{ mutableStateOf(0) }
var resetPwdFlag by remember{ mutableIntStateOf(0) }
RadioButtonItem("RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT",
{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},
{resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY})
RadioButtonItem("",{resetPwdFlag==0},{resetPwdFlag=0})
Row {
Row(modifier = if(!isWear){Modifier}else{Modifier.horizontalScroll(rememberScrollState())}) {
Button(
onClick = {
if(newPwd.length>=4||newPwd.isEmpty()){ confirmed=!confirmed
}else{ Toast.makeText(myContext, "需要4位数字或字母", Toast.LENGTH_SHORT).show() }
}else{ Toast.makeText(myContext, "需要4位密码", Toast.LENGTH_SHORT).show() }
},
modifier = Modifier.padding(end = 10.dp),
modifier = Modifier.padding(end = 5.dp),
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm) || myDpm.isAdminActive(myComponent)
) {
Text("确认密码")
Text(text = if(confirmed){"取消"}else{"确定"})
}
if(VERSION.SDK_INT>=26){
Button(
@@ -167,11 +179,13 @@ fun Password(){
}else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() }
confirmed=false
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError)
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError),
enabled = confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))
) {
Text("设置密码")
Text("应用")
}
}else{
}
Spacer(Modifier.padding(horizontal = 2.dp))
Button(
onClick = {
val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag)
@@ -182,8 +196,7 @@ fun Password(){
enabled = confirmed,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError)
) {
Text("设置密码")
}
Text("应用(已弃用)")
}
}
}
@@ -198,23 +211,26 @@ fun Password(){
if(VERSION.SDK_INT>=31){
Column(modifier = sections()) {
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位"
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)"
).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 = "不是实际密码复杂度")
Text(text = "设置密码复杂度将会取代密码质量")
Text(text = "不是实际密码复杂度",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Text(text = "设置密码复杂度将会取代密码质量",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.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))
Text(text = "连续性密码重复6666或密码递增递减4321、2468", modifier = Modifier.padding(vertical = 3.dp),
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Button(
onClick = {
myDpm.requiredPasswordComplexity = selectedItem
@@ -245,9 +261,11 @@ fun Password(){
selectedItem=myDpm.getPasswordQuality(myComponent)
}
Text(text = "密码质量要求", style = MaterialTheme.typography.titleLarge)
Text(text = "不是实际密码质量")
Text(text = "不是实际密码质量",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
if(VERSION.SDK_INT>=31){
Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = MaterialTheme.colorScheme.error)
Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = MaterialTheme.colorScheme.error,
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first})
RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first})
@@ -257,7 +275,8 @@ fun Password(){
RadioButtonItem(passwordQuality[5].second,{selectedItem==passwordQuality[5].first},{selectedItem=passwordQuality[5].first})
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))
Text(text = "连续性密码重复6666或密码递增递减4321、2468", modifier = Modifier.padding(vertical = 3.dp),
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Button(
onClick = {
myDpm.setPasswordQuality(myComponent,selectedItem)
@@ -288,14 +307,22 @@ fun PasswordItem(
var inputContent by remember{ mutableStateOf(if(isDeviceOwner(myDpm)){getMethod()}else{""}) }
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(itemDesc),modifier=Modifier.padding(vertical = 2.dp))
Text(text= stringResource(itemDesc),modifier=Modifier.padding(vertical = 2.dp),
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
.padding(end = 8.dp)
.padding(
end = if (!sharedPref.getBoolean("isWear", false)) {
8.dp
} else {
0.dp
}
)
){
TextField(
value = inputContent,
@@ -313,6 +340,7 @@ fun PasswordItem(
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
enabled = isDeviceOwner(myDpm)
)
if(!sharedPref.getBoolean("isWear",false)){
IconButton(
onClick = { focusMgr.clearFocus() ; setMethod(inputContent) ; inputContentEdited=inputContent!=getMethod() },
enabled = isDeviceOwner(myDpm)&&ableToApply,
@@ -324,6 +352,13 @@ fun PasswordItem(
)
) {
Icon(imageVector = Icons.Outlined.Check, contentDescription = null)
}}
}
if(sharedPref.getBoolean("isWear",false)&&isDeviceOwner(myDpm)&&ableToApply){
Button(
onClick = {focusMgr.clearFocus() ; setMethod(inputContent) ; inputContentEdited=inputContent!=getMethod()}
) {
Text("应用")
}
}
}

View File

@@ -19,6 +19,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
@@ -35,6 +36,7 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat.startActivity
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
@@ -42,25 +44,34 @@ import androidx.navigation.NavHostController
@Composable
fun DpmPermissions(navCtrl:NavHostController){
//da:DeviceAdmin do:DeviceOwner
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val isda = myDpm.isAdminActive(myComponent)
val focusManager = LocalFocusManager.current
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false)
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
if(!myDpm.isAdminActive(myComponent)&&isWear){
Button(onClick = { activateDeviceAdmin(myContext,myComponent) },modifier = Modifier
.padding(horizontal = 3.dp)
.fillMaxWidth()) {
Text("激活Device admin")
}
}
Row(
modifier = sections(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(text = "Device Admin", style = MaterialTheme.typography.titleLarge)
Text(text = "Device Admin", fontSize = if(!isWear){22.sp}else{20.sp})
Text(if(isda){"已激活"}else{"未激活"})
}
if(!isWear)
if(isda){
Button(
onClick = {
@@ -85,12 +96,13 @@ fun DpmPermissions(navCtrl:NavHostController){
modifier = sections(MaterialTheme.colorScheme.tertiaryContainer),
horizontalAlignment = Alignment.Start
) {
Text("你可以在adb shell中使用以下命令激活Device Admin")
SelectionContainer {
Text("dpm set-active-admin com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
color = MaterialTheme.colorScheme.onTertiaryContainer)
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})
}
Text("或者进入设置 -> 安全 -> 更多安全设置 -> 设备管理应用 -> Android Owner")
Text(text = "或者进入设置(原生安卓) -> 安全 -> 更多安全设置 -> 设备管理应用 -> Android Owner",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
Row(
@@ -99,10 +111,10 @@ fun DpmPermissions(navCtrl:NavHostController){
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(text = "Profile Owner", style = MaterialTheme.typography.titleLarge)
Text(text = "Profile Owner", fontSize = if(!isWear){22.sp}else{20.sp})
Text(if(isProfileOwner(myDpm)){"已激活"}else{"未激活"})
}
if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24){
if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24&&!isWear){
Button(
onClick = {
myDpm.clearProfileOwner(myComponent)
@@ -123,15 +135,17 @@ fun DpmPermissions(navCtrl:NavHostController){
horizontalAlignment = Alignment.Start
) {
if(!isDeviceOwner(myDpm)){
Text("你可以在adb shell中使用以下命令激活Profile Owner")
SelectionContainer {
Text("dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
color = MaterialTheme.colorScheme.onTertiaryContainer)
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})
}
Text("一个设备只能有一个Device owner强烈建议激活Device owner")
Text(text = "Device owner和Profile owner不能同时存在强烈建议激活Device owner",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
if(isDeviceOwner(myDpm)){
Text("Device owner创建其他用户后这个应用会成为新用户的Profile owner")
Text(text = "Device owner创建其他用户后这个应用会成为新用户的Profile owner",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
}
@@ -141,10 +155,10 @@ fun DpmPermissions(navCtrl:NavHostController){
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(text = "Device Owner", style = MaterialTheme.typography.titleLarge)
Text(text = "Device Owner", fontSize = if(!isWear){22.sp}else{20.sp})
Text(if(isDeviceOwner(myDpm)){"已激活"}else{"未激活"})
}
if(isDeviceOwner(myDpm)){
if(isDeviceOwner(myDpm)&&!isWear){
Button(
onClick = {
myDpm.clearDeviceOwnerApp("com.binbin.androidowner")
@@ -164,13 +178,14 @@ fun DpmPermissions(navCtrl:NavHostController){
modifier = sections(MaterialTheme.colorScheme.tertiaryContainer),
horizontalAlignment = Alignment.Start
) {
Text("你可以在adb shell中使用以下命令激活Device Owner")
SelectionContainer {
Text(text = "dpm set-device-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver",
color = MaterialTheme.colorScheme.onTertiaryContainer)
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})
}
if(!isda){
Text("使用此命令也会激活Device Admin")
Text(text = "使用此命令也会激活Device Admin",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
}
@@ -178,7 +193,8 @@ fun DpmPermissions(navCtrl:NavHostController){
Text(
text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态",
color = MaterialTheme.colorScheme.onErrorContainer,
modifier = sections(MaterialTheme.colorScheme.errorContainer)
modifier = sections(MaterialTheme.colorScheme.errorContainer),
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium}
)
}
if(VERSION.SDK_INT>=30){
@@ -270,6 +286,54 @@ fun DpmPermissions(navCtrl:NavHostController){
DeviceOwnerInfo(R.string.long_support_msg,R.string.long_support_msg_desc,R.string.message,focusManager,myContext,
{myDpm.getLongSupportMessage(myComponent)},{content -> myDpm.setLongSupportMessage(myComponent,content)})
}
if(isWear&&(myDpm.isAdminActive(myComponent)||isProfileOwner(myDpm)||isDeviceOwner(myDpm))){
Column(modifier = sections(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(
onClick = {
myDpm.removeActiveAdmin(myComponent)
navCtrl.navigate("HomePage") {
popUpTo(
navCtrl.graph.findStartDestination().id
) { saveState = true }
}
},
colors = ButtonDefaults.buttonColors(contentColor = MaterialTheme.colorScheme.onError, containerColor = MaterialTheme.colorScheme.error),
enabled = myDpm.isAdminActive(myComponent)
) {
Text("撤销Device admin")
}
if(VERSION.SDK_INT>=24){
Button(
onClick = {
myDpm.clearProfileOwner(myComponent)
navCtrl.navigate("HomePage") {
popUpTo(
navCtrl.graph.findStartDestination().id
) { saveState = true }
}
},
colors = ButtonDefaults.buttonColors(contentColor = MaterialTheme.colorScheme.onError, containerColor = MaterialTheme.colorScheme.error),
enabled = isProfileOwner(myDpm)
) {
Text("撤销Profile owner")
}
}
Button(
onClick = {
myDpm.clearDeviceOwnerApp("com.binbin.androidowner")
navCtrl.navigate("HomePage") {
popUpTo(
navCtrl.graph.findStartDestination().id
) { saveState = true }
}
},
colors = ButtonDefaults.buttonColors(contentColor = MaterialTheme.colorScheme.onError, containerColor = MaterialTheme.colorScheme.error),
enabled = isDeviceOwner(myDpm)
) {
Text("撤销Device owner")
}
}
}
Spacer(Modifier.padding(vertical = 20.dp))
}
}
@@ -285,8 +349,13 @@ fun DeviceOwnerInfo(
output:(content:String?)->Unit
){
Column(modifier = sections()) {
Text(text = stringResource(name), style = MaterialTheme.typography.titleLarge)
if(desc!=R.string.place_holder){Text(text = stringResource(desc),modifier = Modifier.padding(top = 6.dp))}
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Text(text = stringResource(name), style = MaterialTheme.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})
}
var inputContent by remember{ mutableStateOf(input()) }
TextField(
value = if(inputContent!=null){ inputContent.toString() }else{""},

View File

@@ -5,6 +5,7 @@ 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
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -15,6 +16,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -25,28 +27,35 @@ 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.NavHostController
@Composable
fun AppSetting(){
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
fun AppSetting(navCtrl:NavHostController){
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
val myContext = LocalContext.current
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 4.dp)
.clip(RoundedCornerShape(14.dp))
.background(color = MaterialTheme.colorScheme.primaryContainer)
.padding(vertical = 6.dp)
) {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(modifier = sections()) {
Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 3.dp),horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
Text(text = "Wear", style = MaterialTheme.typography.titleLarge)
Switch(
checked = sharedPref.getBoolean("isWear",false),
onCheckedChange = {
sharedPref.edit().putBoolean("isWear",!sharedPref.getBoolean("isWear",false)).apply()
navCtrl.navigate("HomePage")
}
)
}
}
Column(modifier = sections()) {
Column(
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 12.dp)
) {
Text(text = "Android owner", style = MaterialTheme.typography.headlineMedium, color = MaterialTheme.colorScheme.onPrimaryContainer)
Text(text = "使用安卓的Device admin、Device owner 、Profile owner全方位掌控你的设备")
Text(text = "使用安卓的Device admin、Device owner 、Profile owner全方位掌控你的设备",
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
Spacer(Modifier.padding(vertical = 4.dp))
Text("这个应用只在AOSP和LineageOS上测试过不确保每个功能都在其它系统可用尤其是国内的魔改系统。")
Text(text = "这个应用只在AOSP和LineageOS上测试过不确保每个功能都在其它系统可用尤其是国内的魔改系统。",
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -63,12 +72,15 @@ fun AppSetting(){
)
Column {
Text(text = "源代码", fontSize = 18.sp, fontWeight = FontWeight.SemiBold)
if(!sharedPref.getBoolean("isWear",false)){
Text(text = "https://github.com/BinTianqi/AndroidOwner", color = MaterialTheme.colorScheme.onPrimaryContainer)
Text(text = "欢迎提交issue、给小星星")
}
}
}
}
Spacer(Modifier.padding(vertical = 30.dp))
}
}
fun shareLink(inputContext:Context,link:String){

View File

@@ -9,9 +9,11 @@ import android.os.UserHandle
import android.os.UserManager
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.text.KeyboardActions
@@ -187,6 +189,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)
Text(text = text, style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onPrimaryContainer)
TextField(
value = msg,
@@ -197,7 +200,7 @@ fun UserSessionMessage(
modifier = Modifier.padding(vertical = 6.dp),
enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)
)
Row {
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = if(!sharedPref.getBoolean("isWear",false)){Arrangement.SpaceAround}else{Arrangement.SpaceBetween}) {
Button(
onClick = {
focusMgr.clearFocus()
@@ -209,7 +212,7 @@ fun UserSessionMessage(
) {
Text("应用")
}
Spacer(Modifier.padding(horizontal = 5.dp))
if(!sharedPref.getBoolean("isWear",false)){Spacer(Modifier.padding(horizontal = 5.dp))}
Button(
onClick = {
focusMgr.clearFocus()
@@ -219,7 +222,7 @@ fun UserSessionMessage(
},
enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)
) {
Text("使用默认")
Text("默认")
}
}
}

View File

@@ -57,13 +57,21 @@ fun UserRestriction(){
var mediaVisible by remember{ mutableStateOf(false) }
var userVisible by remember{ mutableStateOf(false) }
var otherVisible by remember{ mutableStateOf(false) }
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false)
LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally
){
items(1){
Text("打开开关后会禁用对应的功能")
Text(text = "打开开关后会禁用对应的功能",modifier = Modifier.padding(3.dp),
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
if(isProfileOwner(myDpm)){
Text("Profile owner无法更改部分功能")
Text(text = "Profile owner无法更改部分功能",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
if(isWear){
Text(text = "部分功能在手表上无效",
style = if(!isWear){MaterialTheme.typography.bodyLarge}else{MaterialTheme.typography.bodyMedium})
}
}
@@ -111,13 +119,20 @@ fun UserRestriction(){
items(1){
Spacer(Modifier.padding(vertical = 5.dp))
if(VERSION.SDK_INT<24){ Text("以下功能需要安卓7或以上数据漫游、修改用户头像、更换壁纸") }
if(VERSION.SDK_INT<26){ Text("以下功能需要安卓8或以上蓝牙、自动填充服务、添加/移除工作资料") }
if(VERSION.SDK_INT<28){ Text("以下功能需要安卓9或以上:飞行模式、位置信息、调整亮度、修改语言、修改日期时间、修改屏幕超时、打印、分享至工作应用、切换用户") }
if(VERSION.SDK_INT<29){ Text("以下功能需要安卓10或以上配置私人DNS、内容捕获、内容建议") }
if(VERSION.SDK_INT<31){ Text("以下功能需要安卓12或以上:切换摄像头使用权限、切换麦克风使用权限") }
if(VERSION.SDK_INT<33){ Text("以下功能需要安卓13或以上添加WiFi配置、分享设备管理器配置的WiFi、WiFi共享") }
if(VERSION.SDK_INT<34){ Text("以下功能需要安卓14或以上:2G信号、启用设备管理器、超宽频段无线电") }
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}) }
Spacer(Modifier.padding(vertical = 30.dp))
}
}
@@ -125,14 +140,16 @@ fun UserRestriction(){
@Composable
fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Text(
text = txt,
color = if(getSection()){MaterialTheme.colorScheme.onTertiaryContainer}else{MaterialTheme.colorScheme.onPrimaryContainer},
textAlign = TextAlign.Center,
style = MaterialTheme.typography.headlineMedium,
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.headlineMedium}else{MaterialTheme.typography.titleLarge},
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 6.dp)
.padding(horizontal = if(!sharedPref.getBoolean("isWear",false)){8.dp}else{4.dp},
vertical = if(!sharedPref.getBoolean("isWear",false)){6.dp}else{3.dp})
.clip(RoundedCornerShape(15.dp))
.background(
color = if (getSection()) {
@@ -142,7 +159,7 @@ fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){
}
)
.clickable(onClick = setSection)
.padding(vertical = 8.dp)
.padding(vertical = if(!sharedPref.getBoolean("isWear",false)){8.dp}else{3.dp})
)
}
@@ -156,6 +173,7 @@ private fun UserRestrictionItem(
myDpm: DevicePolicyManager
){
var strictState by remember{ mutableStateOf(false) }
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Row(
modifier = sections(MaterialTheme.colorScheme.secondaryContainer),
verticalAlignment = Alignment.CenterVertically,
@@ -164,18 +182,19 @@ private fun UserRestrictionItem(
Row(
verticalAlignment = Alignment.CenterVertically
) {
if(!sharedPref.getBoolean("isWear",false)){
Icon(
painter = painterResource(leadIcon),
contentDescription = null,
modifier = Modifier.padding(start = 4.dp, end = 8.dp),
tint = MaterialTheme.colorScheme.secondary
)
)}
Column(
modifier = Modifier.align(Alignment.CenterVertically)
) {
Text(
text = stringResource(itemName),
style = MaterialTheme.typography.titleLarge,
style = if(!sharedPref.getBoolean("isWear",false)){MaterialTheme.typography.titleLarge}else{MaterialTheme.typography.bodyLarge},
color = MaterialTheme.colorScheme.onTertiaryContainer
)
if(restrictionDescription!=""){Text(text = restrictionDescription, color = MaterialTheme.colorScheme.onSecondaryContainer)}
@@ -203,7 +222,7 @@ private fun UserRestrictionItem(
strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction)
},
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm),
modifier = Modifier.padding(end = 5.dp)
modifier = Modifier.padding(end = if(!sharedPref.getBoolean("isWear",false)){5.dp}else{0.dp})
)
}
}

View File

@@ -1,30 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
android:viewportWidth="24"
android:viewportHeight="24">
<group android:scaleX="0.495"
android:scaleY="0.495"
android:translateX="6.06"
android:translateY="6.06">
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
android:fillColor="#FFFFFFFF"
android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/>
</group>
</vector>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#383838</color>
</resources>