extract all string resources

This commit is contained in:
BinTianqi
2024-03-03 13:11:26 +08:00
parent 01d6fef6de
commit e27d4b41b2
10 changed files with 502 additions and 346 deletions

View File

@@ -836,7 +836,7 @@ Profile owner无法禁用部分功能工作资料中部分功能无效wear
- (29) 内容捕获(作用未知) - (29) 内容捕获(作用未知)
- (29) 内容建议(作用未知) - (29) 内容建议(作用未知)
- 创建窗口比如Toast - 创建窗口比如Toast
- (24) 更换壁纸 - (24) 更换壁纸在MIUI上可能不起作用
- (34) 启用设备管理器设备管理器就是Device admin - (34) 启用设备管理器设备管理器就是Device admin
- (23) 娱乐(仅谷歌商店里的应用) - (23) 娱乐(仅谷歌商店里的应用)
- 修改账号设置 - 修改账号设置

View File

@@ -125,9 +125,9 @@ fun MyScaffold(){
"UserManage" to R.string.user_manage, "UserManage" to R.string.user_manage,
"ApplicationManage" to R.string.app_manage, "ApplicationManage" to R.string.app_manage,
"UserRestriction" to R.string.user_restrict, "UserRestriction" to R.string.user_restrict,
"Password" to R.string.password, "Password" to R.string.password_and_keyguard,
"AppSetting" to R.string.setting, "AppSetting" to R.string.setting,
"ShizukuActivate" to R.string.shizuku_activate "ShizukuActivate" to R.string.shizuku
) )
val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name val topBarName = topBarNameMap[backStackEntry?.destination?.route]?: R.string.app_name
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
@@ -245,7 +245,7 @@ fun HomePage(navCtrl:NavHostController){
HomePageItem(R.string.app_manage, R.drawable.apps_fill0, "ApplicationManage", navCtrl) HomePageItem(R.string.app_manage, R.drawable.apps_fill0, "ApplicationManage", navCtrl)
HomePageItem(R.string.user_restrict, R.drawable.manage_accounts_fill0, "UserRestriction", navCtrl) HomePageItem(R.string.user_restrict, R.drawable.manage_accounts_fill0, "UserRestriction", navCtrl)
HomePageItem(R.string.user_manage,R.drawable.account_circle_fill0,"UserManage",navCtrl) HomePageItem(R.string.user_manage,R.drawable.account_circle_fill0,"UserManage",navCtrl)
HomePageItem(R.string.password, R.drawable.password_fill0, "Password",navCtrl) HomePageItem(R.string.password_and_keyguard, R.drawable.password_fill0, "Password",navCtrl)
HomePageItem(R.string.setting, R.drawable.info_fill0, "AppSetting",navCtrl) HomePageItem(R.string.setting, R.drawable.info_fill0, "AppSetting",navCtrl)
Spacer(Modifier.padding(vertical = 20.dp)) Spacer(Modifier.padding(vertical = 20.dp))
} }

View File

