hide Wipe data by default, add Delete work profile

close #53
This commit is contained in:
BinTianqi
2024-07-19 09:09:10 +08:00
parent e9949c67ef
commit d4de1eba75
6 changed files with 126 additions and 16 deletions

View File

@@ -44,6 +44,7 @@ fun AppSetting(navCtrl:NavHostController, materialYou: MutableState<Boolean>, bl
modifier = Modifier.padding(top = it.calculateTopPadding()) modifier = Modifier.padding(top = it.calculateTopPadding())
) { ) {
composable(route = "Home") { Home(localNavCtrl) } composable(route = "Home") { Home(localNavCtrl) }
composable(route = "Options") { Options() }
composable(route = "Theme") { ThemeSettings(materialYou, blackTheme) } composable(route = "Theme") { ThemeSettings(materialYou, blackTheme) }
composable(route = "Auth") { AuthSettings() } composable(route = "Auth") { AuthSettings() }
composable(route = "Automation") { Automation() } composable(route = "Automation") { Automation() }
@@ -55,6 +56,7 @@ fun AppSetting(navCtrl:NavHostController, materialYou: MutableState<Boolean>, bl
@Composable @Composable
private fun Home(navCtrl: NavHostController) { private fun Home(navCtrl: NavHostController) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
SubPageItem(R.string.theme, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") } SubPageItem(R.string.theme, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") }
SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") } SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") }
SubPageItem(R.string.automation_api, "", R.drawable.apps_fill0) { navCtrl.navigate("Automation") } SubPageItem(R.string.automation_api, "", R.drawable.apps_fill0) { navCtrl.navigate("Automation") }
@@ -62,6 +64,18 @@ private fun Home(navCtrl: NavHostController) {
} }
} }
@Composable
private fun Options() {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
SwitchItem(
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
{ sharedPref.getBoolean("dangerous_features", false) },
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }
)
}
}
@Composable @Composable
private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) { private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)

View File

@@ -11,11 +11,15 @@ import android.app.admin.DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT
import android.app.admin.DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED import android.app.admin.DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED
import android.app.admin.DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED import android.app.admin.DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED
import android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT import android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT
import android.app.admin.DevicePolicyManager.WIPE_EUICC
import android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE
import android.app.admin.DevicePolicyManager.WIPE_SILENTLY
import android.content.* import android.content.*
import android.os.Binder import android.os.Binder
import android.os.Build.VERSION import android.os.Build.VERSION
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -26,13 +30,17 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@@ -80,6 +88,7 @@ fun ManagedProfile(navCtrl: NavHostController) {
composable(route = "CreateWorkProfile") { CreateWorkProfile() } composable(route = "CreateWorkProfile") { CreateWorkProfile() }
composable(route = "SuspendPersonalApp") { SuspendPersonalApp() } composable(route = "SuspendPersonalApp") { SuspendPersonalApp() }
composable(route = "IntentFilter") { IntentFilter() } composable(route = "IntentFilter") { IntentFilter() }
composable(route = "DeleteWorkProfile") { DeleteWorkProfile() }
} }
} }
} }
@@ -97,7 +106,7 @@ private fun Home(navCtrl: NavHostController) {
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp)
) )
if(VERSION.SDK_INT >= 30&&isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) { if(VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) {
SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") } SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") }
} }
if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) { if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) {
@@ -106,9 +115,12 @@ private fun Home(navCtrl: NavHostController) {
if(dpm.isOrgProfile(receiver)) { if(dpm.isOrgProfile(receiver)) {
SubPageItem(R.string.suspend_personal_app, "", R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") } SubPageItem(R.string.suspend_personal_app, "", R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") }
} }
if(isProfileOwner(dpm) && (VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isManagedProfile(receiver)))) { if(isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
SubPageItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") } SubPageItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") }
} }
if(isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
SubPageItem(R.string.delete_work_profile, "", R.drawable.delete_forever_fill0) { navCtrl.navigate("DeleteWorkProfile") }
}
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
} }
} }
@@ -265,3 +277,81 @@ private fun IntentFilter() {
} }
} }
} }
@Composable
private fun DeleteWorkProfile() {
val context = LocalContext.current
val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val focusMgr = LocalFocusManager.current
var warning by remember { mutableStateOf(false) }
var externalStorage by remember { mutableStateOf(false) }
var euicc by remember { mutableStateOf(false) }
var silent by remember { mutableStateOf(false) }
var reason by remember { mutableStateOf("") }
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp))
Text(
text = stringResource(R.string.delete_work_profile),
style = typography.headlineLarge,
modifier = Modifier.padding(6.dp),color = colorScheme.error
)
Spacer(Modifier.padding(vertical = 5.dp))
CheckBoxItem(stringResource(R.string.wipe_external_storage), externalStorage, { externalStorage = it })
if(VERSION.SDK_INT >= 28) { CheckBoxItem(stringResource(R.string.wipe_euicc), euicc, { euicc = it }) }
if(VERSION.SDK_INT >= 29) { CheckBoxItem(stringResource(R.string.wipe_silently), silent, { silent = it }) }
AnimatedVisibility(!silent && VERSION.SDK_INT >= 28) {
OutlinedTextField(
value = reason, onValueChange = { reason = it },
label = { Text(stringResource(R.string.reason)) },
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
)
}
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
focusMgr.clearFocus()
warning = true
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError),
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.delete))
}
Spacer(Modifier.padding(vertical = 30.dp))
}
if(warning) {
LaunchedEffect(Unit) { silent = reason == "" }
AlertDialog(
title = {
Text(text = stringResource(R.string.warning), color = colorScheme.error)
},
text = {
Text(text = stringResource(R.string.wipe_work_profile_warning), color = colorScheme.error)
},
onDismissRequest = { warning = false },
confirmButton = {
TextButton(
onClick = {
var flag = 0
if(externalStorage) { flag += WIPE_EXTERNAL_STORAGE }
if(euicc && VERSION.SDK_INT >= 28) { flag += WIPE_EUICC }
if(silent && VERSION.SDK_INT >= 29) { flag += WIPE_SILENTLY }
if(VERSION.SDK_INT >= 28 && !silent) {
dpm.wipeData(flag, reason)
} else {
dpm.wipeData(flag)
}
},
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)
) {
Text(stringResource(R.string.confirm))
}
},
dismissButton = {
TextButton(onClick = { warning = false }) {
Text(stringResource(R.string.cancel))
}
}
)
}
}

