diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c420934..0070adf 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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 { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4d2fad8..96379e0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + 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}) + } + } } } diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index d6024b9..59e218f 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -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)) } } diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index 4e88e2e..73479bb 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -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( @@ -120,6 +127,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( @@ -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,10 +255,12 @@ fun HomePageItem(name:Int, imgVector:Int, description:Int, navTo:String, myNav:N style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onPrimaryContainer ) - Text( - text = stringResource(description), - color = MaterialTheme.colorScheme.onPrimaryContainer - ) + if(!sharedPref.getBoolean("isWear",false)){ + Text( + text = stringResource(description), + color = MaterialTheme.colorScheme.onPrimaryContainer + ) + } } } } @@ -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 - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp) - .clip(RoundedCornerShape(14.dp)) - .background(color = bgColor) - .padding(vertical = 6.dp, horizontal = 10.dp) + 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) + } } diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index 520d857..7de22e5 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -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,24 +179,25 @@ 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("设置密码") - } - }else{ - Button( - onClick = { - val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag) - if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show() - }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } - confirmed=false - }, - enabled = confirmed, - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError) - ) { - Text("设置密码") + Text("应用") } } + Spacer(Modifier.padding(horizontal = 2.dp)) + Button( + onClick = { + val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag) + if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show() + }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } + confirmed=false + }, + enabled = confirmed, + colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error, contentColor = MaterialTheme.colorScheme.onError) + ) { + 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("应用") } } } diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index 6d8fe57..2013a36 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -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{""}, diff --git a/app/src/main/java/com/binbin/androidowner/Setting.kt b/app/src/main/java/com/binbin/androidowner/Setting.kt index ca92fa5..c458b71 100644 --- a/app/src/main/java/com/binbin/androidowner/Setting.kt +++ b/app/src/main/java/com/binbin/androidowner/Setting.kt @@ -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,11 +72,14 @@ fun AppSetting(){ ) Column { Text(text = "源代码", fontSize = 18.sp, fontWeight = FontWeight.SemiBold) - Text(text = "https://github.com/BinTianqi/AndroidOwner", color = MaterialTheme.colorScheme.onPrimaryContainer) - Text(text = "欢迎提交issue、给小星星") + 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)) } } diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt index db12029..1318109 100644 --- a/app/src/main/java/com/binbin/androidowner/User.kt +++ b/app/src/main/java/com/binbin/androidowner/User.kt @@ -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("默认") } } } diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index 5d4d103..7730514 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -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}) ) } } diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 2b068d1..b682104 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,30 +1,14 @@ - - - - - - - - + android:viewportWidth="24" + android:viewportHeight="24"> + - \ No newline at end of file + 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"/> + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755..7005cb8 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,6 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 6f3b755..7005cb8 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,6 +1,6 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..c3e2d28 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..afc205f Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..989c00c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d6..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..ce07022 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611d..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09f416e Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a307..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..0394bab Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a695..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..19e21c3 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 28d4b77..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..f3c1c9e Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f50..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..d2309df Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index aa7d642..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..825f273 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae3..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..606b9bd --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #383838 + \ No newline at end of file