@@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -45,19 +46,19 @@ fun ManagedProfile() {
Column(modifier = Modifier.verticalScroll(rememberScrollState())){ Column(modifier = Modifier.verticalScroll(rememberScrollState())){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = "信息", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.info), style = typography.titleLarge, color = titleColor)
if(VERSION.SDK_INT>=24){ if(VERSION.SDK_INT>=24){
if(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){ if(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
Text(text = "已是工作资料") Text(text = stringResource(R.string.is_already_work_profile))
}else{ }else{
Text(text = "可以创建工作资料:${myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE)}", style = bodyTextStyle) Text(text = stringResource(R.string.able_to_create_work_profile, myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE)), style = bodyTextStyle)
if(isDeviceOwner(myDpm)){ if(isDeviceOwner(myDpm)){
Text(text = "Device owner不能创建工作资料", style = bodyTextStyle) Text(text = stringResource(R.string.device_owner_cannot_create_work_profile), style = bodyTextStyle)
} }
} }
} }
if(VERSION.SDK_INT>=30){ if(VERSION.SDK_INT>=30){
Text(text = "由组织拥有的工作资料:${myDpm.isOrganizationOwnedDeviceWithManagedProfile}", style = bodyTextStyle) Text(text = stringResource(R.string.is_org_owned_profile, myDpm.isOrganizationOwnedDeviceWithManagedProfile), style = bodyTextStyle)
} }
if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent))){ if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent))){
Button( Button(
@@ -80,26 +81,25 @@ fun ManagedProfile() {
var expand by remember{mutableStateOf(false)} var expand by remember{mutableStateOf(false)}
Column(modifier = sections(colorScheme.tertiaryContainer,{expand=true},!expand).animateContentSize(animationSpec = scrollAnim())){ Column(modifier = sections(colorScheme.tertiaryContainer,{expand=true},!expand).animateContentSize(animationSpec = scrollAnim())){
if(expand){ if(expand){
Text(text = "组织拥有的工作资料", color = colorScheme.onTertiaryContainer, style = typography.titleLarge) Text(text = stringResource(R.string.org_owned_work_profile), color = colorScheme.onTertiaryContainer, style = typography.titleLarge)
SelectionContainer { SelectionContainer {
Text(text = "使用ADB执行以下命令或者使用Shizuku") Text(text = "使用ADB执行以下命令或者使用Shizuku")
Text( Text(
text = "adb shell \"dpm mark-profile-owner-on-organization-owned-device --user ${Binder.getCallingUid()/100000}" + text = stringResource(R.string.activate_org_profile_command, Binder.getCallingUid()/100000),
" com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"",
color = colorScheme.onTertiaryContainer, style = bodyTextStyle color = colorScheme.onTertiaryContainer, style = bodyTextStyle
) )
} }
}else{ }else{
Text(text = "成为组织拥有的工作资料", color = colorScheme.onTertiaryContainer) Text(text = stringResource(R.string.become_org_profile), color = colorScheme.onTertiaryContainer)
Text(text = "点击展开", style = bodyTextStyle) Text(text = stringResource(R.string.touch_to_view_command), style = bodyTextStyle)
} }
} }
} }
if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))){ if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))){
Column(modifier = sections()) { Column(modifier = sections()) {
Text(text = "工作资料", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.work_profile), style = typography.titleLarge, color = titleColor)
var skipEncrypt by remember{mutableStateOf(false)} var skipEncrypt by remember{mutableStateOf(false)}
if(VERSION.SDK_INT>=24){CheckBoxItem("跳过加密",{skipEncrypt},{skipEncrypt=!skipEncrypt})} if(VERSION.SDK_INT>=24){CheckBoxItem(stringResource(R.string.skip_encryption),{skipEncrypt},{skipEncrypt=!skipEncrypt})}
Button( Button(
onClick = { onClick = {
try { try {
@@ -113,12 +113,12 @@ fun ManagedProfile() {
if(VERSION.SDK_INT>=33){intent.putExtra(EXTRA_PROVISIONING_ALLOW_OFFLINE,true)} if(VERSION.SDK_INT>=33){intent.putExtra(EXTRA_PROVISIONING_ALLOW_OFFLINE,true)}
createManagedProfile.launch(intent) createManagedProfile.launch(intent)
}catch(e:ActivityNotFoundException){ }catch(e:ActivityNotFoundException){
Toast.makeText(myContext,"不支持",Toast.LENGTH_SHORT).show() Toast.makeText(myContext,myContext.getString(R.string.unsupported),Toast.LENGTH_SHORT).show()
} }
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("创建") Text(stringResource(R.string.create))
} }
} }
} }
@@ -127,7 +127,7 @@ fun ManagedProfile() {
Row(modifier = sections(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ Row(modifier = sections(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
var suspended by remember{mutableStateOf(false)} var suspended by remember{mutableStateOf(false)}
suspended = myDpm.getPersonalAppsSuspendedReasons(myComponent)!=PERSONAL_APPS_NOT_SUSPENDED suspended = myDpm.getPersonalAppsSuspendedReasons(myComponent)!=PERSONAL_APPS_NOT_SUSPENDED
Text(text = "挂起个人应用", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.suspend_personal_app), style = typography.titleLarge, color = titleColor)
Switch( Switch(
checked = suspended, checked = suspended,
onCheckedChange ={ onCheckedChange ={
@@ -142,24 +142,24 @@ fun ManagedProfile() {
Column(modifier = sections()){ Column(modifier = sections()){
var time by remember{mutableStateOf("")} var time by remember{mutableStateOf("")}
time = myDpm.getManagedProfileMaximumTimeOff(myComponent).toString() time = myDpm.getManagedProfileMaximumTimeOff(myComponent).toString()
Text(text = "资料关闭时间", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.profile_max_time_off), style = typography.titleLarge, color = titleColor)
Text(text = "工作资料处于关闭状态的时间达到该限制后会挂起个人应用0为无限制", style = bodyTextStyle) Text(text = stringResource(R.string.profile_max_time_out_desc), style = bodyTextStyle)
Text(text = "个人应用已经因此挂起:${myDpm.getPersonalAppsSuspendedReasons(myComponent)==PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT}") Text(text = stringResource(R.string.personal_app_suspended_because_timeout, myDpm.getPersonalAppsSuspendedReasons(myComponent)==PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT))
OutlinedTextField( OutlinedTextField(
value = time, onValueChange = {time=it}, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp), value = time, onValueChange = {time=it}, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp),
label = {Text("时间(ms)")}, label = {Text(stringResource(R.string.time_unit_ms))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()})
) )
Text(text = "不能少于72小时", style = bodyTextStyle) Text(text = stringResource(R.string.cannot_less_than_72_hours), style = bodyTextStyle)
Button( Button(
onClick = { onClick = {
myDpm.setManagedProfileMaximumTimeOff(myComponent,time.toLong()) myDpm.setManagedProfileMaximumTimeOff(myComponent,time.toLong())
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("应用") Text(stringResource(R.string.apply))
} }
} }
} }
@@ -167,7 +167,7 @@ fun ManagedProfile() {
if(isProfileOwner(myDpm)&&(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isManagedProfile(myComponent)))){ if(isProfileOwner(myDpm)&&(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isManagedProfile(myComponent)))){
Column(modifier = sections()){ Column(modifier = sections()){
var action by remember{mutableStateOf("")} var action by remember{mutableStateOf("")}
Text(text = "Intent过滤器", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.intent_filter), style = typography.titleLarge, color = titleColor)
OutlinedTextField( OutlinedTextField(
value = action, onValueChange = {action = it}, value = action, onValueChange = {action = it},
label = {Text("Action")}, label = {Text("Action")},
@@ -178,31 +178,31 @@ fun ManagedProfile() {
Button( Button(
onClick = { onClick = {
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter(action), FLAG_PARENT_CAN_ACCESS_MANAGED) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter(action), FLAG_PARENT_CAN_ACCESS_MANAGED)
Toast.makeText(myContext,"成功",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("添加(工作到个人)") Text(stringResource(R.string.add_intent_filter_work_to_personal))
} }
Button( Button(
onClick = { onClick = {
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter(action), FLAG_MANAGED_CAN_ACCESS_PARENT) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter(action), FLAG_MANAGED_CAN_ACCESS_PARENT)
Toast.makeText(myContext,"成功",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("添加(个人到工作)") Text(stringResource(R.string.add_intent_filter_personal_to_work))
} }
Button( Button(
onClick = { onClick = {
myDpm.clearCrossProfileIntentFilters(myComponent) myDpm.clearCrossProfileIntentFilters(myComponent)
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_MANAGED_CAN_ACCESS_PARENT) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_MANAGED_CAN_ACCESS_PARENT)
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_PARENT_CAN_ACCESS_MANAGED) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_PARENT_CAN_ACCESS_MANAGED)
Toast.makeText(myContext,"成功",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
){ ){
Text("清除所有过滤器") Text(stringResource(R.string.clear_cross_profile_filters))
} }
} }
} }
@@ -210,28 +210,28 @@ fun ManagedProfile() {
if(VERSION.SDK_INT>=31&&(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent))){ if(VERSION.SDK_INT>=31&&(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent))){
Column(modifier = sections()){ Column(modifier = sections()){
var orgId by remember{mutableStateOf("")} var orgId by remember{mutableStateOf("")}
Text(text = "组织ID", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.org_id), style = typography.titleLarge, color = titleColor)
OutlinedTextField( OutlinedTextField(
value = orgId, onValueChange = {orgId=it}, value = orgId, onValueChange = {orgId=it},
label = {Text("组织ID")}, label = {Text(stringResource(R.string.org_id))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp) modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp)
) )
AnimatedVisibility(orgId.length !in 6..64) { AnimatedVisibility(orgId.length !in 6..64) {
Text(text = "长度应在6~64个字符之间", style = bodyTextStyle) Text(text = stringResource(R.string.length_6_to_64), style = bodyTextStyle)
} }
Button( Button(
onClick = { onClick = {
myDpm.setOrganizationId(orgId) myDpm.setOrganizationId(orgId)
Toast.makeText(myContext,"成功",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
}, },
enabled = orgId.length in 6..64, enabled = orgId.length in 6..64,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
){ ){
Text("应用") Text(stringResource(R.string.apply))
} }
Text(text = "设置组织ID后才能获取设备唯一标识码", style = bodyTextStyle) Text(text = stringResource(R.string.get_specific_id_after_set_org_id), style = bodyTextStyle)
} }
} }
@@ -248,18 +248,18 @@ fun ActivateManagedProfile(navCtrl: NavHostController){
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_MANAGED_CAN_ACCESS_PARENT) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_MANAGED_CAN_ACCESS_PARENT)
myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_PARENT_CAN_ACCESS_MANAGED) myDpm.addCrossProfileIntentFilter(myComponent, IntentFilter("com.binbin.androidowner.MAIN_ACTION"), FLAG_PARENT_CAN_ACCESS_MANAGED)
Column(modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally){ Column(modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally){
Text(text = "激活工作资料", style = typography.titleLarge) Text(text = stringResource(R.string.activate_managed_profile), style = typography.titleLarge)
Text(text = "你还没有激活工作资料,请立即激活") Text(text = stringResource(R.string.activate_managed_profile_desc))
Button( Button(
onClick = { onClick = {
myDpm.setProfileEnabled(myComponent) myDpm.setProfileEnabled(myComponent)
navCtrl.popBackStack("HomePage",false) navCtrl.popBackStack("HomePage",false)
sharedPref.edit().putBoolean("ManagedProfileActivated",true).apply() sharedPref.edit().putBoolean("ManagedProfileActivated",true).apply()
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth().padding(8.dp) modifier = Modifier.fillMaxWidth().padding(8.dp)
) { ) {
Text("激活") Text(stringResource(R.string.activate))
} }
} }
} }

View File

@@ -74,8 +74,8 @@ fun Network(){
if(VERSION.SDK_INT>=33){ if(VERSION.SDK_INT>=33){
Column(modifier = sections()){ Column(modifier = sections()){
var selectedWifiSecLevel by remember{mutableIntStateOf(myDpm.minimumRequiredWifiSecurityLevel)} var selectedWifiSecLevel by remember{mutableIntStateOf(myDpm.minimumRequiredWifiSecurityLevel)}
Text(text = "要求最小WiFi安全等级", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.min_wifi_security_level), style = typography.titleLarge, color = titleColor)
RadioButtonItem("开放", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_OPEN}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_OPEN}) RadioButtonItem(stringResource(R.string.wifi_security_level_open), {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_OPEN}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_OPEN})
RadioButtonItem("WEP, WPA(2)-PSK", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_PERSONAL}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_PERSONAL}) RadioButtonItem("WEP, WPA(2)-PSK", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_PERSONAL}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_PERSONAL})
RadioButtonItem("WPA-EAP", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP}) RadioButtonItem("WPA-EAP", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP})
RadioButtonItem("WPA3-192bit", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192}) RadioButtonItem("WPA3-192bit", {selectedWifiSecLevel==DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192}, {selectedWifiSecLevel= DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192})
@@ -83,15 +83,13 @@ fun Network(){
enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile), enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile),
onClick = { onClick = {
myDpm.minimumRequiredWifiSecurityLevel=selectedWifiSecLevel myDpm.minimumRequiredWifiSecurityLevel=selectedWifiSecLevel
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
){ ){
Text("应用") Text(stringResource(R.string.apply))
} }
} }
}else{
Text(text = "Wifi安全等级需API33", modifier = Modifier.padding(vertical = 3.dp))
} }
if(VERSION.SDK_INT>=33&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){ if(VERSION.SDK_INT>=33&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){
@@ -112,13 +110,13 @@ fun Network(){
} }
var inited by remember{mutableStateOf(false)} var inited by remember{mutableStateOf(false)}
if(!inited){ refreshPolicy(); refreshList(); inited=true } if(!inited){ refreshPolicy(); refreshList(); inited=true }
Text(text = "WiFi SSID策略", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.wifi_ssid_policy), style = typography.titleLarge, color = titleColor)
RadioButtonItem("",{selectedPolicyType==-1},{selectedPolicyType=-1}) RadioButtonItem(stringResource(R.string.none),{selectedPolicyType==-1},{selectedPolicyType=-1})
RadioButtonItem("白名单",{selectedPolicyType==WIFI_SSID_POLICY_TYPE_ALLOWLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_ALLOWLIST}) RadioButtonItem(stringResource(R.string.whitelist),{selectedPolicyType==WIFI_SSID_POLICY_TYPE_ALLOWLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_ALLOWLIST})
RadioButtonItem("黑名单",{selectedPolicyType==WIFI_SSID_POLICY_TYPE_DENYLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_DENYLIST}) RadioButtonItem(stringResource(R.string.blacklist),{selectedPolicyType==WIFI_SSID_POLICY_TYPE_DENYLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_DENYLIST})
Column(modifier = Modifier.animateContentSize(scrollAnim()).horizontalScroll(rememberScrollState())){ Column(modifier = Modifier.animateContentSize(scrollAnim()).horizontalScroll(rememberScrollState())){
if(ssidList!=""){ if(ssidList!=""){
Text("SSID列表") Text(stringResource(R.string.ssid_list_is))
SelectionContainer{ SelectionContainer{
Text(text = ssidList, style = bodyTextStyle, color = colorScheme.onPrimaryContainer) Text(text = ssidList, style = bodyTextStyle, color = colorScheme.onPrimaryContainer)
} }
@@ -136,9 +134,9 @@ fun Network(){
Button( Button(
onClick = { onClick = {
if(inputSsid==""){ if(inputSsid==""){
Toast.makeText(myContext, "不能为空", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.cannot_be_empty), Toast.LENGTH_SHORT).show()
}else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){ }else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){
Toast.makeText(myContext, "重复", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.already_exist), Toast.LENGTH_SHORT).show()
}else{ }else{
ssidSet.add(WifiSsid.fromBytes(inputSsid.toByteArray())) ssidSet.add(WifiSsid.fromBytes(inputSsid.toByteArray()))
refreshList() refreshList()
@@ -147,23 +145,23 @@ fun Network(){
}, },
modifier = Modifier.fillMaxWidth(0.49F) modifier = Modifier.fillMaxWidth(0.49F)
) { ) {
Text("添加") Text(stringResource(R.string.add))
} }
Button( Button(
onClick = { onClick = {
if(inputSsid==""){ if(inputSsid==""){
Toast.makeText(myContext, "不能为空", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.cannot_be_empty), Toast.LENGTH_SHORT).show()
}else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){ }else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){
ssidSet.remove(WifiSsid.fromBytes(inputSsid.toByteArray())) ssidSet.remove(WifiSsid.fromBytes(inputSsid.toByteArray()))
inputSsid = "" inputSsid = ""
refreshList() refreshList()
}else{ }else{
Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.not_exist), Toast.LENGTH_SHORT).show()
} }
}, },
modifier = Modifier.fillMaxWidth(0.96F) modifier = Modifier.fillMaxWidth(0.96F)
) { ) {
Text("移除") Text(stringResource(R.string.remove))
} }
} }
Button( Button(
@@ -171,16 +169,16 @@ fun Network(){
focusMgr.clearFocus() focusMgr.clearFocus()
if(selectedPolicyType==-1){ if(selectedPolicyType==-1){
if(policy==null&&ssidSet.isNotEmpty()){ if(policy==null&&ssidSet.isNotEmpty()){
Toast.makeText(myContext, "请选择策略", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.please_select_a_policy), Toast.LENGTH_SHORT).show()
}else{ }else{
myDpm.wifiSsidPolicy = null myDpm.wifiSsidPolicy = null
refreshPolicy() refreshPolicy()
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
} }
}else{ }else{
myDpm.wifiSsidPolicy = if(ssidSet.size==0){ null }else{ WifiSsidPolicy(selectedPolicyType, ssidSet) } myDpm.wifiSsidPolicy = if(ssidSet.size==0){ null }else{ WifiSsidPolicy(selectedPolicyType, ssidSet) }
refreshPolicy() refreshPolicy()
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
} }
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
@@ -191,20 +189,20 @@ fun Network(){
} }
if(VERSION.SDK_INT>=29&&isDeviceOwner(myDpm)){ if(VERSION.SDK_INT>=29&&isDeviceOwner(myDpm)){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = "私人DNS", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.private_dns), style = typography.titleLarge, color = titleColor)
val dnsStatus = mapOf( val dnsStatus = mapOf(
DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN to "未知", DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN to stringResource(R.string.unknown),
DevicePolicyManager.PRIVATE_DNS_MODE_OFF to "关闭", DevicePolicyManager.PRIVATE_DNS_MODE_OFF to stringResource(R.string.disabled),
DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC to "自动", DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC to stringResource(R.string.auto),
DevicePolicyManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME to "指定主机名" DevicePolicyManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME to stringResource(R.string.dns_provide_hostname)
) )
val operationResult = mapOf( val operationResult = mapOf(
DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR to "成功", DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR to stringResource(R.string.success),
DevicePolicyManager.PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING to "主机不支持DNS over TLS", DevicePolicyManager.PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING to stringResource(R.string.host_not_serving_dns_tls),
DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING to "失败" DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING to stringResource(R.string.fail)
) )
var status by remember{mutableStateOf(dnsStatus[myDpm.getGlobalPrivateDnsMode(myComponent)])} var status by remember{mutableStateOf(dnsStatus[myDpm.getGlobalPrivateDnsMode(myComponent)])}
Text(text = "当前状态:$status") Text(text = stringResource(R.string.current_state, status?:stringResource(R.string.unknown)))
Button( Button(
onClick = { onClick = {
val result = myDpm.setGlobalPrivateDnsModeOpportunistic(myComponent) val result = myDpm.setGlobalPrivateDnsModeOpportunistic(myComponent)
@@ -213,14 +211,14 @@ fun Network(){
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("设为自动") Text(stringResource(R.string.set_to_auto))
} }
Spacer(Modifier.padding(vertical = 3.dp)) Spacer(Modifier.padding(vertical = 3.dp))
var inputHost by remember{mutableStateOf(myDpm.getGlobalPrivateDnsHost(myComponent) ?: "")} var inputHost by remember{mutableStateOf(myDpm.getGlobalPrivateDnsHost(myComponent) ?: "")}
OutlinedTextField( OutlinedTextField(
value = inputHost, value = inputHost,
onValueChange = {inputHost=it}, onValueChange = {inputHost=it},
label = {Text("DNS主机名")}, label = {Text(stringResource(R.string.dns_hostname))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp) modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp)
@@ -233,27 +231,27 @@ fun Network(){
result = myDpm.setGlobalPrivateDnsModeSpecifiedHost(myComponent,inputHost) result = myDpm.setGlobalPrivateDnsModeSpecifiedHost(myComponent,inputHost)
Toast.makeText(myContext, operationResult[result], Toast.LENGTH_SHORT).show() Toast.makeText(myContext, operationResult[result], Toast.LENGTH_SHORT).show()
}catch(e:IllegalArgumentException){ }catch(e:IllegalArgumentException){
Toast.makeText(myContext, "无效主机名", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.invalid_hostname), Toast.LENGTH_SHORT).show()
}catch(e:SecurityException){ }catch(e:SecurityException){
Toast.makeText(myContext, "安全错误", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.security_exception), Toast.LENGTH_SHORT).show()
}finally { }finally {
status = dnsStatus[myDpm.getGlobalPrivateDnsMode(myComponent)] status = dnsStatus[myDpm.getGlobalPrivateDnsMode(myComponent)]
} }
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("设置DNS主机") Text(stringResource(R.string.set_dns_host))
} }
} }
} }
if(VERSION.SDK_INT>=26&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)))){ if(VERSION.SDK_INT>=26&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)))){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = "收集网络日志", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.retrieve_net_logs), style = typography.titleLarge, color = titleColor)
Text(text = "功能开发中", style = bodyTextStyle) Text(text = stringResource(R.string.developing), style = bodyTextStyle)
Row(modifier=Modifier.fillMaxWidth().padding(horizontal=8.dp),horizontalArrangement=Arrangement.SpaceBetween,verticalAlignment=Alignment.CenterVertically){ Row(modifier=Modifier.fillMaxWidth().padding(horizontal=8.dp),horizontalArrangement=Arrangement.SpaceBetween,verticalAlignment=Alignment.CenterVertically){
var checked by remember{mutableStateOf(myDpm.isNetworkLoggingEnabled(myComponent))} var checked by remember{mutableStateOf(myDpm.isNetworkLoggingEnabled(myComponent))}
Text(text = "启用", style = typography.titleLarge) Text(text = stringResource(R.string.enabled), style = typography.titleLarge)
Switch( Switch(
checked = checked, checked = checked,
onCheckedChange = {myDpm.setNetworkLoggingEnabled(myComponent,!checked);checked = myDpm.isNetworkLoggingEnabled(myComponent)} onCheckedChange = {myDpm.setNetworkLoggingEnabled(myComponent,!checked);checked = myDpm.isNetworkLoggingEnabled(myComponent)}
@@ -264,15 +262,15 @@ fun Network(){
val log = myDpm.retrieveNetworkLogs(myComponent,1234567890) val log = myDpm.retrieveNetworkLogs(myComponent,1234567890)
if(log!=null){ if(log!=null){
for(i in log){ Log.d("NetLog",i.toString()) } for(i in log){ Log.d("NetLog",i.toString()) }
Toast.makeText(myContext,"已输出至Log",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
}else{ }else{
Log.d("NetLog","") Log.d("NetLog",myContext.getString(R.string.none))
Toast.makeText(myContext,"",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.none),Toast.LENGTH_SHORT).show()
} }
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("收集") Text(stringResource(R.string.retrieve))
} }
} }
} }
@@ -280,35 +278,35 @@ fun Network(){
if(VERSION.SDK_INT>=31&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))){ if(VERSION.SDK_INT>=31&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))){
Column(modifier = sections()){ Column(modifier = sections()){
var keyPair by remember{mutableStateOf("")} var keyPair by remember{mutableStateOf("")}
Text(text = "WiFi密钥对", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.wifi_keypair), style = typography.titleLarge, color = titleColor)
OutlinedTextField( OutlinedTextField(
value = keyPair, value = keyPair,
label = { Text("密钥对")}, label = { Text(stringResource(R.string.keypair))},
onValueChange = {keyPair = it}, onValueChange = {keyPair = it},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp) modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp)
) )
val isExist = try{myDpm.isKeyPairGrantedToWifiAuth(keyPair)}catch(e:java.lang.IllegalArgumentException){false} val isExist = try{myDpm.isKeyPairGrantedToWifiAuth(keyPair)}catch(e:java.lang.IllegalArgumentException){false}
Text("已存在$isExist") Text(stringResource(R.string.already_exist)+"$isExist")
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
Button( Button(
onClick = { onClick = {
val result = myDpm.grantKeyPairToWifiAuth(keyPair) val result = myDpm.grantKeyPairToWifiAuth(keyPair)
Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(if(result){R.string.success}else{R.string.fail}), Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth(0.49F) modifier = Modifier.fillMaxWidth(0.49F)
) { ) {
Text("添加") Text(stringResource(R.string.add))
} }
Button( Button(
onClick = { onClick = {
val result = myDpm.revokeKeyPairFromWifiAuth(keyPair) val result = myDpm.revokeKeyPairFromWifiAuth(keyPair)
Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(if(result){R.string.success}else{R.string.fail}), Toast.LENGTH_SHORT).show()
}, },
modifier = Modifier.fillMaxWidth(0.96F) modifier = Modifier.fillMaxWidth(0.96F)
) { ) {
Text("移除") Text(stringResource(R.string.remove))
} }
} }
} }
@@ -320,17 +318,17 @@ fun Network(){
var inputNum by remember{mutableStateOf("0")} var inputNum by remember{mutableStateOf("0")}
var nextStep by remember{mutableStateOf(false)} var nextStep by remember{mutableStateOf(false)}
val builder = Builder() val builder = Builder()
Text(text = "APN设置", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.apn_settings), style = typography.titleLarge, color = titleColor)
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
Text(text = "启用", style = typography.titleLarge) Text(text = stringResource(R.string.enable), style = typography.titleLarge)
Switch(checked = myDpm.isOverrideApnEnabled(myComponent), onCheckedChange = {myDpm.setOverrideApnsEnabled(myComponent,it)}) Switch(checked = myDpm.isOverrideApnEnabled(myComponent), onCheckedChange = {myDpm.setOverrideApnsEnabled(myComponent,it)})
} }
Text(text = "一共有${setting.size}个APN设置", style = bodyTextStyle) Text(text = stringResource(R.string.total_apn_amount, setting.size), style = bodyTextStyle)
if(setting.size>0){ if(setting.size>0){
Text(text = "选择一个你要修改的APN设置(1~${setting.size})或者输入0以新建APN设置", style = bodyTextStyle) Text(text = stringResource(R.string.select_a_apn_or_create, setting.size), style = bodyTextStyle)
TextField( TextField(
value = inputNum, value = inputNum,
label = { Text("序号")}, label = { Text("APN")},
onValueChange = {inputNum = it}, onValueChange = {inputNum = it},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
@@ -338,14 +336,14 @@ fun Network(){
enabled = !nextStep enabled = !nextStep
) )
}else{ }else{
Text(text = "当前没有APN设置你可以新建一个APN设置", style = bodyTextStyle) Text(text = stringResource(R.string.no_apn_you_should_create_one), style = bodyTextStyle)
} }
Button( Button(
onClick = {focusMgr.clearFocus(); nextStep=!nextStep}, onClick = {focusMgr.clearFocus(); nextStep=!nextStep},
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = inputNum!=""&&(nextStep||inputNum=="0"||setting[inputNum.toInt()-1]!=null) enabled = inputNum!=""&&(nextStep||inputNum=="0"||setting[inputNum.toInt()-1]!=null)
) { ) {
Text(if(nextStep){"上一步"}else{"下一步"}) Text(stringResource(if(nextStep){R.string.previous_step}else{R.string.next_step}))
} }
var result = Builder().build() var result = Builder().build()
AnimatedVisibility(nextStep) { AnimatedVisibility(nextStep) {
@@ -404,28 +402,28 @@ fun Network(){
TextField( TextField(
value = inputApnName, value = inputApnName,
onValueChange = {inputApnName=it}, onValueChange = {inputApnName=it},
label = {Text("名称")}, label = {Text(stringResource(R.string.name))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
Text(text = "启用", style = typography.titleLarge) Text(text = stringResource(R.string.enable), style = typography.titleLarge)
Switch(checked = carrierEnabled, onCheckedChange = {carrierEnabled=it}) Switch(checked = carrierEnabled, onCheckedChange = {carrierEnabled=it})
} }
Text(text = "用户名", style = typography.titleLarge) Text(text = stringResource(R.string.user_name), style = typography.titleLarge)
TextField( TextField(
value = user, value = user,
onValueChange = {user=it}, onValueChange = {user=it},
label = {Text("用户名")}, label = {Text(stringResource(R.string.user_name))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
if(VERSION.SDK_INT>=33){ if(VERSION.SDK_INT>=33){
Text(text = "资料ID", style = typography.titleLarge) Text(text = stringResource(R.string.profile_id), style = typography.titleLarge)
TextField( TextField(
value = profileId, value = profileId,
onValueChange = {profileId=it}, onValueChange = {profileId=it},
@@ -436,7 +434,7 @@ fun Network(){
) )
} }
Text(text = "验证类型", style = typography.titleLarge) Text(text = stringResource(R.string.auth_type), style = typography.titleLarge)
RadioButtonItem("",{selectedAuthType==AUTH_TYPE_NONE},{selectedAuthType=AUTH_TYPE_NONE}) RadioButtonItem("",{selectedAuthType==AUTH_TYPE_NONE},{selectedAuthType=AUTH_TYPE_NONE})
RadioButtonItem("CHAP",{selectedAuthType==AUTH_TYPE_CHAP},{selectedAuthType=AUTH_TYPE_CHAP}) RadioButtonItem("CHAP",{selectedAuthType==AUTH_TYPE_CHAP},{selectedAuthType=AUTH_TYPE_CHAP})
RadioButtonItem("PAP",{selectedAuthType==AUTH_TYPE_PAP},{selectedAuthType=AUTH_TYPE_PAP}) RadioButtonItem("PAP",{selectedAuthType==AUTH_TYPE_PAP},{selectedAuthType=AUTH_TYPE_PAP})
@@ -456,32 +454,32 @@ fun Network(){
) )
} }
Text(text = "APN类型", style = typography.titleLarge) Text(text = stringResource(R.string.apn_type), style = typography.titleLarge)
TextField( TextField(
value = apnTypeBitmask, value = apnTypeBitmask,
onValueChange = {apnTypeBitmask=it}, onValueChange = {apnTypeBitmask=it},
label = {Text("位掩码")}, label = {Text(stringResource(R.string.bitmask))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
Text(text = "描述", style = typography.titleLarge) Text(text = stringResource(R.string.description), style = typography.titleLarge)
TextField( TextField(
value = entryName, value = entryName,
onValueChange = {entryName=it}, onValueChange = {entryName=it},
label = {Text("文本")}, label = {Text(stringResource(R.string.description))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
Text(text = "MMS代理", style = typography.titleLarge) Text(text = stringResource(R.string.mms_proxy), style = typography.titleLarge)
if(VERSION.SDK_INT>=29){ if(VERSION.SDK_INT>=29){
TextField( TextField(
value = mmsProxyAddress, value = mmsProxyAddress,
onValueChange = {mmsProxyAddress=it}, onValueChange = {mmsProxyAddress=it},
label = {Text("地址")}, label = {Text(stringResource(R.string.address))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
@@ -490,18 +488,18 @@ fun Network(){
TextField( TextField(
value = mmsProxyPort, value = mmsProxyPort,
onValueChange = {mmsProxyPort=it}, onValueChange = {mmsProxyPort=it},
label = {Text("端口")}, label = {Text(stringResource(R.string.port))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
Text(text = "代理", style = typography.titleLarge) Text(text = stringResource(R.string.proxy), style = typography.titleLarge)
if(VERSION.SDK_INT>=29){ if(VERSION.SDK_INT>=29){
TextField( TextField(
value = proxyAddress, value = proxyAddress,
onValueChange = {proxyAddress=it}, onValueChange = {proxyAddress=it},
label = {Text("地址")}, label = {Text(stringResource(R.string.address))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
@@ -510,7 +508,7 @@ fun Network(){
TextField( TextField(
value = proxyPort, value = proxyPort,
onValueChange = {proxyPort=it}, onValueChange = {proxyPort=it},
label = {Text("端口")}, label = {Text(stringResource(R.string.port))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
@@ -552,11 +550,11 @@ fun Network(){
RadioButtonItem("GID",{mvnoType==MVNO_TYPE_GID},{mvnoType=MVNO_TYPE_GID}) RadioButtonItem("GID",{mvnoType==MVNO_TYPE_GID},{mvnoType=MVNO_TYPE_GID})
RadioButtonItem("ICCID",{mvnoType==MVNO_TYPE_ICCID},{mvnoType=MVNO_TYPE_ICCID}) RadioButtonItem("ICCID",{mvnoType==MVNO_TYPE_ICCID},{mvnoType=MVNO_TYPE_ICCID})
Text(text = "网络类型", style = typography.titleLarge) Text(text = stringResource(R.string.network_type), style = typography.titleLarge)
TextField( TextField(
value = networkTypeBitmask, value = networkTypeBitmask,
onValueChange = {networkTypeBitmask=it}, onValueChange = {networkTypeBitmask=it},
label = {Text("位掩码")}, label = {Text(stringResource(R.string.bitmask))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
@@ -572,11 +570,11 @@ fun Network(){
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
) )
Text(text = "密码", style = typography.titleLarge) Text(text = stringResource(R.string.password), style = typography.titleLarge)
TextField( TextField(
value = password, value = password,
onValueChange = {password=it}, onValueChange = {password=it},
label = {Text("密码")}, label = {Text(stringResource(R.string.password))},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
@@ -584,12 +582,12 @@ fun Network(){
if(VERSION.SDK_INT>=33){ if(VERSION.SDK_INT>=33){
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
Text(text = "持久的", style = typography.titleLarge) Text(text = stringResource(R.string.persistent), style = typography.titleLarge)
Switch(checked = persistent, onCheckedChange = {persistent=it}) Switch(checked = persistent, onCheckedChange = {persistent=it})
} }
} }
Text(text = "协议", style = typography.titleLarge) Text(text = stringResource(R.string.protocol), style = typography.titleLarge)
RadioButtonItem("IPV4",{protocol==PROTOCOL_IP},{protocol=PROTOCOL_IP}) RadioButtonItem("IPV4",{protocol==PROTOCOL_IP},{protocol=PROTOCOL_IP})
RadioButtonItem("IPV6",{protocol==PROTOCOL_IPV6},{protocol=PROTOCOL_IPV6}) RadioButtonItem("IPV6",{protocol==PROTOCOL_IPV6},{protocol=PROTOCOL_IPV6})
RadioButtonItem("IPV4/IPV6",{protocol==PROTOCOL_IPV4V6},{protocol=PROTOCOL_IPV4V6}) RadioButtonItem("IPV4/IPV6",{protocol==PROTOCOL_IPV4V6},{protocol=PROTOCOL_IPV4V6})
@@ -599,7 +597,7 @@ fun Network(){
RadioButtonItem("Unstructured",{protocol==PROTOCOL_UNSTRUCTURED},{protocol=PROTOCOL_UNSTRUCTURED}) RadioButtonItem("Unstructured",{protocol==PROTOCOL_UNSTRUCTURED},{protocol=PROTOCOL_UNSTRUCTURED})
} }
Text(text = "漫游协议", style = typography.titleLarge) Text(text = stringResource(R.string.roaming_protocol), style = typography.titleLarge)
RadioButtonItem("IPV4",{roamingProtocol==PROTOCOL_IP},{roamingProtocol=PROTOCOL_IP}) RadioButtonItem("IPV4",{roamingProtocol==PROTOCOL_IP},{roamingProtocol=PROTOCOL_IP})
RadioButtonItem("IPV6",{roamingProtocol==PROTOCOL_IPV6},{roamingProtocol=PROTOCOL_IPV6}) RadioButtonItem("IPV6",{roamingProtocol==PROTOCOL_IPV6},{roamingProtocol=PROTOCOL_IPV6})
RadioButtonItem("IPV4/IPV6",{roamingProtocol==PROTOCOL_IPV4V6},{roamingProtocol=PROTOCOL_IPV4V6}) RadioButtonItem("IPV4/IPV6",{roamingProtocol==PROTOCOL_IPV4V6},{roamingProtocol=PROTOCOL_IPV4V6})
@@ -641,7 +639,7 @@ fun Network(){
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(if(finalStep){"上一步"}else{"下一步"}) Text(stringResource(if(finalStep){R.string.previous_step}else{R.string.next_step}))
} }
AnimatedVisibility(finalStep) { AnimatedVisibility(finalStep) {
if(inputNum=="0"){ if(inputNum=="0"){
@@ -649,18 +647,18 @@ fun Network(){
onClick = {myDpm.addOverrideApn(myComponent,result)}, onClick = {myDpm.addOverrideApn(myComponent,result)},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("新建") Text(stringResource(R.string.create))
} }
}else{ }else{
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
Button( Button(
onClick = { onClick = {
val success = myDpm.updateOverrideApn(myComponent,id,result) val success = myDpm.updateOverrideApn(myComponent,id,result)
Toast.makeText(myContext, if(success){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(if(success){R.string.success}else{R.string.fail}), Toast.LENGTH_SHORT).show()
}, },
Modifier.fillMaxWidth(0.49F) Modifier.fillMaxWidth(0.49F)
){ ){
Text("更新") Text(stringResource(R.string.update))
} }
Button( Button(
onClick = { onClick = {
@@ -669,7 +667,7 @@ fun Network(){
}, },
Modifier.fillMaxWidth(0.96F) Modifier.fillMaxWidth(0.96F)
){ ){
Text("移除") Text(stringResource(R.string.remove))
} }
} }
} }

View File

@@ -52,14 +52,14 @@ fun Password(){
) { ) {
val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) }
Text( Text(
text = "以下操作可能会造成不可挽回的损失,请先备份好数据。执行操作时一定要谨慎!!!", text = stringResource(R.string.password_warning),
color = colorScheme.onErrorContainer, color = colorScheme.onErrorContainer,
modifier = sections(colorScheme.errorContainer), modifier = sections(colorScheme.errorContainer),
style=bodyTextStyle style=bodyTextStyle
) )
if(isWear){ if(isWear){
Text( Text(
text = "警告手表不支持带字母的密码也不支持超过4位的PIN码如果你设置了这样的密码或密码复杂度要求你将无法解锁你的手表", text = stringResource(R.string.password_wearos_warning),
color = colorScheme.onErrorContainer, color = colorScheme.onErrorContainer,
modifier = sections(colorScheme.errorContainer), modifier = sections(colorScheme.errorContainer),
style = typography.bodyMedium style = typography.bodyMedium
@@ -69,88 +69,87 @@ fun Password(){
Column(modifier = sections()) { Column(modifier = sections()) {
if(VERSION.SDK_INT>=29){ if(VERSION.SDK_INT>=29){
val passwordComplexity = mapOf( val passwordComplexity = mapOf(
PASSWORD_COMPLEXITY_NONE to "无(允许不设密码)", PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none),
PASSWORD_COMPLEXITY_LOW to "低(允许图案和连续性)", PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low),
PASSWORD_COMPLEXITY_MEDIUM to "无连续性至少4位", PASSWORD_COMPLEXITY_MEDIUM to stringResource(R.string.password_complexity_medium),
PASSWORD_COMPLEXITY_HIGH to "无连续性至少6位" PASSWORD_COMPLEXITY_HIGH to stringResource(R.string.password_complexity_high)
) )
val pwdComplex = passwordComplexity[myDpm.passwordComplexity] val pwdComplex = passwordComplexity[myDpm.passwordComplexity]
Text(text = "当前密码复杂度:$pwdComplex",style=bodyTextStyle) Text(text = stringResource(R.string.current_password_complexity_is, pwdComplex?:stringResource(R.string.unknown)),style=bodyTextStyle)
} }
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
Text("密码达到要求:${myDpm.isActivePasswordSufficient}",style=bodyTextStyle) Text(stringResource(R.string.is_password_sufficient, myDpm.isActivePasswordSufficient),style=bodyTextStyle)
} }
val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts
Text(text = "密码已错误次数:$pwdFailedAttempts",style=bodyTextStyle) Text(text = stringResource(R.string.password_failed_attempts_is, pwdFailedAttempts),style=bodyTextStyle)
if(VERSION.SDK_INT>=28&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){ if(VERSION.SDK_INT>=28&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent) val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent)
Text("个人与工作应用密码一致:$unifiedPwd",style=bodyTextStyle) Text(stringResource(R.string.is_using_unified_password, unifiedPwd),style=bodyTextStyle)
} }
} }
} }
if(VERSION.SDK_INT>=26){ if(VERSION.SDK_INT>=26){
Column(horizontalAlignment = Alignment.Start, modifier = sections()) { Column(horizontalAlignment = Alignment.Start, modifier = sections()) {
Text(text = "密码重置令牌", style = typography.titleLarge,color = titleColor) Text(text = stringResource(R.string.reset_password_token), style = typography.titleLarge,color = titleColor)
Row( Row(
modifier = if(!isWear){Modifier.fillMaxWidth()}else{Modifier.horizontalScroll(rememberScrollState())}, modifier = if(!isWear){Modifier.fillMaxWidth()}else{Modifier.horizontalScroll(rememberScrollState())},
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
){ ){
Button( Button(
onClick = { onClick = {
if(myDpm.clearResetPasswordToken(myComponent)){ Toast.makeText(myContext, "清除成功", Toast.LENGTH_SHORT).show() if(myDpm.clearResetPasswordToken(myComponent)){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}else{ Toast.makeText(myContext, "清除失败", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
}, },
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.32F)}, modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.32F)},
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm) enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm)
) { ) {
Text("清除") Text(stringResource(R.string.clear))
} }
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))} if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
Button( Button(
onClick = { onClick = {
try { try {
if(myDpm.setResetPasswordToken(myComponent, myByteArray)){ if(myDpm.setResetPasswordToken(myComponent, myByteArray)){
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}else{ }else{
Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show()
} }
}catch(e:SecurityException){ }catch(e:SecurityException){
Toast.makeText(myContext, "失败(安全异常)", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.security_exception), Toast.LENGTH_SHORT).show()
} }
}, },
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm), enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.47F)} modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.47F)}
) { ) {
Text("设置") Text(stringResource(R.string.set))
} }
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))} if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
Button( Button(
onClick = { onClick = {
if(!myDpm.isResetPasswordTokenActive(myComponent)){ if(!myDpm.isResetPasswordTokenActive(myComponent)){
try{ activateToken(myContext) try{ activateToken(myContext) }
}catch(e:NullPointerException){ Toast.makeText(myContext, "请先设置令牌", Toast.LENGTH_SHORT).show() } catch(e:NullPointerException){ Toast.makeText(myContext, myContext.getString(R.string.please_set_a_token), Toast.LENGTH_SHORT).show() }
}else{ Toast.makeText(myContext, "已经激活", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, "已经激活", Toast.LENGTH_SHORT).show() }
}, },
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm), enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.88F)} modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.88F)}
) { ) {
Text("激活") Text(stringResource(R.string.activate))
} }
} }
if(isWear){ Text(text = "(可以水平滚动)",style=typography.bodyMedium) } Text(stringResource(R.string.activate_token_not_required_when_no_password),style=bodyTextStyle)
Text("没有密码时会自动激活令牌",style=bodyTextStyle)
} }
} }
Column( Column(
modifier = sections() modifier = sections()
) { ) {
var confirmed by remember{ mutableStateOf(false) } var confirmed by remember{ mutableStateOf(false) }
Text(text = "修改密码",style = typography.titleLarge,color = titleColor) Text(text = stringResource(R.string.reset_password),style = typography.titleLarge,color = titleColor)
OutlinedTextField( OutlinedTextField(
value = newPwd, value = newPwd,
onValueChange = {newPwd=it}, onValueChange = {newPwd=it},
enabled = !confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)), enabled = !confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)),
label = { Text("密码")}, label = { Text(stringResource(R.string.password))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().padding(vertical = if(isWear){0.dp}else{5.dp}).fillMaxWidth() modifier = Modifier.focusable().padding(vertical = if(isWear){0.dp}else{5.dp}).fillMaxWidth()
@@ -158,14 +157,17 @@ fun Password(){
Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 3.dp),style=bodyTextStyle) Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 3.dp),style=bodyTextStyle)
var resetPwdFlag by remember{ mutableIntStateOf(0) } var resetPwdFlag by remember{ mutableIntStateOf(0) }
if(VERSION.SDK_INT>=23){ if(VERSION.SDK_INT>=23){
RadioButtonItem("启动(boot)时不要求密码", {resetPwdFlag==RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, {resetPwdFlag=RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}) RadioButtonItem(
stringResource(R.string.do_not_ask_credentials_on_boot),
{resetPwdFlag==RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, {resetPwdFlag=RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}
)
} }
RadioButtonItem("不允许其他设备管理员重置密码直至用户输入一次密码",{resetPwdFlag==RESET_PASSWORD_REQUIRE_ENTRY}, {resetPwdFlag=RESET_PASSWORD_REQUIRE_ENTRY}) RadioButtonItem(stringResource(R.string.reset_password_require_entry),{resetPwdFlag==RESET_PASSWORD_REQUIRE_ENTRY}, {resetPwdFlag=RESET_PASSWORD_REQUIRE_ENTRY})
RadioButtonItem("",{resetPwdFlag==0},{resetPwdFlag=0}) RadioButtonItem(stringResource(R.string.none),{resetPwdFlag==0},{resetPwdFlag=0})
Button( Button(
onClick = { onClick = {
if(newPwd.length>=4||newPwd.isEmpty()){ confirmed=!confirmed if(newPwd.length>=4||newPwd.isEmpty()){ confirmed=!confirmed
}else{ Toast.makeText(myContext, "需要4位密码", Toast.LENGTH_SHORT).show() } }else{ Toast.makeText(myContext, myContext.getString(R.string.require_4_digit_password), Toast.LENGTH_SHORT).show() }
}, },
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm) || myDpm.isAdminActive(myComponent), enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm) || myDpm.isAdminActive(myComponent),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@@ -174,35 +176,35 @@ fun Password(){
contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError } contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError }
) )
) { ) {
Text(text = if(confirmed){"取消"}else{"确定"}) Text(text = stringResource(if(confirmed){R.string.cancel}else{R.string.confirm}))
} }
if(VERSION.SDK_INT>=26){ if(VERSION.SDK_INT>=26){
Button( Button(
onClick = { onClick = {
val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,resetPwdFlag) val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show();newPwd=""} if(resetSuccess){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show();newPwd=""}
else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
confirmed=false confirmed=false
}, },
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError),
enabled = confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)), enabled = confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("使用令牌重置密码") Text(stringResource(R.string.reset_password_with_token))
} }
} }
Button( Button(
onClick = { onClick = {
val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag) val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show();newPwd=""} if(resetSuccess){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show(); newPwd=""}
else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
confirmed=false confirmed=false
}, },
enabled = confirmed, enabled = confirmed,
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("重置密码(弃用)") Text(stringResource(R.string.reset_password_deprecated))
} }
} }
@@ -212,23 +214,22 @@ fun Password(){
{myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) }) {myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) })
PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield,true, PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield,true,
{myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) }) {myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) })
PasswordItem(R.string.max_time_to_lock,R.string.max_time_to_lock_desc,R.string.max_time_to_lock_textfield,true, PasswordItem(R.string.max_time_to_lock,R.string.max_time_to_lock_desc,R.string.time_unit_ms,true,
{myDpm.getMaximumTimeToLock(myComponent).toString()},{ic -> myDpm.setMaximumTimeToLock(myComponent,ic.toLong())}) {myDpm.getMaximumTimeToLock(myComponent).toString()},{ic -> myDpm.setMaximumTimeToLock(myComponent,ic.toLong())})
if(VERSION.SDK_INT>=31){ if(VERSION.SDK_INT>=31){
Column(modifier = sections()) { Column(modifier = sections()) {
val passwordComplexity = mapOf( val passwordComplexity = mapOf(
PASSWORD_COMPLEXITY_NONE to "无(允许不设密码)", PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none),
PASSWORD_COMPLEXITY_LOW to "低(允许图案和连续性)", PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low),
PASSWORD_COMPLEXITY_MEDIUM to "无连续性至少4位", PASSWORD_COMPLEXITY_MEDIUM to stringResource(R.string.password_complexity_medium),
PASSWORD_COMPLEXITY_HIGH to "无连续性至少6位" PASSWORD_COMPLEXITY_HIGH to stringResource(R.string.password_complexity_high)
).toList() ).toList()
var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) } var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) }
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
selectedItem=myDpm.requiredPasswordComplexity selectedItem=myDpm.requiredPasswordComplexity
} }
Text(text = "密码复杂度要求", style = typography.titleLarge,color = titleColor) Text(text = stringResource(R.string.required_password_complexity), style = typography.titleLarge,color = titleColor)
Text(text = "不是实际密码复杂度", style = bodyTextStyle)
RadioButtonItem(passwordComplexity[0].second,{selectedItem==passwordComplexity[0].first},{selectedItem=passwordComplexity[0].first}) 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[1].second,{selectedItem==passwordComplexity[1].first},{selectedItem=passwordComplexity[1].first})
RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first}) RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first})
@@ -236,24 +237,24 @@ fun Password(){
if(isWear){ if(isWear){
colorScheme.error}else{ colorScheme.error}else{
colorScheme.onBackground}) colorScheme.onBackground})
Text(text = "连续性密码重复6666或密码递增递减4321、2468", modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle) Text(text = stringResource(R.string.password_ordered_desc), modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle)
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
Button( Button(
onClick = { onClick = {
myDpm.requiredPasswordComplexity = selectedItem myDpm.requiredPasswordComplexity = selectedItem
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}, },
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm), enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm),
modifier = if(isWear){Modifier.fillMaxWidth()}else{Modifier.fillMaxWidth(0.4F)} modifier = if(isWear){Modifier.fillMaxWidth()}else{Modifier.fillMaxWidth(0.4F)}
) { ) {
Text(text = "应用") Text(text = stringResource(R.string.apply))
} }
if(!isWear){ if(!isWear){
Button( Button(
onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}, onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))},
modifier = Modifier.fillMaxWidth(0.95F) modifier = Modifier.fillMaxWidth(0.95F)
){ ){
Text("要求设置新密码") Text(stringResource(R.string.require_set_new_password))
} }
} }
} }
@@ -262,7 +263,7 @@ fun Password(){
onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}, onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
){ ){
Text("要求设置新密码") Text(stringResource(R.string.require_set_new_password))
} }
} }
} }
@@ -306,25 +307,25 @@ fun Password(){
} }
calculateCustomFeature() calculateCustomFeature()
} }
Text(text = "锁屏功能", style = typography.titleLarge) Text(text = stringResource(R.string.keyguard_disabled_features), style = typography.titleLarge)
RadioButtonItem("允许全部",{state==0},{state=0}) RadioButtonItem(stringResource(R.string.enable_all),{state==0},{state=0})
RadioButtonItem("禁用全部",{state==1},{state=1}) RadioButtonItem(stringResource(R.string.disable_all),{state==1},{state=1})
RadioButtonItem("自定义",{state==2},{state=2}) RadioButtonItem(stringResource(R.string.custom),{state==2},{state=2})
AnimatedVisibility(state==2) { AnimatedVisibility(state==2) {
Column { Column {
CheckBoxItem("禁用小工具(安卓5以下)",{widgets},{widgets=!widgets}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_widgets),{widgets},{widgets=!widgets})
CheckBoxItem("禁用相机",{camera},{camera=!camera}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_camera),{camera},{camera=!camera})
CheckBoxItem("禁用通知",{notification},{notification=!notification}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_notification),{notification},{notification=!notification})
CheckBoxItem("禁用未经编辑的通知",{unredacted},{unredacted=!unredacted}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_unredacted_notification),{unredacted},{unredacted=!unredacted})
CheckBoxItem("禁用可信代理",{agents},{agents=!agents}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_trust_agents),{agents},{agents=!agents})
CheckBoxItem("禁用指纹解锁",{fingerprint},{fingerprint=!fingerprint}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_fingerprint),{fingerprint},{fingerprint=!fingerprint})
if(VERSION.SDK_INT>=24){ CheckBoxItem("禁止远程输入(弃用)",{remote}, {remote=!remote}) } if(VERSION.SDK_INT>=24){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_remote_input),{remote}, {remote=!remote}) }
if(VERSION.SDK_INT>=28){ if(VERSION.SDK_INT>=28){
CheckBoxItem("禁用人脸解锁",{face},{face=!face}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_face),{face},{face=!face})
CheckBoxItem("禁用虹膜解锁(?)",{iris},{iris=!iris}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_iris),{iris},{iris=!iris})
CheckBoxItem("禁用生物识别",{biometrics},{biometrics=!biometrics}) CheckBoxItem(stringResource(R.string.keyguard_disabled_features_biometrics),{biometrics},{biometrics=!biometrics})
} }
if(VERSION.SDK_INT>=34){ CheckBoxItem("禁用快捷方式",{shortcuts},{shortcuts=!shortcuts}) } if(VERSION.SDK_INT>=34){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_shortcuts),{shortcuts},{shortcuts=!shortcuts}) }
} }
} }
Button( Button(
@@ -346,13 +347,13 @@ fun Password(){
if(widgets){result+=KEYGUARD_DISABLE_WIDGETS_ALL} if(widgets){result+=KEYGUARD_DISABLE_WIDGETS_ALL}
} }
myDpm.setKeyguardDisabledFeatures(myComponent,result) myDpm.setKeyguardDisabledFeatures(myComponent,result)
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
calculateCustomFeature() calculateCustomFeature()
}, },
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm), enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = "应用") Text(text = stringResource(R.string.apply))
} }
} }
@@ -367,23 +368,22 @@ fun Password(){
} }
Column(modifier = sections(onClick = {passwordQualityExpand=true;launchScrollDown=true}, clickable = !passwordQualityExpand).animateContentSize(animationSpec = scrollAnim())) { Column(modifier = sections(onClick = {passwordQualityExpand=true;launchScrollDown=true}, clickable = !passwordQualityExpand).animateContentSize(animationSpec = scrollAnim())) {
val passwordQuality = mapOf( val passwordQuality = mapOf(
PASSWORD_QUALITY_UNSPECIFIED to "未指定", PASSWORD_QUALITY_UNSPECIFIED to stringResource(R.string.password_quality_unspecified),
PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度", PASSWORD_QUALITY_SOMETHING to stringResource(R.string.password_quality_something),
PASSWORD_QUALITY_ALPHABETIC to "至少1个字母", PASSWORD_QUALITY_ALPHABETIC to stringResource(R.string.password_quality_alphabetic),
PASSWORD_QUALITY_NUMERIC to "至少1个数字", PASSWORD_QUALITY_NUMERIC to stringResource(R.string.password_quality_numeric),
PASSWORD_QUALITY_ALPHANUMERIC to "数字字母各至少一个", PASSWORD_QUALITY_ALPHANUMERIC to stringResource(R.string.password_quality_alphanumeric),
PASSWORD_QUALITY_BIOMETRIC_WEAK to "生物识别(弱)", PASSWORD_QUALITY_BIOMETRIC_WEAK to stringResource(R.string.password_quality_biometrics_weak),
PASSWORD_QUALITY_NUMERIC_COMPLEX to "复杂数字(无连续性)", PASSWORD_QUALITY_NUMERIC_COMPLEX to stringResource(R.string.password_quality_numeric_complex),
PASSWORD_QUALITY_COMPLEX to "自定义(暂不支持", PASSWORD_QUALITY_COMPLEX to stringResource(R.string.custom)+"${stringResource(R.string.unsupported)}",
).toList() ).toList()
var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) } var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) }
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.getPasswordQuality(myComponent) } if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.getPasswordQuality(myComponent) }
Text(text = "密码质量要求", style = typography.titleLarge,color = titleColor) Text(text = stringResource(R.string.required_password_quality), style = typography.titleLarge,color = titleColor)
if(passwordQualityExpand){ if(passwordQualityExpand){
Text(text = "不是实际密码质量", style = bodyTextStyle) Text(text = stringResource(R.string.password_complexity_instead_password_quality), style = bodyTextStyle)
Text(text = "设置密码复杂度将会取代密码质量", style = bodyTextStyle)
} }
if(VERSION.SDK_INT>=31){ Text(text = "已弃用,请使用上面的”密码复杂度要求“。点击展开", color = colorScheme.error, style = bodyTextStyle) } if(VERSION.SDK_INT>=31){ Text(text = stringResource(R.string.password_quality_deprecated_desc), color = colorScheme.error, style = bodyTextStyle) }
if(passwordQualityExpand){ if(passwordQualityExpand){
RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first}) RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first})
RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first}) RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first})
@@ -393,20 +393,20 @@ fun Password(){
RadioButtonItem(passwordQuality[5].second,{selectedItem==passwordQuality[5].first},{selectedItem=passwordQuality[5].first}) 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[6].second,{selectedItem==passwordQuality[6].first},{selectedItem=passwordQuality[6].first})
RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first}) RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first})
Text(text = "连续性密码重复6666或密码递增递减4321、2468", modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle) Text(text = stringResource(R.string.password_ordered_desc), modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle)
Button( Button(
onClick = { onClick = {
myDpm.setPasswordQuality(myComponent,selectedItem) myDpm.setPasswordQuality(myComponent,selectedItem)
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}, },
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm), enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("应用") Text(stringResource(R.string.apply))
} }
if(VERSION.SDK_INT<31){ if(VERSION.SDK_INT<31){
Button(onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}){ Button(onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}){
Text("要求设置新密码") Text(stringResource(R.string.require_set_new_password))
}} }}
} }
} }
@@ -465,12 +465,12 @@ private fun PasswordItem(
} }
fun activateToken(myContext: Context){ fun activateToken(myContext: Context){
val desc = "在这里激活密码重置令牌" val desc = myContext.getString(R.string.activate_reset_password_token_here)
val keyguardManager = myContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager val keyguardManager = myContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, desc) val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(myContext.getString(R.string.app_name), desc)
if (confirmIntent != null) { if (confirmIntent != null) {
startActivity(myContext,confirmIntent, null) startActivity(myContext,confirmIntent, null)
} else { } else {
Toast.makeText(myContext, "激活失败", Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show()
} }
} }