View File

@@ -176,6 +176,8 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDia
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val receiver = ComponentName(context, Receiver::class.java) val receiver = ComponentName(context, Receiver::class.java)
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
val dangerousFeatures = sharedPref.getBoolean("dangerous_features", false)
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.system_manage), text = stringResource(R.string.system_manage),
@@ -223,7 +225,7 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDia
if(VERSION.SDK_INT >= 30 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { if(VERSION.SDK_INT >= 30 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) {
SubPageItem(R.string.frp_policy, "", R.drawable.device_reset_fill0) { navCtrl.navigate("FRP") } SubPageItem(R.string.frp_policy, "", R.drawable.device_reset_fill0) { navCtrl.navigate("FRP") }
} }
if(dpm.isAdminActive(receiver)) { if(dangerousFeatures && dpm.isAdminActive(receiver) && !(VERSION.SDK_INT >= 24 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver))) {
SubPageItem(R.string.wipe_data, "", R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") } SubPageItem(R.string.wipe_data, "", R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") }
} }
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
@@ -1131,10 +1133,6 @@ private fun WipeData() {
Text("WipeDevice") Text("WipeDevice")
} }
} }
Spacer(Modifier.padding(vertical = 5.dp))
if(VERSION.SDK_INT >= 24 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) {
Information{ Text(text = stringResource(R.string.will_delete_work_profile)) }
}
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
} }
if(warning) { if(warning) {
@@ -1144,11 +1142,7 @@ private fun WipeData() {
Text(text = stringResource(R.string.warning), color = colorScheme.error) Text(text = stringResource(R.string.warning), color = colorScheme.error)
}, },
text = { text = {
Text(text = stringResource( Text(text = stringResource(R.string.wipe_data_warning), color = colorScheme.error)
if(VERSION.SDK_INT >= 24 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) R.string.wipe_work_profile_warning
else R.string.wipe_data_warning),
color = colorScheme.error
)
}, },
onDismissRequest = { warning = false }, onDismissRequest = { warning = false },
confirmButton = { confirmButton = {

View File

@@ -55,6 +55,7 @@
<string name="use_policy">Politika Kullan</string> <string name="use_policy">Politika Kullan</string>
<string name="account">Hesap</string> <string name="account">Hesap</string>
<string name="warning">Warning</string> <!--TODO--> <string name="warning">Warning</string> <!--TODO-->
<string name="delete">Delete</string> <!--TODO-->
<!--Permissions--> <!--Permissions-->
<string name="click_to_activate">Etkinleştirmek İçin Tıklayın</string> <string name="click_to_activate">Etkinleştirmek İçin Tıklayın</string>
@@ -181,7 +182,7 @@
<string name="wipe_silently">Sessizce sil</string> <string name="wipe_silently">Sessizce sil</string>
<string name="will_delete_work_profile">Çalışma profili silinecek</string> <string name="will_delete_work_profile">Çalışma profili silinecek</string>
<string name="wipe_data_warning">All data on your device will be ERASED</string> <!--TODO--> <string name="wipe_data_warning">All data on your device will be ERASED</string> <!--TODO-->
<string name="wipe_work_profile_warning">Your work profile will be REMOVED</string> <!--TODO--> <string name="wipe_work_profile_warning">Your work profile will be DELETED</string> <!--TODO-->
<string name="encrypt_status_is">Şifreleme durumu: </string> <string name="encrypt_status_is">Şifreleme durumu: </string>
<string name="frp_policy">FRP politikası</string> <string name="frp_policy">FRP politikası</string>
<string name="factory_reset_protection_policy">Fabrika ayarlarına sıfırlama koruma politikası</string> <string name="factory_reset_protection_policy">Fabrika ayarlarına sıfırlama koruma politikası</string>
@@ -276,6 +277,7 @@
<string name="org_id">Kuruluş Kimliği</string> <string name="org_id">Kuruluş Kimliği</string>
<string name="length_6_to_64">Uzunluk 6 ile 64 karakter arasında olmalıdır</string> <string name="length_6_to_64">Uzunluk 6 ile 64 karakter arasında olmalıdır</string>
<string name="get_specific_id_after_set_org_id">Bunu ayarladıktan sonra cihaz spesifik Kimlik alabilirsiniz. </string> <string name="get_specific_id_after_set_org_id">Bunu ayarladıktan sonra cihaz spesifik Kimlik alabilirsiniz. </string>
<string name="delete_work_profile">Delete work profile</string> <!--TODO-->
<!--AppManager--> <!--AppManager-->
<string name="app_manager">Uygulama yöneticisi</string> <string name="app_manager">Uygulama yöneticisi</string>
@@ -527,6 +529,7 @@
<!--Settings&About--> <!--Settings&About-->
<string name="setting">Ayarlar</string> <string name="setting">Ayarlar</string>
<string name="show_dangerous_features">Show dangerous features</string> <!--TODO-->
<string name="material_you_color">Material You rengi</string> <string name="material_you_color">Material You rengi</string>
<string name="dynamic_color_desc">Android 12+</string> <string name="dynamic_color_desc">Android 12+</string>
<string name="about">Hakkında</string> <string name="about">Hakkında</string>
@@ -552,6 +555,9 @@
<string name="clear_storage">Depolamayı temizle</string> <string name="clear_storage">Depolamayı temizle</string>
<string name="clear_storage_success">Depolama başarıyla temizlendi\nUygulama kapanacak</string> <string name="clear_storage_success">Depolama başarıyla temizlendi\nUygulama kapanacak</string>
<string name="automation_api">Automation API</string> <!--TODO-->
<string name="automation_debug">Debug mode</string> <!--TODO-->
<!--AndroidPermission--> <!--AndroidPermission-->
<string name="permission_READ_EXTERNAL_STORAGE">Harici depolamayı oku</string> <string name="permission_READ_EXTERNAL_STORAGE">Harici depolamayı oku</string>
<string name="permission_WRITE_EXTERNAL_STORAGE">Harici depolamaya yaz</string> <string name="permission_WRITE_EXTERNAL_STORAGE">Harici depolamaya yaz</string>

View File

@@ -52,6 +52,7 @@
<string name="use_policy">使用策略</string> <string name="use_policy">使用策略</string>
<string name="account">账户</string> <string name="account">账户</string>
<string name="warning">警告</string> <string name="warning">警告</string>
<string name="delete">删除</string>
<!--Permissions--> <!--Permissions-->
<string name="click_to_activate">点击以激活</string> <string name="click_to_activate">点击以激活</string>
@@ -271,6 +272,7 @@
<string name="org_id">组织ID</string> <string name="org_id">组织ID</string>
<string name="length_6_to_64">长度应在6~64个字符之间</string> <string name="length_6_to_64">长度应在6~64个字符之间</string>
<string name="get_specific_id_after_set_org_id">设置组织ID后才能获取设备唯一标识码</string> <string name="get_specific_id_after_set_org_id">设置组织ID后才能获取设备唯一标识码</string>
<string name="delete_work_profile">删除工作资料</string>
<!--AppManage--> <!--AppManage-->
<string name="app_manager">应用管理</string> <string name="app_manager">应用管理</string>
@@ -518,6 +520,7 @@
<!--Settings&About--> <!--Settings&About-->
<string name="setting">设置</string> <string name="setting">设置</string>
<string name="show_dangerous_features">显示危险功能</string>
<string name="material_you_color">Material you 颜色</string> <string name="material_you_color">Material you 颜色</string>
<string name="dynamic_color_desc">安卓12+</string> <string name="dynamic_color_desc">安卓12+</string>
<string name="about">关于</string> <string name="about">关于</string>

View File

@@ -55,6 +55,7 @@
<string name="use_policy">Use policy</string> <string name="use_policy">Use policy</string>
<string name="account">Account</string> <string name="account">Account</string>
<string name="warning">Warning</string> <string name="warning">Warning</string>
<string name="delete">Delete</string>
<!--Permissions--> <!--Permissions-->
<string name="click_to_activate">Click to activate</string> <string name="click_to_activate">Click to activate</string>
@@ -110,8 +111,8 @@
<string name="dpm_activate_da_command" translatable="false">dpm set-active-admin com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string> <string name="dpm_activate_da_command" translatable="false">dpm set-active-admin com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
<string name="shizuku_activated_shell">Permission granted (Shell)</string> <string name="shizuku_activated_shell">Permission granted (Shell)</string>
<string name="shizuku_activated_root">Permission granted (Root)</string> <string name="shizuku_activated_root">Permission granted (Root)</string>
<string name="activate_profile_owner">Activate profile owner</string> <string name="activate_profile_owner">Activate Profile owner</string>
<string name="activate_device_owner">Activate device owner</string> <string name="activate_device_owner">Activate Device owner</string>
<string name="activate_org_profile">Activate organization-owned work profile</string> <string name="activate_org_profile">Activate organization-owned work profile</string>
<string name="shizuku_service_disconnected">Shizuku service disconnected</string> <string name="shizuku_service_disconnected">Shizuku service disconnected</string>
<string name="invalid_binder">Invalid binder</string> <string name="invalid_binder">Invalid binder</string>
@@ -186,7 +187,7 @@
<string name="wipe_silently">Wipe silently</string> <string name="wipe_silently">Wipe silently</string>
<string name="will_delete_work_profile">Work profile will be deleted. </string> <string name="will_delete_work_profile">Work profile will be deleted. </string>
<string name="wipe_data_warning">All data on your device will be ERASED</string> <string name="wipe_data_warning">All data on your device will be ERASED</string>
<string name="wipe_work_profile_warning">Your work profile will be REMOVED</string> <string name="wipe_work_profile_warning">Your work profile will be DELETED</string>
<string name="encrypt_status_is">Encrypt status: </string> <string name="encrypt_status_is">Encrypt status: </string>
<string name="frp_policy">FRP policy</string> <string name="frp_policy">FRP policy</string>
<string name="factory_reset_protection_policy">Factory reset protection policy</string> <string name="factory_reset_protection_policy">Factory reset protection policy</string>
@@ -285,6 +286,7 @@
<string name="org_id">Organization ID</string> <string name="org_id">Organization ID</string>
<string name="length_6_to_64">The length should be between 6~64 characters</string> <string name="length_6_to_64">The length should be between 6~64 characters</string>
<string name="get_specific_id_after_set_org_id">You can get device specific ID after set this. </string> <string name="get_specific_id_after_set_org_id">You can get device specific ID after set this. </string>
<string name="delete_work_profile">Delete work profile</string>
<!--AppManager--> <!--AppManager-->
<string name="app_manager">App manager</string> <string name="app_manager">App manager</string>
@@ -534,6 +536,7 @@
<!--Settings&About--> <!--Settings&About-->
<string name="setting">Settings</string> <string name="setting">Settings</string>
<string name="show_dangerous_features">Show dangerous features</string>
<string name="material_you_color">Material you color</string> <string name="material_you_color">Material you color</string>
<string name="dynamic_color_desc">Android 12+</string> <string name="dynamic_color_desc">Android 12+</string>
<string name="about">About</string> <string name="about">About</string>