View File

@@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@@ -45,7 +46,7 @@ fun AppSetting(navCtrl:NavHostController){
} }
if(VERSION.SDK_INT>=32){ if(VERSION.SDK_INT>=32){
Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 3.dp),horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 3.dp),horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
Text(text = "动态取色", style = typography.titleLarge, color = titleColor) Text(text = stringResource(R.string.dynamic_color), style = typography.titleLarge, color = titleColor)
Switch( Switch(
checked = sharedPref.getBoolean("dynamicColor",false), checked = sharedPref.getBoolean("dynamicColor",false),
onCheckedChange = { onCheckedChange = {
@@ -54,22 +55,16 @@ fun AppSetting(navCtrl:NavHostController){
} }
) )
} }
Text(text = "打开或关闭动态取色需要重启应用", style = if(isWear){typography.bodyMedium}else{typography.bodyLarge}) Text(text = stringResource(R.string.dynamic_color_desc), style = if(isWear){typography.bodyMedium}else{typography.bodyLarge})
} }
} }
Column(modifier = sections()) { Column(modifier = sections()) {
Column( Column(
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 12.dp) modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 12.dp)
) { ) {
Text(text = "关于", style = typography.headlineSmall, color = titleColor) Text(text = stringResource(R.string.about), style = typography.headlineSmall, color = titleColor)
Text(text = "Android owner v$verName ($verCode)", style = bodyTextStyle) Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", style = bodyTextStyle)
Text(text = "使用安卓的Device admin、Device owner 、Profile owner全方位掌控你的设备", style = bodyTextStyle) Text(text = stringResource(R.string.about_desc), style = bodyTextStyle)
Spacer(Modifier.padding(vertical = 4.dp))
Text(text = "这个应用只在AOSP和LineageOS上测试过不确保每个功能都在其它系统可用尤其是国内的魔改系统。", style = bodyTextStyle)
Spacer(Modifier.padding(vertical = 4.dp))
Text(text = "大部分功能都要Device owner权限", style = bodyTextStyle)
Spacer(Modifier.padding(vertical = 2.dp))
Text(text = "安卓版本越高,支持的功能越多", style = bodyTextStyle)
} }
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -84,7 +79,7 @@ fun AppSetting(navCtrl:NavHostController){
modifier = Modifier.padding(start = 6.dp, end = 10.dp), modifier = Modifier.padding(start = 6.dp, end = 10.dp),
tint = colorScheme.primary tint = colorScheme.primary
) )
Text(text = "使用教程", style = typography.titleLarge, color = colorScheme.onPrimaryContainer, modifier = Modifier.padding(bottom = 2.dp)) Text(text = stringResource(R.string.user_guide), style = typography.titleLarge, color = colorScheme.onPrimaryContainer, modifier = Modifier.padding(bottom = 2.dp))
} }
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -99,7 +94,7 @@ fun AppSetting(navCtrl:NavHostController){
modifier = Modifier.padding(start = 6.dp, end = 10.dp), modifier = Modifier.padding(start = 6.dp, end = 10.dp),
tint = colorScheme.primary tint = colorScheme.primary
) )
Text(text = "源代码", style = typography.titleLarge, color = colorScheme.onPrimaryContainer, modifier = Modifier.padding(bottom = 2.dp)) Text(text = stringResource(R.string.source_code), style = typography.titleLarge, color = colorScheme.onPrimaryContainer, modifier = Modifier.padding(bottom = 2.dp))
} }
} }
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
@@ -109,5 +104,5 @@ fun AppSetting(navCtrl:NavHostController){
fun shareLink(inputContext:Context,link:String){ fun shareLink(inputContext:Context,link:String){
val uri = Uri.parse(link) val uri = Uri.parse(link)
val intent = Intent(Intent.ACTION_VIEW, uri) val intent = Intent(Intent.ACTION_VIEW, uri)
inputContext.startActivity(Intent.createChooser(intent, "Hello"),null) inputContext.startActivity(Intent.createChooser(intent, "Open in browser"),null)
} }

View File

@@ -32,10 +32,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
import rikka.shizuku.Shizuku import rikka.shizuku.Shizuku
import java.io.* import java.io.*
@@ -58,14 +58,14 @@ fun ShizukuActivate(){
if(Binder.getCallingUid()/100000!=0){ if(Binder.getCallingUid()/100000!=0){
Row(modifier = sections(colorScheme.errorContainer), verticalAlignment = Alignment.CenterVertically){ Row(modifier = sections(colorScheme.errorContainer), verticalAlignment = Alignment.CenterVertically){
Icon(imageVector = Icons.Rounded.Warning, contentDescription = null, tint = colorScheme.onErrorContainer) Icon(imageVector = Icons.Rounded.Warning, contentDescription = null, tint = colorScheme.onErrorContainer)
Text(text = "暂不支持在非主用户中使用Shizuku", style = bodyTextStyle, color = colorScheme.onErrorContainer) Text(text = stringResource(R.string.not_primary_user_not_support_shizuku), style = bodyTextStyle, color = colorScheme.onErrorContainer)
} }
} }
var launchPermissionCheck by remember{mutableStateOf(false)} var launchPermissionCheck by remember{mutableStateOf(false)}
LaunchedEffect(launchPermissionCheck){ LaunchedEffect(launchPermissionCheck){
if(launchPermissionCheck){ if(launchPermissionCheck){
outputText = checkPermission() outputText = checkPermission(myContext)
scrollState.animateScrollTo(scrollState.maxValue, scrollAnim()) scrollState.animateScrollTo(scrollState.maxValue, scrollAnim())
launchPermissionCheck=false launchPermissionCheck=false
} }
@@ -74,12 +74,12 @@ fun ShizukuActivate(){
onClick = {launchPermissionCheck=true}, onClick = {launchPermissionCheck=true},
enabled = VERSION.SDK_INT>=24, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) enabled = VERSION.SDK_INT>=24, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)
) { ) {
Text(text = "检查权限") Text(text = stringResource(R.string.check_permission))
} }
if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){ if(!isDeviceOwner(myDpm)&&!isProfileOwner(myDpm)){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = "激活", style = typography.titleLarge, color = colorScheme.onPrimaryContainer) Text(text = stringResource(R.string.activate), style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
if(!myDpm.isAdminActive(myComponent)){ if(!myDpm.isAdminActive(myComponent)){
var launchActivateDA by remember{mutableStateOf(false)} var launchActivateDA by remember{mutableStateOf(false)}
@@ -124,8 +124,8 @@ fun ShizukuActivate(){
if(VERSION.SDK_INT>=30&&!isDeviceOwner(myDpm)&&!myDpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile){ if(VERSION.SDK_INT>=30&&!isDeviceOwner(myDpm)&&!myDpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE)&&!myDpm.isOrganizationOwnedDeviceWithManagedProfile){
Column(modifier = sections()){ Column(modifier = sections()){
Text(text = "组织拥有工作资料", style = typography.titleLarge, color = colorScheme.onPrimaryContainer) Text(text = stringResource(R.string.org_owned_work_profile), style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
Text(text = "请输入工作资料的UserID", style = bodyTextStyle) Text(text = stringResource(R.string.input_userid_of_work_profile), style = bodyTextStyle)
var inputUserID by remember{mutableStateOf("")} var inputUserID by remember{mutableStateOf("")}
OutlinedTextField( OutlinedTextField(
value = inputUserID, onValueChange = {inputUserID=it}, value = inputUserID, onValueChange = {inputUserID=it},
@@ -151,12 +151,12 @@ fun ShizukuActivate(){
onClick = { onClick = {
launchActivateOrgProfile=true launchActivateOrgProfile=true
if(myDpm.isOrganizationOwnedDeviceWithManagedProfile){ if(myDpm.isOrganizationOwnedDeviceWithManagedProfile){
Toast.makeText(myContext,"成功",Toast.LENGTH_SHORT).show() Toast.makeText(myContext, myContext.getString(R.string.success),Toast.LENGTH_SHORT).show()
} }
}, },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = "激活") Text(text = stringResource(R.string.activate))
} }
} }
} }
@@ -172,13 +172,13 @@ fun ShizukuActivate(){
Button( Button(
onClick = {launchListOwners=true}, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) onClick = {launchListOwners=true}, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)
) { ) {
Text(text = "列出Owners") Text(text = stringResource(R.string.list_owners))
} }
var launchTest by remember{mutableStateOf(false)} var launchTest by remember{mutableStateOf(false)}
LaunchedEffect(launchTest){ LaunchedEffect(launchTest){
if(launchTest){ if(launchTest){
outputText="下面应该出现一行包含“2000”或“0”的文本\n" outputText= myContext.getString(R.string.should_contain_2000_or_0)
scrollState.animateScrollTo(scrollState.maxValue, scrollAnim()) scrollState.animateScrollTo(scrollState.maxValue, scrollAnim())
outputText+=executeCommand("sh rish.sh","id",null,filesDir) outputText+=executeCommand("sh rish.sh","id",null,filesDir)
launchTest=false launchTest=false
@@ -187,7 +187,7 @@ fun ShizukuActivate(){
Button( Button(
onClick = {launchTest=true}, modifier = Modifier.align(Alignment.CenterHorizontally) onClick = {launchTest=true}, modifier = Modifier.align(Alignment.CenterHorizontally)
) { ) {
Text(text = "测试rish") Text(text = stringResource(R.string.test_rish))
} }
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){
@@ -220,17 +220,17 @@ fun extractRish(myContext:Context){
if(VERSION.SDK_INT>=34){ Runtime.getRuntime().exec("chmod 400 rish_shizuku.dex",null,myContext.filesDir) } if(VERSION.SDK_INT>=34){ Runtime.getRuntime().exec("chmod 400 rish_shizuku.dex",null,myContext.filesDir) }
} }
private fun checkPermission():String { private fun checkPermission(myContext: Context):String {
return if(Shizuku.isPreV11()) { return if(Shizuku.isPreV11()) {
"请更新Shizuku" myContext.getString(R.string.please_update_shizuku)
}else{ }else{
try{ try{
if(Shizuku.checkSelfPermission()==PackageManager.PERMISSION_GRANTED) { if(Shizuku.checkSelfPermission()==PackageManager.PERMISSION_GRANTED) {
val permission = when(Shizuku.getUid()){ 0->"Root"; 2000->"Shell"; else->"未知权限" } val permission = when(Shizuku.getUid()){ 0->"Root"; 2000->"Shell"; else->myContext.getString(R.string.unknown) }
"Shizuku v${Shizuku.getVersion()}\n已授权($permission" myContext.getString(R.string.shizuku_permission_granted, Shizuku.getVersion(), permission)
}else if(Shizuku.shouldShowRequestPermissionRationale()){ "用户拒绝" } }else if(Shizuku.shouldShowRequestPermissionRationale()){ myContext.getString(R.string.denied) }
else{ Shizuku.requestPermission(0); "请求授权" } else{ Shizuku.requestPermission(0); myContext.getString(R.string.request_permission) }
}catch(e: Throwable){ "服务未启动" } }catch(e: Throwable){ myContext.getString(R.string.shizuku_not_started) }
} }
} }
@@ -246,7 +246,7 @@ fun executeCommand(command: String, subCommand:String, env: Array<String>?, dir:
IOUtils.copy(tunnel,outputStream) IOUtils.copy(tunnel,outputStream)
outputStream.close() outputStream.close()
val exitCode = process.waitFor() val exitCode = process.waitFor()
if(exitCode!=0){ result+="出错了!退出码:$exitCode" } if(exitCode!=0){ result+="Error: $exitCode" }
}catch(e:Exception){ }catch(e:Exception){
e.printStackTrace() e.printStackTrace()
return e.toString() return e.toString()

View File

@@ -21,6 +21,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -43,24 +44,24 @@ fun SysUpdatePolicy(){
Text(text = "Update first available: ${Date(sysUpdateInfo.receivedTime)}", style = bodyTextStyle) Text(text = "Update first available: ${Date(sysUpdateInfo.receivedTime)}", style = bodyTextStyle)
Text(text = "Hash code: ${sysUpdateInfo.hashCode()}", style = bodyTextStyle) Text(text = "Hash code: ${sysUpdateInfo.hashCode()}", style = bodyTextStyle)
val securityStateDesc = when(sysUpdateInfo.securityPatchState){ val securityStateDesc = when(sysUpdateInfo.securityPatchState){
SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN->"未知" SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN-> stringResource(R.string.unknown)
SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE->"" SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE->"true"
else->"" else->"false"
} }
Text(text = "安全补丁: $securityStateDesc", style = bodyTextStyle) Text(text = stringResource(R.string.is_security_patch, securityStateDesc), style = bodyTextStyle)
}else{ }else{
Text(text = "暂无系统更新", style = bodyTextStyle) Text(text = stringResource(R.string.no_system_update), style = bodyTextStyle)
} }
} }
} }
if(VERSION.SDK_INT>=23){ if(VERSION.SDK_INT>=23){
Column(modifier = sections()) { Column(modifier = sections()) {
var selectedPolicy by remember{ mutableStateOf(myDpm.systemUpdatePolicy?.policyType) } var selectedPolicy by remember{ mutableStateOf(myDpm.systemUpdatePolicy?.policyType) }
Text(text = "系统更新策略", style = typography.titleLarge, color = colorScheme.onPrimaryContainer) Text(text = stringResource(R.string.system_update_policy), style = typography.titleLarge, color = colorScheme.onPrimaryContainer)
RadioButtonItem("准备好后立即更新",{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC}) RadioButtonItem(stringResource(R.string.system_update_policy_automatic),{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC})
RadioButtonItem("在某段时间里更新",{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_WINDOWED},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_WINDOWED}) RadioButtonItem(stringResource(R.string.system_update_policy_install_windowed),{selectedPolicy==SystemUpdatePolicy.TYPE_INSTALL_WINDOWED},{selectedPolicy=SystemUpdatePolicy.TYPE_INSTALL_WINDOWED})
RadioButtonItem("延迟30天",{selectedPolicy==SystemUpdatePolicy.TYPE_POSTPONE},{selectedPolicy=SystemUpdatePolicy.TYPE_POSTPONE}) RadioButtonItem(stringResource(R.string.system_update_policy_postpone),{selectedPolicy==SystemUpdatePolicy.TYPE_POSTPONE},{selectedPolicy=SystemUpdatePolicy.TYPE_POSTPONE})
RadioButtonItem("",{selectedPolicy == null},{selectedPolicy=null}) RadioButtonItem(stringResource(R.string.none),{selectedPolicy == null},{selectedPolicy=null})
var windowedPolicyStart by remember{ mutableStateOf("") } var windowedPolicyStart by remember{ mutableStateOf("") }
var windowedPolicyEnd by remember{ mutableStateOf("") } var windowedPolicyEnd by remember{ mutableStateOf("") }
if(selectedPolicy==2){ if(selectedPolicy==2){
@@ -68,7 +69,7 @@ fun SysUpdatePolicy(){
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {
OutlinedTextField( OutlinedTextField(
value = windowedPolicyStart, value = windowedPolicyStart,
label = { Text("开始时间")}, label = { Text(stringResource(R.string.start_time))},
onValueChange = {windowedPolicyStart=it}, onValueChange = {windowedPolicyStart=it},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
@@ -78,14 +79,14 @@ fun SysUpdatePolicy(){
OutlinedTextField( OutlinedTextField(
value = windowedPolicyEnd, value = windowedPolicyEnd,
onValueChange = {windowedPolicyEnd=it}, onValueChange = {windowedPolicyEnd=it},
label = {Text("结束时间")}, label = {Text(stringResource(R.string.end_time))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().fillMaxWidth() modifier = Modifier.focusable().fillMaxWidth()
) )
} }
Spacer(Modifier.padding(vertical = 3.dp)) Spacer(Modifier.padding(vertical = 3.dp))
Text(text = "请输入一天中的分钟0~1440", style = bodyTextStyle) Text(text = stringResource(R.string.minutes_in_one_day), style = bodyTextStyle)
} }
val policy = val policy =
when(selectedPolicy){ when(selectedPolicy){
@@ -99,7 +100,7 @@ fun SysUpdatePolicy(){
enabled = isDeviceOwner(myDpm), enabled = isDeviceOwner(myDpm),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("应用") Text(stringResource(R.string.apply))
} }
}} }}
/*if(VERSION.SDK_INT>=29){ /*if(VERSION.SDK_INT>=29){

View File

@@ -78,7 +78,7 @@ fun UserRestriction(){
SectionTab("更多连接",{connectivityVisible}) { connectivityVisible=!connectivityVisible } SectionTab("更多连接",{connectivityVisible}) { connectivityVisible=!connectivityVisible }
AnimatedVisibility(connectivityVisible) { AnimatedVisibility(connectivityVisible) {
Column { Column {
for(connectivityItem in RestrictionData().connectivity()){ for(connectivityItem in RestrictionData().connectivity(myContext)){
UserRestrictionItem(connectivityItem.restriction,connectivityItem.name,connectivityItem.desc,connectivityItem.ico) UserRestrictionItem(connectivityItem.restriction,connectivityItem.name,connectivityItem.desc,connectivityItem.ico)
} }
} }
@@ -86,7 +86,7 @@ fun UserRestriction(){
SectionTab("应用",{applicationVisible}) { applicationVisible=!applicationVisible } SectionTab("应用",{applicationVisible}) { applicationVisible=!applicationVisible }
AnimatedVisibility(applicationVisible) { AnimatedVisibility(applicationVisible) {
Column { Column {
for(applicationItem in RestrictionData().application()){ for(applicationItem in RestrictionData().application(myContext)){
UserRestrictionItem(applicationItem.restriction,applicationItem.name,applicationItem.desc,applicationItem.ico) UserRestrictionItem(applicationItem.restriction,applicationItem.name,applicationItem.desc,applicationItem.ico)
} }
} }
@@ -110,7 +110,7 @@ fun UserRestriction(){
SectionTab("其他",{otherVisible}) { otherVisible=!otherVisible } SectionTab("其他",{otherVisible}) { otherVisible=!otherVisible }
AnimatedVisibility(otherVisible) { AnimatedVisibility(otherVisible) {
Column { Column {
for(otherItem in RestrictionData().other()){ for(otherItem in RestrictionData().other(myContext)){
UserRestrictionItem(otherItem.restriction,otherItem.name,otherItem.desc,otherItem.ico) UserRestrictionItem(otherItem.restriction,otherItem.name,otherItem.desc,otherItem.ico)
} }
} }
@@ -214,7 +214,7 @@ private class RestrictionData{
if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0)} if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0)}
if(VERSION.SDK_INT>=34){ if(VERSION.SDK_INT>=34){
list += Restriction(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0) list += Restriction(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0)
list += Restriction(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.wifi_tethering_fill0)
} }
if(VERSION.SDK_INT>=33){ if(VERSION.SDK_INT>=33){
list += Restriction(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0) list += Restriction(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0)
@@ -233,7 +233,7 @@ private class RestrictionData{
list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0) list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0)
return list return list
} }
fun connectivity():List<Restriction>{ fun connectivity(myContext:Context):List<Restriction>{
val list:MutableList<Restriction> = mutableListOf() val list:MutableList<Restriction> = mutableListOf()
if(VERSION.SDK_INT>=26){ if(VERSION.SDK_INT>=26){
list += Restriction(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0) list += Restriction(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0)
@@ -243,17 +243,17 @@ private class RestrictionData{
if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0)} if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0)}
if(VERSION.SDK_INT>=22){list += Restriction(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0)} if(VERSION.SDK_INT>=22){list += Restriction(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0)}
list += Restriction(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0) list += Restriction(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0)
list += Restriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, "包括TF卡和USB-OTG",R.drawable.sd_card_fill0) list += Restriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, myContext.getString(R.string.mount_physical_media_desc),R.drawable.sd_card_fill0)
if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0)} if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0)}
return list return list
} }
fun application():List<Restriction>{ fun application(myContext: Context):List<Restriction>{
val list:MutableList<Restriction> = mutableListOf() val list:MutableList<Restriction> = mutableListOf()
list += Restriction(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0)
if(VERSION.SDK_INT>=29){list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0)} if(VERSION.SDK_INT>=29){list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0)}
list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0)
list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0) list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0)
list += Restriction(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, "清空缓存/清空内部存储",R.drawable.apps_fill0) list += Restriction(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, myContext.getString(R.string.apps_control_desc),R.drawable.apps_fill0)
if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0) } if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0) }
return list return list
} }
@@ -278,14 +278,14 @@ private class RestrictionData{
list += Restriction(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0) list += Restriction(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0)
if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0)} if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0)}
if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0)} if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0)}
list += Restriction(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, "在不同用户和工作资料之间复制粘贴",R.drawable.content_paste_fill0) list += Restriction(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, "",R.drawable.content_paste_fill0)
if(VERSION.SDK_INT>=28){ if(VERSION.SDK_INT>=28){
list += Restriction(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0) list += Restriction(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0)
list += Restriction(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unifiied_pwd,"",R.drawable.work_fill0) list += Restriction(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unified_pwd,"",R.drawable.work_fill0)
} }
return list return list
} }
fun other():List<Restriction>{ fun other(myContext: Context):List<Restriction>{
val list:MutableList<Restriction> = mutableListOf() val list:MutableList<Restriction> = mutableListOf()
if(VERSION.SDK_INT>=26){ list += Restriction(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0) } if(VERSION.SDK_INT>=26){ list += Restriction(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0) }
list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0)
@@ -293,10 +293,10 @@ private class RestrictionData{
list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0)
list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0)
} }
list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, "可能包括Toast和浮动通知",R.drawable.web_asset) list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, myContext.getString(R.string.create_windows_desc),R.drawable.web_asset)
if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0)} if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0)}
if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0) } if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0) }
if(VERSION.SDK_INT>=23){ list += Restriction(UserManager.DISALLOW_FUN,R.string.`fun`,"可能会影响谷歌商店的游戏",R.drawable.stadia_controller_fill0) } if(VERSION.SDK_INT>=23){ list += Restriction(UserManager.DISALLOW_FUN,R.string.`fun`, myContext.getString(R.string.fun_desc),R.drawable.stadia_controller_fill0) }
list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0) list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0)
if(VERSION.SDK_INT>=28){ if(VERSION.SDK_INT>=28){
list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0) list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0)

View File

@@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<!--Global--> <!--Global-->
<string name="app_name">Android Owner</string> <string name="app_name" translatable="false">Android Owner</string>
<string name="disabled">禁用</string> <string name="disabled">禁用</string>
<string name="enabled">启用</string> <string name="enabled">启用</string>
<string name="disable">禁用</string> <string name="disable">禁用</string>
@@ -24,6 +24,8 @@
<string name="grant">允许</string> <string name="grant">允许</string>
<string name="deny">拒绝</string> <string name="deny">拒绝</string>
<string name="current_state">当前状态:%1$s</string> <string name="current_state">当前状态:%1$s</string>
<string name="auto">自动</string>
<string name="password">密码</string>
<string name="reason">原因</string> <string name="reason">原因</string>
<string name="custom">自定义</string> <string name="custom">自定义</string>
<string name="unknown">未知</string> <string name="unknown">未知</string>
@@ -35,6 +37,7 @@
<string name="apply">应用</string> <string name="apply">应用</string>
<string name="decide_by_user">由用户决定</string> <string name="decide_by_user">由用户决定</string>
<string name="unsupported">不支持</string> <string name="unsupported">不支持</string>
<string name="developing">功能开发中</string>
<string name="place_holder" /> <string name="place_holder" />
<!--Permissions--> <!--Permissions-->
@@ -61,12 +64,31 @@
<string name="transform_ownership_desc">把Device owner或Profile owner权限转移到另一个应用。目标必须是Device admin</string> <string name="transform_ownership_desc">把Device owner或Profile owner权限转移到另一个应用。目标必须是Device admin</string>
<string name="target_package_name">目标包名</string> <string name="target_package_name">目标包名</string>
<string name="target_class_name">目标类名</string> <string name="target_class_name">目标类名</string>
<string name="owner_lockscr_info">锁屏信息</string>
<string name="support_msg">提供支持的短消息</string>
<string name="support_msg_desc">如果你禁用了某个功能,用户尝试使用这个功能时会看见这个消息(可多行)</string>
<string name="message">消息</string>
<string name="long_support_msg">提供支持的长消息</string>
<string name="long_support_msg_desc">都是显示短消息,长消息不知道在哪里显示</string>
<string name="transform">转移</string> <string name="transform">转移</string>
<string name="deactivate_da">撤销Device admin</string> <string name="deactivate_da">撤销Device admin</string>
<string name="deactivate_po">撤销Profile owner</string> <string name="deactivate_po">撤销Profile owner</string>
<string name="deactivate_do">撤销Device owner</string> <string name="deactivate_do">撤销Device owner</string>
<string name="activate_android_owner_here">在这里激活Android Owner</string> <string name="activate_android_owner_here">在这里激活Android Owner</string>
<!--Shizuku-->
<string name="shizuku">Shizuku</string>
<string name="not_primary_user_not_support_shizuku">暂不支持在非主用户中使用Shizuku</string>
<string name="check_permission">检查权限</string>
<string name="input_userid_of_work_profile">请输入工作资料的UserID</string>
<string name="list_owners">列出Owners</string>
<string name="should_contain_2000_or_0">下面应该出现一行包含“2000”或“0”的文本\n</string>
<string name="test_rish">测试rish</string>
<string name="please_update_shizuku">请更新Shizuku</string>
<string name="shizuku_permission_granted">Shizuku v%1$i\n已授权%2$s</string>
<string name="request_permission">请求授权</string>
<string name="shizuku_not_started">服务未启动</string>
<!--System--> <!--System-->
<string name="device_ctrl">系统</string> <string name="device_ctrl">系统</string>
<string name="disable_cam">禁用相机</string> <string name="disable_cam">禁用相机</string>
@@ -127,11 +149,96 @@
<string name="will_delete_work_profile">将会删除工作资料</string> <string name="will_delete_work_profile">将会删除工作资料</string>
<string name="api34_or_above_wipedata_cannot_in_system_user">API34或以上将不能在系统用户中使用WipeData</string> <string name="api34_or_above_wipedata_cannot_in_system_user">API34或以上将不能在系统用户中使用WipeData</string>
<!--SystemUpdatePolicy-->
<string name="is_security_patch">安全补丁: %1$s</string>
<string name="no_system_update">暂无系统更新</string>
<string name="system_update_policy">系统更新策略</string>
<string name="system_update_policy_automatic">准备好后立即更新</string>
<string name="system_update_policy_install_windowed">在某段时间里更新</string>
<string name="system_update_policy_postpone">延迟30天</string>
<string name="start_time">开始时间</string>
<string name="end_time">结束时间</string>
<string name="minutes_in_one_day">请输入一天中的分钟0~1440</string>
<!--Network-->
<string name="network">网络</string>
<string name="min_wifi_security_level">要求最小WiFi安全等级</string>
<string name="wifi_security_level_open">开放</string>
<string name="preferential_network_service">优先网络服务</string>
<string name="wifi_lockdown">WiFi锁定</string>
<string name="wifi_ssid_policy">WiFi SSID策略</string>
<string name="ssid_list_is">SSID列表</string>
<string name="cannot_be_empty">不能为空</string>
<string name="already_exist">重复</string>
<string name="please_select_a_policy">请选择策略</string>
<string name="private_dns">私人DNS</string>
<string name="dns_provide_hostname">指定主机名</string>
<string name="host_not_serving_dns_tls">主机不支持DNS over TLS</string>
<string name="set_to_auto">设为自动</string>
<string name="dns_hostname">DNS主机名</string>
<string name="invalid_hostname">无效主机名</string>
<string name="security_exception">安全错误</string>
<string name="set_dns_host">设置DNS主机</string>
<string name="retrieve_net_logs">收集网络日志</string>
<string name="retrieve">收集</string>
<string name="wifi_keypair">WiFi密钥对</string>
<string name="keypair">密钥对</string>
<string name="apn_settings">APN设置</string>
<string name="total_apn_amount">一共有%1$s个APN设置</string>
<string name="select_a_apn_or_create">选择一个你要修改的APN设置(1~%1$s)或者输入0以新建APN设置</string>
<string name="no_apn_you_should_create_one">当前没有APN设置你可以新建一个APN设置</string>
<string name="previous_step">上一步</string>
<string name="next_step">下一步</string>
<string name="name">名称</string>
<string name="user_name">用户名</string>
<string name="profile_id">资料ID</string>
<string name="auth_type">验证类型</string>
<string name="apn_type">APN类型</string>
<string name="bitmask">位掩码</string>
<string name="description">描述</string>
<string name="mms_proxy">MMS代理</string>
<string name="address">地址</string>
<string name="port">端口</string>
<string name="proxy">代理</string>
<string name="network_type">网络类型</string>
<string name="persistent">持久的</string>
<string name="protocol">协议</string>
<string name="roaming_protocol">漫游协议</string>
<string name="update">更新</string>
<!--WorkProfile-->
<string name="work_profile">工作资料</string>
<string name="info">信息</string>
<string name="is_already_work_profile">已是工作资料</string>
<string name="able_to_create_work_profile">可以创建工作资料:%1$s</string>
<string name="device_owner_cannot_create_work_profile">Device owner不能创建工作资料</string>
<string name="is_org_owned_profile">由组织拥有的工作资料:%1$s</string>
<string name="org_owned_work_profile">组织拥有的工作资料</string>
<string name="activate_org_profile_command" tools:ignore="TypographyDashes">adb shell \"dpm mark-profile-owner-on-organization-owned-device --user %1$s com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver\"</string>
<string name="become_org_profile">成为组织拥有的工作资料</string>
<string name="skip_encryption">跳过加密</string>
<string name="create">创建</string>
<string name="suspend_personal_app">挂起个人应用</string>
<string name="profile_max_time_off">资料关闭时间</string>
<string name="profile_max_time_out_desc">工作资料处于关闭状态的时间达到该限制后会挂起个人应用0为无限制</string>
<string name="personal_app_suspended_because_timeout">个人应用已经因此挂起:%1$s</string>
<string name="cannot_less_than_72_hours">不能少于72小时</string>
<string name="intent_filter">Intent过滤器</string>
<string name="add_intent_filter_work_to_personal">添加(工作到个人)</string>
<string name="add_intent_filter_personal_to_work">添加(个人到工作)</string>
<string name="clear_cross_profile_filters">清除所有过滤器</string>
<string name="org_id">组织ID</string>
<string name="length_6_to_64">长度应在6~64个字符之间</string>
<string name="get_specific_id_after_set_org_id">设置组织ID后才能获取设备唯一标识码</string>
<string name="activate_managed_profile">激活工作资料</string>
<string name="activate_managed_profile_desc">你还没有激活工作资料,请立即激活</string>
<!--AppManage--> <!--AppManage-->
<string name="app_manage">应用管理</string> <string name="app_manage">应用管理</string>
<string name="suspend">挂起</string> <string name="suspend">挂起</string>
<string name="hide">隐藏</string> <string name="hide">隐藏</string>
<string name="isapphidden_desc">如果隐藏,有可能是没安装</string> <string name="isapphidden_desc">如果隐藏,有可能是没安装</string>
<string name="always_on_vpn">VPN保持打开</string>
<string name="permission">权限</string> <string name="permission">权限</string>
<string name="scope_is_work_profile">作用域: 工作资料</string> <string name="scope_is_work_profile">作用域: 工作资料</string>
<string name="app_info">应用详情</string> <string name="app_info">应用详情</string>
@@ -162,98 +269,153 @@
<string name="silent_install">静默安装</string> <string name="silent_install">静默安装</string>
<string name="request_install">请求安装</string> <string name="request_install">请求安装</string>
<!--UserRestriction-->
<string name="user_restrict">用户限制</string> <string name="user_restrict">用户限制</string>
<string name="config_mobile_network">配置移动数据</string> <string name="config_mobile_network">配置移动数据</string>
<string name="config_wifi">配置Wi-Fi</string> <string name="config_wifi">配置Wi-Fi</string>
<string name="bluetooth">蓝牙</string> <string name="data_roaming">数据漫游</string>
<string name="bt_share">蓝牙分享</string> <string name="cellular_2g">使用2G(GSM)</string>
<string name="airplane_mode">飞行模式</string> <string name="ultra_wideband_radio">超宽频段无线电</string>
<string name="config_location">配置位置信息</string>
<string name="config_brightness">调整亮度</string>
<string name="debug_features">调试功能</string>
<string name="create_windows">创建窗口</string>
<string name="adjust_volume">调整音量</string>
<string name="install_apps">安装应用</string>
<string name="camera_toggle">切换摄像头使用权限</string>
<string name="sms">短信</string>
<string name="apps_ctrl">控制应用</string>
<string name="autofill">自动填充服务</string>
<string name="inst_unknown_src">安装未知来源应用</string>
<string name="add_user">添加用户</string>
<string name="ambient_display">息屏显示</string>
<string name="add_wifi_conf">添加WiFi配置</string> <string name="add_wifi_conf">添加WiFi配置</string>
<string name="change_wifi_state">修改WiFi状态</string> <string name="change_wifi_state">修改WiFi状态</string>
<string name="config_cell_broadcasts">配置小区广播</string>
<string name="config_credentials">配置凭据</string>
<string name="config_locale">修改语言</string>
<string name="cellular_2g">使用2G(GSM)</string>
<string name="config_date_time">修改日期、时间</string>
<string name="config_default_apps">修改默认App</string>
<string name="config_private_dns">配置私人DNS</string>
<string name="config_scr_timeout">修改屏幕超时</string>
<string name="config_tethering">配置网络共享</string>
<string name="config_vpn">配置VPN</string>
<string name="content_capture">内容捕获</string>
<string name="content_suggestions">内容建议</string>
<string name="cross_profile_copy">跨用户复制</string>
<string name="data_roaming">数据漫游</string>
<string name="factory_reset">恢复出厂设置</string>
<string name="fun">娱乐</string>
<string name="grant_admin">启用设备管理器</string>
<string name="install_unknown_src_globally">安装未知来源应用(全局)</string>
<string name="microphone_toggle">切换麦克风使用权限</string>
<string name="modify_accounts">修改账号设置</string>
<string name="mount_physical_media">挂载物理媒体</string>
<string name="network_reset">重置网络</string>
<string name="outgoing_beam">Beam发送</string>
<string name="outgoing_calls">拨打电话</string>
<string name="printing">打印</string>
<string name="remove_user">移除用户</string>
<string name="safe_boot">安全模式</string>
<string name="set_user_icon">修改用户头像</string>
<string name="set_wallpaper">更换壁纸</string>
<string name="share_into_managed_profile">分享至工作应用</string>
<string name="share_location">分享位置</string>
<string name="share_admin_wifi">分享设备管理器配置的WiFi</string>
<string name="sys_err_dialog">系统报错对话框</string>
<string name="ultra_wideband_radio">超宽频段无线电</string>
<string name="unifiied_pwd">个人和工作密码相同</string>
<string name="uninstall_apps">卸载应用</string>
<string name="unmute_microphone">取消麦克风静音</string>
<string name="usb_file_transfer">USB文件传输</string>
<string name="switch_user">切换用户</string>
<string name="wifi_direct">WiFi直连</string> <string name="wifi_direct">WiFi直连</string>
<string name="wifi_tethering">WiFi共享</string> <string name="wifi_tethering">WiFi共享</string>
<string name="share_admin_wifi">分享设备管理器配置的WiFi</string>
<string name="network_reset">重置网络</string>
<string name="config_tethering">配置网络共享</string>
<string name="config_vpn">配置VPN</string>
<string name="config_private_dns">配置私人DNS</string>
<string name="airplane_mode">飞行模式</string>
<string name="config_cell_broadcasts">配置小区广播</string>
<string name="sms">短信</string>
<string name="outgoing_calls">拨出电话</string>
<string name="password">密码与锁屏</string> <string name="bluetooth">蓝牙</string>
<string name="bt_share">蓝牙分享</string>
<string name="share_location">分享位置</string>
<string name="config_location">配置位置信息</string>
<string name="outgoing_beam">Beam发送</string>
<string name="usb_file_transfer">USB文件传输</string>
<string name="mount_physical_media">挂载物理媒体</string>
<string name="mount_physical_media_desc">包括TF卡和USB-OTG</string>
<string name="printing">打印</string>
<string name="install_apps">安装应用</string>
<string name="install_unknown_src_globally">安装未知来源应用(全局)</string>
<string name="inst_unknown_src">安装未知来源应用</string>
<string name="uninstall_apps">卸载应用</string>
<string name="apps_ctrl">控制应用</string>
<string name="apps_control_desc">清空缓存/清空内部存储</string>
<string name="config_default_apps">修改默认App</string>
<string name="config_brightness">调整亮度</string>
<string name="config_scr_timeout">修改屏幕超时</string>
<string name="ambient_display">息屏显示</string>
<string name="adjust_volume">调整音量</string>
<string name="unmute_microphone">取消麦克风静音</string>
<string name="camera_toggle">切换摄像头使用权限</string>
<string name="microphone_toggle">切换麦克风使用权限</string>
<string name="add_user">添加用户</string>
<string name="remove_user">移除用户</string>
<string name="switch_user">切换用户</string>
<string name="set_user_icon">修改用户头像</string>
<string name="cross_profile_copy">跨用户复制</string>
<string name="share_into_managed_profile">分享至工作应用</string>
<string name="unified_pwd">个人和工作密码相同</string>
<string name="autofill">自动填充服务</string>
<string name="config_credentials">配置凭据</string>
<string name="content_capture">内容捕获</string>
<string name="content_suggestions">内容建议</string>
<string name="create_windows">创建窗口</string>
<string name="create_windows_desc">可能包括Toast和浮动通知</string>
<string name="set_wallpaper">更换壁纸</string>
<string name="grant_admin">启用设备管理器</string>
<string name="fun">娱乐</string>
<string name="fun_desc">会影响谷歌商店的游戏</string>
<string name="modify_accounts">修改账号设置</string>
<string name="config_locale">修改语言</string>
<string name="config_date_time">修改日期、时间</string>
<string name="sys_err_dialog">系统报错对话框</string>
<string name="factory_reset">恢复出厂设置</string>
<string name="safe_boot">安全模式</string>
<string name="debug_features">调试功能</string>
<!--UserManage-->
<string name="user_manage">用户管理</string>
<!--Password&Keyguard-->
<string name="password_and_keyguard">密码与锁屏</string>
<string name="reset_pwd_desc">留空可以清除密码纯数字将使用PIN码</string> <string name="reset_pwd_desc">留空可以清除密码纯数字将使用PIN码</string>
<string name="max_pwd_fail">最大密码错误次数</string> <string name="max_pwd_fail">最大密码错误次数</string>
<string name="max_pwd_fail_desc">达到该限制会恢复出厂设置</string> <string name="max_pwd_fail_desc">达到该限制会恢复出厂设置</string>
<string name="max_pwd_fail_textfield">错误次数</string> <string name="max_pwd_fail_textfield">错误次数</string>
<string name="pwd_timeout">密码失效超时时间</string> <string name="pwd_timeout">密码失效超时时间</string>
<string name="max_time_to_lock">屏幕超时</string>
<string name="max_time_to_lock_desc">超时后锁屏(毫秒)0为由用户决定</string>
<string name="pwd_timeout_desc">超时后用户需重新设置密码毫秒0为无限制</string> <string name="pwd_timeout_desc">超时后用户需重新设置密码毫秒0为无限制</string>
<string name="pwd_timeout_textfield">超时时间(ms)</string> <string name="pwd_timeout_textfield">超时时间(ms)</string>
<string name="pwd_history">密码历史记录长度</string> <string name="pwd_history">密码历史记录长度</string>
<string name="pwd_history_desc">用户输入的密码不能与历史记录中的任何密码相同0为无限制</string> <string name="pwd_history_desc">用户输入的密码不能与历史记录中的任何密码相同0为无限制</string>
<string name="pwd_history_textfield">历史记录长度</string> <string name="pwd_history_textfield">历史记录长度</string>
<string name="password_warning">以下操作可能会造成不可挽回的损失,请先备份好数据。执行操作时一定要谨慎!!!</string>
<string name="password_wearos_warning">警告手表不支持带字母的密码也不支持超过4位的PIN码如果你设置了这样的密码或密码复杂度要求你将无法解锁你的手表</string>
<string name="password_complexity_none">无(允许不设密码)</string>
<string name="password_complexity_low">低(允许图案和连续性)</string>
<string name="password_complexity_medium">无连续性至少4位</string>
<string name="password_complexity_high">无连续性至少6位</string>
<string name="current_password_complexity_is">当前密码复杂度:%1$s</string>
<string name="is_password_sufficient">密码达到要求:%1$s</string>
<string name="password_failed_attempts_is">密码已错误次数:%1$s</string>
<string name="is_using_unified_password">个人与工作应用密码一致:%1$s</string>
<string name="reset_password_token">密码重置令牌</string>
<string name="clear">清除</string>
<string name="set">设置</string>
<string name="please_set_a_token">请先设置令牌</string>
<string name="activate_token_not_required_when_no_password">没有密码时会自动激活令牌</string>
<string name="reset_password">重置密码</string>
<string name="do_not_ask_credentials_on_boot">启动(boot)时不要求密码</string>
<string name="reset_password_require_entry">不允许其他设备管理员重置密码直至用户输入一次密码</string>
<string name="require_4_digit_password">需要4位密码</string>
<string name="reset_password_with_token">使用令牌重置密码</string>
<string name="reset_password_deprecated">重置密码(弃用)</string>
<string name="required_password_complexity">密码复杂度要求</string>
<string name="password_ordered_desc">连续性密码重复6666或密码递增递减4321、2468</string>
<string name="require_set_new_password">要求设置新密码</string>
<string name="keyguard_disabled_features">锁屏功能</string>
<string name="enable_all">启用全部</string>
<string name="keyguard_disabled_features_widgets">禁用小工具(安卓5以下)</string>
<string name="keyguard_disabled_features_camera">禁用相机</string>
<string name="keyguard_disabled_features_notification">禁用通知</string>
<string name="keyguard_disabled_features_unredacted_notification">禁用未经编辑的通知</string>
<string name="keyguard_disabled_features_trust_agents">禁用可信代理</string>
<string name="keyguard_disabled_features_fingerprint">禁用指纹解锁</string>
<string name="keyguard_disabled_features_remote_input">禁止远程输入(弃用)</string>
<string name="keyguard_disabled_features_face">禁用人脸解锁</string>
<string name="keyguard_disabled_features_iris">禁用虹膜解锁(?)</string>
<string name="keyguard_disabled_features_biometrics">禁用生物识别</string>
<string name="keyguard_disabled_features_shortcuts">禁用快捷方式</string>
<string name="password_quality_unspecified">未指定</string>
<string name="password_quality_something">需要密码或图案,不管复杂度</string>
<string name="password_quality_alphabetic">至少1个字母</string>
<string name="password_quality_numeric">至少1个数字</string>
<string name="password_quality_alphanumeric">数字字母各至少一个</string>
<string name="password_quality_biometrics_weak">生物识别(弱)</string>
<string name="password_quality_numeric_complex">复杂数字(无连续性)</string>
<string name="required_password_quality">密码质量要求</string>
<string name="password_complexity_instead_password_quality">设置密码复杂度将会取代密码质量</string>
<string name="password_quality_deprecated_desc">已弃用,请使用上面的”密码复杂度要求“。点击展开</string>
<string name="activate_reset_password_token_here">在这里激活密码重置令牌</string>
<string name="owner_lockscr_info">锁屏信息</string> <!--Settings&About-->
<string name="support_msg">提供支持的短消息</string>
<string name="support_msg_desc">如果你禁用了某个功能,用户尝试使用这个功能时会看见这个消息(可多行)</string>
<string name="message">消息</string>
<string name="long_support_msg">提供支持的长消息</string>
<string name="long_support_msg_desc">都是显示短消息,长消息不知道在哪里显示</string>
<string name="user_manage">用户管理</string>
<string name="setting">设置</string> <string name="setting">设置</string>
<string name="always_on_vpn">VPN保持打开</string> <string name="dynamic_color">动态取色</string>
<string name="experimental_feature">实验性功能</string> <string name="dynamic_color_desc">打开或关闭动态取色需要重启应用</string>
<string name="max_time_to_lock">屏幕超时</string> <string name="about">关于</string>
<string name="max_time_to_lock_desc">超时后锁屏(毫秒)0为由用户决定</string> <string name="about_desc">使用安卓的Device admin、Device owner 、Profile owner全方位掌控你的设备</string>
<string name="max_time_to_lock_textfield">超时时间(ms)</string> <string name="user_guide">使用教程</string>
<string name="preferential_network_service">优先网络服务</string> <string name="source_code">源代码</string>
<string name="network">网络</string>
<string name="developing">功能开发中</string>
<string name="wifi_lockdown">WiFi锁定</string>
<string name="work_profile">工作资料</string>
<string name="shizuku_activate">Shizuku</string>
</resources> </resources>