Use pager to split Lock task mode into 3 page

Change version name to v6.3
Update workflow file
Fix a typo in Readme.md
This commit is contained in:
BinTianqi
2024-12-31 22:28:40 +08:00
parent ec6bccc0b5
commit 65bf0f75d8
15 changed files with 307 additions and 247 deletions

View File

@@ -6,8 +6,6 @@ on:
- '**.md' - '**.md'
tags-ignore: tags-ignore:
- '**' - '**'
branches-ignore:
- 'master'
jobs: jobs:
build: build:
@@ -63,7 +61,7 @@ jobs:
upload-telegram: upload-telegram:
name: Upload Builds name: Upload Builds
if: ${{ success() }} if: ${{ success() && github.ref_name == 'dev' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- build - build

View File

@@ -31,7 +31,7 @@
- 应用:禁止安装/卸载应用... - 应用:禁止安装/卸载应用...
- 用户:禁止添加/删除/切换用户... - 用户:禁止添加/删除/切换用户...
- 媒体:禁止调整亮度、禁止调整音量... - 媒体:禁止调整亮度、禁止调整音量...
- 其他:禁止修改账号、禁止修改语言、禁止恢复出设置、禁用调试功能... - 其他:禁止修改账号、禁止修改语言、禁止恢复出设置、禁用调试功能...
- 用户管理 - 用户管理
- 用户信息 - 用户信息
- 启动/切换/停止/删除用户 - 启动/切换/停止/删除用户

View File

@@ -24,8 +24,8 @@ android {
applicationId = "com.bintianqi.owndroid" applicationId = "com.bintianqi.owndroid"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 34 versionCode = 35
versionName = "6.2" versionName = "6.3"
multiDexEnabled = false multiDexEnabled = false
} }

View File

@@ -1,6 +1,5 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.annotation.SuppressLint
import android.app.PendingIntent import android.app.PendingIntent
import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT import android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT
@@ -20,6 +19,7 @@ import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -413,7 +413,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String) {
} }
@SuppressLint("NewApi") @RequiresApi(30)
@Composable @Composable
private fun UserCtrlDisabledPkg(pkgName:String) { private fun UserCtrlDisabledPkg(pkgName:String) {
val context = LocalContext.current val context = LocalContext.current
@@ -456,7 +456,7 @@ private fun UserCtrlDisabledPkg(pkgName:String) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(23)
@Composable @Composable
private fun PermissionManage(pkgName: String) { private fun PermissionManage(pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
@@ -556,7 +556,7 @@ private fun PermissionManage(pkgName: String) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(30)
@Composable @Composable
private fun CrossProfilePkg(pkgName: String) { private fun CrossProfilePkg(pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
@@ -636,7 +636,7 @@ private fun CrossProfileWidget(pkgName: String) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(34)
@Composable @Composable
private fun CredentialManagePolicy(pkgName: String) { private fun CredentialManagePolicy(pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
@@ -822,7 +822,7 @@ private fun PermittedIME(pkgName: String) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
private fun KeepUninstalledApp(pkgName: String) { private fun KeepUninstalledApp(pkgName: String) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -1,7 +1,6 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.accounts.Account import android.accounts.Account
import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE import android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE
import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE
@@ -21,6 +20,7 @@ import android.os.Build.VERSION
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility 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
@@ -59,8 +59,8 @@ import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.CardItem import com.bintianqi.owndroid.ui.CardItem
import com.bintianqi.owndroid.ui.CheckBoxItem import com.bintianqi.owndroid.ui.CheckBoxItem
import com.bintianqi.owndroid.ui.CopyTextButton import com.bintianqi.owndroid.ui.CopyTextButton
import com.bintianqi.owndroid.ui.InfoCard
import com.bintianqi.owndroid.ui.FunctionItem import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.InfoCard
import com.bintianqi.owndroid.ui.MyScaffold import com.bintianqi.owndroid.ui.MyScaffold
import com.bintianqi.owndroid.ui.SwitchItem import com.bintianqi.owndroid.ui.SwitchItem
import com.bintianqi.owndroid.yesOrNo import com.bintianqi.owndroid.yesOrNo
@@ -160,7 +160,7 @@ fun CreateWorkProfile(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(30)
@Composable @Composable
fun OrgOwnedProfile(navCtrl: NavHostController) { fun OrgOwnedProfile(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -180,7 +180,7 @@ fun OrgOwnedProfile(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(30)
@Composable @Composable
fun SuspendPersonalApp(navCtrl: NavHostController) { fun SuspendPersonalApp(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -1,7 +1,6 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog import android.app.AlertDialog
import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF
import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC
@@ -51,6 +50,7 @@ import android.telephony.data.ApnSetting.PROTOCOL_UNSTRUCTURED
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -717,7 +717,7 @@ private fun AddNetwork(wifiConfig: WifiConfiguration? = null, navCtrl: NavHostCo
} }
} }
@SuppressLint("NewApi") @RequiresApi(33)
@Composable @Composable
fun WifiSecurityLevel(navCtrl: NavHostController) { fun WifiSecurityLevel(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -743,7 +743,7 @@ fun WifiSecurityLevel(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(33)
@Composable @Composable
fun WifiSsidPolicy(navCtrl: NavHostController) { fun WifiSsidPolicy(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -817,7 +817,7 @@ fun WifiSsidPolicy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(29)
@Composable @Composable
fun PrivateDNS(navCtrl: NavHostController) { fun PrivateDNS(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -889,7 +889,7 @@ fun PrivateDNS(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun AlwaysOnVPNPackage(navCtrl: NavHostController, vm: MyViewModel) { fun AlwaysOnVPNPackage(navCtrl: NavHostController, vm: MyViewModel) {
val context = LocalContext.current val context = LocalContext.current
@@ -1056,7 +1056,7 @@ fun RecommendedGlobalProxy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(26)
@Composable @Composable
fun NetworkLogging(navCtrl: NavHostController) { fun NetworkLogging(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -1112,7 +1112,7 @@ fun NetworkLogging(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(31)
@Composable @Composable
fun WifiAuthKeypair(navCtrl: NavHostController) { fun WifiAuthKeypair(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -1154,7 +1154,7 @@ fun WifiAuthKeypair(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(33)
@Composable @Composable
fun PreferentialNetworkService(navCtrl: NavHostController) { fun PreferentialNetworkService(navCtrl: NavHostController) {
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
@@ -1306,7 +1306,7 @@ fun PreferentialNetworkService(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
fun OverrideAPN(navCtrl: NavHostController) { fun OverrideAPN(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -33,6 +33,7 @@ import android.content.Intent
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.UserManager import android.os.UserManager
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -232,7 +233,7 @@ fun PasswordInfo(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(26)
@Composable @Composable
fun ResetPasswordToken(navCtrl: NavHostController) { fun ResetPasswordToken(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -412,7 +413,7 @@ fun ResetPassword(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(31)
@Composable @Composable
fun PasswordComplexity(navCtrl: NavHostController) { fun PasswordComplexity(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -12,6 +12,7 @@ import android.os.Build.VERSION
import android.os.RemoteException import android.os.RemoteException
import android.os.UserManager import android.os.UserManager
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
@@ -234,7 +235,7 @@ private fun toggleDhizukuMode(status: Boolean, context: Context) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun LockScreenInfo(navCtrl: NavHostController) { fun LockScreenInfo(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -496,7 +497,7 @@ fun DeviceInfo(navCtrl: NavHostController) {
) )
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun SupportMessages(navCtrl: NavHostController) { fun SupportMessages(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -574,7 +575,7 @@ fun SupportMessages(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
fun TransferOwnership(navCtrl: NavHostController) { fun TransferOwnership(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -50,8 +50,10 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@@ -60,9 +62,11 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
@@ -77,14 +81,18 @@ import androidx.compose.material3.IconButton
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.SegmentedButton import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TimePicker import androidx.compose.material3.TimePicker
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberDatePickerState import androidx.compose.material3.rememberDatePickerState
import androidx.compose.material3.rememberTimePickerState import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -123,6 +131,7 @@ import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.InfoCard import com.bintianqi.owndroid.ui.InfoCard
import com.bintianqi.owndroid.ui.ListItem import com.bintianqi.owndroid.ui.ListItem
import com.bintianqi.owndroid.ui.MyScaffold import com.bintianqi.owndroid.ui.MyScaffold
import com.bintianqi.owndroid.ui.NavIcon
import com.bintianqi.owndroid.ui.RadioButtonItem import com.bintianqi.owndroid.ui.RadioButtonItem
import com.bintianqi.owndroid.ui.SwitchItem import com.bintianqi.owndroid.ui.SwitchItem
import com.bintianqi.owndroid.uriToStream import com.bintianqi.owndroid.uriToStream
@@ -133,9 +142,9 @@ import java.io.ByteArrayOutputStream
import java.util.Date import java.util.Date
import java.util.TimeZone import java.util.TimeZone
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.collections.addAll
import kotlin.math.roundToLong import kotlin.math.roundToLong
@SuppressLint("NewApi")
@Composable @Composable
fun SystemManage(navCtrl: NavHostController) { fun SystemManage(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -198,7 +207,7 @@ fun SystemManage(navCtrl: NavHostController) {
FunctionItem(R.string.wipe_data, icon = R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") } FunctionItem(R.string.wipe_data, icon = R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") }
} }
} }
if(dialog != 0) AlertDialog( if(dialog != 0 &&VERSION.SDK_INT >= 24) AlertDialog(
onDismissRequest = { dialog = 0 }, onDismissRequest = { dialog = 0 },
title = { Text(stringResource(if(dialog == 1) R.string.reboot else R.string.bug_report)) }, title = { Text(stringResource(if(dialog == 1) R.string.reboot else R.string.bug_report)) },
text = { Text(stringResource(if(dialog == 1) R.string.info_reboot else R.string.confirm_bug_report)) }, text = { Text(stringResource(if(dialog == 1) R.string.info_reboot else R.string.confirm_bug_report)) },
@@ -448,7 +457,7 @@ fun HardwareMonitor(navCtrl: NavHostController) {
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
fun ChangeTime(navCtrl: NavHostController) { fun ChangeTime(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -558,7 +567,7 @@ fun ChangeTime(navCtrl: NavHostController) {
) )
} }
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
fun ChangeTimeZone(navCtrl: NavHostController) { fun ChangeTimeZone(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -621,7 +630,7 @@ fun ChangeTimeZone(navCtrl: NavHostController) {
) )
} }
@SuppressLint("NewApi") @RequiresApi(23)
@Composable @Composable
fun PermissionPolicy(navCtrl: NavHostController) { fun PermissionPolicy(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -646,7 +655,7 @@ fun PermissionPolicy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(34)
@Composable @Composable
fun MTEPolicy(navCtrl: NavHostController) { fun MTEPolicy(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -674,7 +683,7 @@ fun MTEPolicy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(31)
@Composable @Composable
fun NearbyStreamingPolicy(navCtrl: NavHostController) { fun NearbyStreamingPolicy(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -739,206 +748,261 @@ fun NearbyStreamingPolicy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @OptIn(ExperimentalMaterial3Api::class)
@RequiresApi(28)
@Composable @Composable
fun LockTaskMode(navCtrl: NavHostController, vm: MyViewModel) { fun LockTaskMode(navCtrl: NavHostController, vm: MyViewModel) {
val coroutine = rememberCoroutineScope()
val pagerState = rememberPagerState { 3 }
var tabIndex by remember { mutableIntStateOf(0) }
tabIndex = pagerState.targetPage
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.lock_task_mode)) },
navigationIcon = { NavIcon { navCtrl.navigateUp() } }
)
}
) { paddingValues ->
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues)
) {
TabRow(tabIndex) {
Tab(
tabIndex == 0, onClick = { coroutine.launch { pagerState.animateScrollToPage(0) } },
text = { Text(stringResource(R.string.start)) }
)
Tab(
tabIndex == 1, onClick = { coroutine.launch { pagerState.animateScrollToPage(1) } },
text = { Text(stringResource(R.string.applications)) }
)
Tab(
tabIndex == 2, onClick = { coroutine.launch { pagerState.animateScrollToPage(2) } },
text = { Text(stringResource(R.string.features)) }
)
}
HorizontalPager(pagerState, verticalAlignment = Alignment.Top) { page ->
Column(
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 8.dp, end = 8.dp, bottom = 80.dp)
) {
if(page == 0) StartLockTaskMode(navCtrl, vm)
else if(page == 1) LockTaskPackages(navCtrl, vm)
else LockTaskFeatures()
}
}
}
}
}
@RequiresApi(28)
@Composable
private fun ColumnScope.StartLockTaskMode(navCtrl: NavHostController, vm: MyViewModel) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
var startLockTaskApp by rememberSaveable { mutableStateOf("") }
var startLockTaskActivity by rememberSaveable { mutableStateOf("") }
var specifyActivity by rememberSaveable { mutableStateOf(false) }
val updatePackage by vm.selectedPackage.collectAsStateWithLifecycle()
LaunchedEffect(updatePackage) {
if(updatePackage != "") {
startLockTaskApp = updatePackage
vm.selectedPackage.value = ""
}
}
Spacer(Modifier.padding(vertical = 5.dp))
OutlinedTextField(
value = startLockTaskApp,
onValueChange = { startLockTaskApp = it },
label = { Text(stringResource(R.string.package_name)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
trailingIcon = {
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
focusMgr.clearFocus()
navCtrl.navigate("PackageSelector")
})
.padding(3.dp))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
)
CheckBoxItem(R.string.specify_activity, specifyActivity) { specifyActivity = it }
AnimatedVisibility(specifyActivity) {
OutlinedTextField(
value = startLockTaskActivity,
onValueChange = { startLockTaskActivity = it },
label = { Text("Activity") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp)
)
}
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
if(!NotificationUtils.checkPermission(context)) return@Button
if(!dpm.isLockTaskPermitted(startLockTaskApp)) {
Toast.makeText(context, R.string.app_not_allowed, Toast.LENGTH_SHORT).show()
return@Button
}
val options = ActivityOptions.makeBasic().setLockTaskEnabled(true)
val packageManager = context.packageManager
val launchIntent = if(specifyActivity) Intent().setComponent(ComponentName(startLockTaskApp, startLockTaskActivity))
else packageManager.getLaunchIntentForPackage(startLockTaskApp)
if (launchIntent != null) {
context.startActivity(launchIntent, options.toBundle())
} else {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
}
) {
Text(stringResource(R.string.start))
}
InfoCard(R.string.info_start_lock_task_mode)
}
@RequiresApi(26)
@Composable
private fun ColumnScope.LockTaskPackages(navCtrl: NavHostController, vm: MyViewModel) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
var appSelectorRequest by rememberSaveable { mutableIntStateOf(0) } val lockTaskPackages = remember { mutableStateListOf<String>() }
MyScaffold(R.string.lock_task_mode, 8.dp, navCtrl, false) { var input by rememberSaveable { mutableStateOf("") }
var lockTaskFeatures by remember { mutableIntStateOf(0) } val updatePackage by vm.selectedPackage.collectAsStateWithLifecycle()
var custom by rememberSaveable { mutableStateOf(false) } LaunchedEffect(updatePackage) {
fun refreshFeature() { if(updatePackage != "") {
lockTaskFeatures = dpm.getLockTaskFeatures(receiver) input = updatePackage
custom = lockTaskFeatures != 0 vm.selectedPackage.value = ""
} }
Spacer(Modifier.padding(vertical = 10.dp)) }
Text(text = stringResource(R.string.lock_task_feature), style = typography.headlineLarge) LaunchedEffect(Unit) { lockTaskPackages.addAll(dpm.getLockTaskPackages(receiver)) }
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
LaunchedEffect(Unit) { refreshFeature() } if(lockTaskPackages.isEmpty()) Text(text = stringResource(R.string.none))
RadioButtonItem(R.string.disable_all, !custom) { custom = false } for(i in lockTaskPackages) {
RadioButtonItem(R.string.custom, custom) { custom = true } ListItem(i) { lockTaskPackages -= i }
AnimatedVisibility(custom) { }
Column { OutlinedTextField(
CheckBoxItem( value = input,
R.string.ltf_sys_info, onValueChange = { input = it },
lockTaskFeatures and LOCK_TASK_FEATURE_SYSTEM_INFO != 0 label = { Text(stringResource(R.string.package_name)) },
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_SYSTEM_INFO } keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
CheckBoxItem( keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
R.string.ltf_notifications, trailingIcon = {
lockTaskFeatures and LOCK_TASK_FEATURE_NOTIFICATIONS != 0 Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_NOTIFICATIONS } modifier = Modifier
CheckBoxItem( .clip(RoundedCornerShape(50))
R.string.ltf_home, .clickable(onClick = {
lockTaskFeatures and LOCK_TASK_FEATURE_HOME != 0 focusMgr.clearFocus()
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_HOME } navCtrl.navigate("PackageSelector")
CheckBoxItem( })
R.string.ltf_overview, .padding(3.dp))
lockTaskFeatures and LOCK_TASK_FEATURE_OVERVIEW != 0 },
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_OVERVIEW } modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
CheckBoxItem( )
R.string.ltf_global_actions, Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
lockTaskFeatures and LOCK_TASK_FEATURE_GLOBAL_ACTIONS != 0 Button(
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_GLOBAL_ACTIONS } onClick = {
CheckBoxItem( lockTaskPackages.add(input)
R.string.ltf_keyguard, input = ""
lockTaskFeatures and LOCK_TASK_FEATURE_KEYGUARD != 0 },
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_KEYGUARD } modifier = Modifier.fillMaxWidth(0.49F)
if(VERSION.SDK_INT >= 30) { ) {
CheckBoxItem( Text(stringResource(R.string.add))
R.string.ltf_block_activity_start_in_task,
lockTaskFeatures and LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK != 0
) { lockTaskFeatures = lockTaskFeatures xor LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK }
}
}
} }
Button( Button(
modifier = Modifier.fillMaxWidth(),
onClick = { onClick = {
try { lockTaskPackages.remove(input)
dpm.setLockTaskFeatures(receiver, lockTaskFeatures) input = ""
context.showOperationResultToast(true) },
} catch (e: IllegalArgumentException) { modifier = Modifier.fillMaxWidth(0.96F)
AlertDialog.Builder(context)
.setTitle(R.string.error)
.setMessage(e.message)
.setPositiveButton(R.string.confirm) { dialog, _ -> dialog.dismiss() }
.show()
}
refreshFeature()
}
) { ) {
Text(stringResource(R.string.apply)) Text(stringResource(R.string.remove))
} }
}
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
dpm.setLockTaskPackages(receiver, lockTaskPackages.toTypedArray())
context.showOperationResultToast(true)
}
) {
Text(stringResource(R.string.apply))
}
InfoCard(R.string.info_lock_task_packages)
}
val lockTaskPackages = remember { mutableStateListOf<String>() } @RequiresApi(28)
var inputLockTaskPkg by rememberSaveable { mutableStateOf("") } @Composable
LaunchedEffect(Unit) { lockTaskPackages.addAll(dpm.getLockTaskPackages(receiver)) } private fun ColumnScope.LockTaskFeatures() {
Spacer(Modifier.padding(vertical = 10.dp)) val context = LocalContext.current
Text(text = stringResource(R.string.lock_task_packages), style = typography.headlineLarge) val dpm = context.getDPM()
Spacer(Modifier.padding(vertical = 5.dp)) val receiver = context.getReceiver()
Column(modifier = Modifier.animateContentSize()) { var flags by remember { mutableIntStateOf(0) }
if(lockTaskPackages.isEmpty()) Text(text = stringResource(R.string.none)) var custom by rememberSaveable { mutableStateOf(false) }
for(i in lockTaskPackages) { fun refresh() {
ListItem(i) { lockTaskPackages -= i } flags = dpm.getLockTaskFeatures(receiver)
custom = flags != 0
}
LaunchedEffect(Unit) { refresh() }
Spacer(Modifier.padding(vertical = 5.dp))
RadioButtonItem(R.string.disable_all, !custom) { custom = false }
RadioButtonItem(R.string.custom, custom) { custom = true }
AnimatedVisibility(custom) {
Column {
CheckBoxItem(
R.string.ltf_sys_info,
flags and LOCK_TASK_FEATURE_SYSTEM_INFO != 0
) { flags = flags xor LOCK_TASK_FEATURE_SYSTEM_INFO }
CheckBoxItem(
R.string.ltf_notifications,
flags and LOCK_TASK_FEATURE_NOTIFICATIONS != 0
) { flags = flags xor LOCK_TASK_FEATURE_NOTIFICATIONS }
CheckBoxItem(
R.string.ltf_home,
flags and LOCK_TASK_FEATURE_HOME != 0
) { flags = flags xor LOCK_TASK_FEATURE_HOME }
CheckBoxItem(
R.string.ltf_overview,
flags and LOCK_TASK_FEATURE_OVERVIEW != 0
) { flags = flags xor LOCK_TASK_FEATURE_OVERVIEW }
CheckBoxItem(
R.string.ltf_global_actions,
flags and LOCK_TASK_FEATURE_GLOBAL_ACTIONS != 0
) { flags = flags xor LOCK_TASK_FEATURE_GLOBAL_ACTIONS }
CheckBoxItem(
R.string.ltf_keyguard,
flags and LOCK_TASK_FEATURE_KEYGUARD != 0
) { flags = flags xor LOCK_TASK_FEATURE_KEYGUARD }
if(VERSION.SDK_INT >= 30) {
CheckBoxItem(
R.string.ltf_block_activity_start_in_task,
flags and LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK != 0
) { flags = flags xor LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK }
} }
} }
OutlinedTextField( }
value = inputLockTaskPkg, Button(
onValueChange = { inputLockTaskPkg = it }, modifier = Modifier.fillMaxWidth(),
label = { Text(stringResource(R.string.package_name)) }, onClick = {
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), try {
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), dpm.setLockTaskFeatures(receiver, flags)
trailingIcon = {
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
focusMgr.clearFocus()
appSelectorRequest = 1
navCtrl.navigate("PackageSelector")
})
.padding(3.dp))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
)
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
lockTaskPackages.add(inputLockTaskPkg)
inputLockTaskPkg = ""
},
modifier = Modifier.fillMaxWidth(0.49F)
) {
Text(stringResource(R.string.add))
}
Button(
onClick = {
lockTaskPackages.remove(inputLockTaskPkg)
inputLockTaskPkg = ""
},
modifier = Modifier.fillMaxWidth(0.96F)
) {
Text(stringResource(R.string.remove))
}
}
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
dpm.setLockTaskPackages(receiver, lockTaskPackages.toTypedArray())
context.showOperationResultToast(true) context.showOperationResultToast(true)
} catch (e: IllegalArgumentException) {
AlertDialog.Builder(context)
.setTitle(R.string.error)
.setMessage(e.message)
.setPositiveButton(R.string.confirm) { dialog, _ -> dialog.dismiss() }
.show()
} }
) { refresh()
Text(stringResource(R.string.apply))
} }
InfoCard(R.string.info_lock_task_packages) ) {
var startLockTaskApp by rememberSaveable { mutableStateOf("") } Text(stringResource(R.string.apply))
var startLockTaskActivity by rememberSaveable { mutableStateOf("") }
var specifyActivity by rememberSaveable { mutableStateOf(false) }
val updatePackage by vm.selectedPackage.collectAsStateWithLifecycle()
LaunchedEffect(updatePackage) {
if(updatePackage != "") {
if(appSelectorRequest == 1) inputLockTaskPkg = updatePackage else startLockTaskApp = updatePackage
vm.selectedPackage.value = ""
}
}
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.start_lock_task_mode), style = typography.headlineLarge)
Spacer(Modifier.padding(vertical = 5.dp))
OutlinedTextField(
value = startLockTaskApp,
onValueChange = { startLockTaskApp = it },
label = { Text(stringResource(R.string.package_name)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
trailingIcon = {
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
focusMgr.clearFocus()
appSelectorRequest = 2
navCtrl.navigate("PackageSelector")
})
.padding(3.dp))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
)
CheckBoxItem(R.string.specify_activity, specifyActivity) { specifyActivity = it }
AnimatedVisibility(specifyActivity) {
OutlinedTextField(
value = startLockTaskActivity,
onValueChange = { startLockTaskActivity = it },
label = { Text("Activity") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp)
)
}
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
if(!NotificationUtils.checkPermission(context)) return@Button
if(!dpm.isLockTaskPermitted(startLockTaskApp)) {
Toast.makeText(context, R.string.app_not_allowed, Toast.LENGTH_SHORT).show()
return@Button
}
val options = ActivityOptions.makeBasic().setLockTaskEnabled(true)
val packageManager = context.packageManager
val launchIntent = if(specifyActivity) Intent().setComponent(ComponentName(startLockTaskApp, startLockTaskActivity))
else packageManager.getLaunchIntentForPackage(startLockTaskApp)
if (launchIntent != null) {
context.startActivity(launchIntent, options.toBundle())
} else {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
}
) {
Text(stringResource(R.string.start))
}
InfoCard(R.string.info_start_lock_task_mode)
} }
} }
@@ -1016,7 +1080,7 @@ fun CACert(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun SecurityLogging(navCtrl: NavHostController) { fun SecurityLogging(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -1152,7 +1216,7 @@ fun DisableAccountManagement(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(30)
@Composable @Composable
fun FRPPolicy(navCtrl: NavHostController) { fun FRPPolicy(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -1244,7 +1308,6 @@ fun FRPPolicy(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi")
@Composable @Composable
fun WipeData(navCtrl: NavHostController) { fun WipeData(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -1305,7 +1368,10 @@ fun WipeData(navCtrl: NavHostController) {
}, },
text = { text = {
Text( Text(
text = stringResource(if(userManager.isSystemUser) R.string.wipe_data_warning else R.string.info_wipe_data_in_managed_user), text = stringResource(
if(VERSION.SDK_INT >= 23 && userManager.isSystemUser) R.string.wipe_data_warning
else R.string.info_wipe_data_in_managed_user
),
color = colorScheme.error color = colorScheme.error
) )
}, },
@@ -1322,7 +1388,7 @@ fun WipeData(navCtrl: NavHostController) {
TextButton( TextButton(
onClick = { onClick = {
if(silent && VERSION.SDK_INT >= 29) { flag = flag or WIPE_SILENTLY } if(silent && VERSION.SDK_INT >= 29) { flag = flag or WIPE_SILENTLY }
if(wipeDevice) { if(wipeDevice && VERSION.SDK_INT >= 34) {
dpm.wipeDevice(flag) dpm.wipeDevice(flag)
} else { } else {
if(VERSION.SDK_INT >= 28 && reason != "") { if(VERSION.SDK_INT >= 28 && reason != "") {

View File

@@ -1,10 +1,10 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.annotation.SuppressLint
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.UserManager import android.os.UserManager
import android.widget.Toast import android.widget.Toast
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@@ -48,7 +48,7 @@ fun UserRestriction(navCtrl:NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun UserRestrictionItem(restriction: Restriction) { fun UserRestrictionItem(restriction: Restriction) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -1,6 +1,5 @@
package com.bintianqi.owndroid.dpm package com.bintianqi.owndroid.dpm
import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -15,6 +14,7 @@ import android.provider.MediaStore
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
@@ -299,7 +299,7 @@ fun UserOperation(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(24)
@Composable @Composable
fun CreateUser(navCtrl: NavHostController) { fun CreateUser(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -350,7 +350,7 @@ fun CreateUser(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(26)
@Composable @Composable
fun AffiliationID(navCtrl: NavHostController) { fun AffiliationID(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -441,7 +441,7 @@ fun ChangeUsername(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(28)
@Composable @Composable
fun UserSessionMessage(navCtrl: NavHostController) { fun UserSessionMessage(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current
@@ -519,7 +519,7 @@ fun UserSessionMessage(navCtrl: NavHostController) {
} }
} }
@SuppressLint("NewApi") @RequiresApi(23)
@Composable @Composable
fun ChangeUserIcon(navCtrl: NavHostController) { fun ChangeUserIcon(navCtrl: NavHostController) {
val context = LocalContext.current val context = LocalContext.current

View File

@@ -65,6 +65,9 @@
<string name="permission_denied">Permission denied</string> <string name="permission_denied">Permission denied</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="status">Status</string> <string name="status">Status</string>
<string name="edit">Edit</string>
<string name="overview">Overview</string>
<string name="features">Features</string>
<!--Разрешения--> <!--Разрешения-->
@@ -170,10 +173,7 @@
<string name="nearby_notification_streaming">Политика потоковой передачи уведомлений Nearby</string> <string name="nearby_notification_streaming">Политика потоковой передачи уведомлений Nearby</string>
<string name="enable_if_secure_enough">Только для одной управляемой учетной записи</string> <string name="enable_if_secure_enough">Только для одной управляемой учетной записи</string>
<string name="lock_task_mode">Режим закрепления задачи</string> <string name="lock_task_mode">Режим закрепления задачи</string>
<string name="lock_task_feature">Функция закрепления задачи</string>
<string name="lock_task_packages">Закрепленные пакеты</string>
<string name="specify_activity">Указать Acitvity</string> <string name="specify_activity">Указать Acitvity</string>
<string name="start_lock_task_mode">Запустить режим закрепления задачи</string>
<string name="app_not_allowed">Приложение не разрешено</string> <string name="app_not_allowed">Приложение не разрешено</string>
<string name="disable_all">Отключить все</string> <string name="disable_all">Отключить все</string>
<!--ltf: функция закрепления задачи--> <!--ltf: функция закрепления задачи-->
@@ -553,7 +553,6 @@
<string name="disable_keyguard_features_unredacted_notification">Отключить неотредактированные уведомления</string> <string name="disable_keyguard_features_unredacted_notification">Отключить неотредактированные уведомления</string>
<string name="disable_keyguard_features_trust_agents">Отключить доверенные агенты</string> <string name="disable_keyguard_features_trust_agents">Отключить доверенные агенты</string>
<string name="disable_keyguard_features_fingerprint">Отключить отпечаток пальца</string> <string name="disable_keyguard_features_fingerprint">Отключить отпечаток пальца</string>
<string name="disable_keyguard_features_remote_input">Отключить удаленный ввод</string>
<string name="disable_keyguard_features_face">Отключить распознавание лица</string> <string name="disable_keyguard_features_face">Отключить распознавание лица</string>
<string name="disable_keyguard_features_iris">Отключить сканер радужной оболочки</string> <string name="disable_keyguard_features_iris">Отключить сканер радужной оболочки</string>
<string name="disable_keyguard_features_biometrics">Отключить биометрию</string> <string name="disable_keyguard_features_biometrics">Отключить биометрию</string>

View File

@@ -66,6 +66,9 @@
<string name="permission_denied">Permission denied</string> <string name="permission_denied">Permission denied</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="status">Status</string> <string name="status">Status</string>
<string name="edit">Edit</string>
<string name="overview">Overview</string>
<string name="features">Features</string>
<!--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>
@@ -171,10 +174,7 @@
<string name="nearby_notification_streaming">Yakındaki bildirim akış politikası</string> <string name="nearby_notification_streaming">Yakındaki bildirim akış politikası</string>
<string name="enable_if_secure_enough">Yalnızca aynı yönetilen hesap</string> <string name="enable_if_secure_enough">Yalnızca aynı yönetilen hesap</string>
<string name="lock_task_mode">Lock task mode</string> <!--TODO--> <string name="lock_task_mode">Lock task mode</string> <!--TODO-->
<string name="lock_task_feature">Görev kilitleme özelliği</string>
<string name="lock_task_packages">Lock task packages</string> <!--TODO-->
<string name="specify_activity">Specify Activity</string> <!--TODO--> <string name="specify_activity">Specify Activity</string> <!--TODO-->
<string name="start_lock_task_mode">Start lock task mode</string> <!--TODO-->
<string name="app_not_allowed">App is not allowed</string> <!--TODO--> <string name="app_not_allowed">App is not allowed</string> <!--TODO-->
<string name="disable_all">Hepsini devre dışı bırak</string> <string name="disable_all">Hepsini devre dışı bırak</string>
@@ -549,7 +549,6 @@
<string name="disable_keyguard_features_unredacted_notification">Sansürsüz bildirimleri devre dışı bırak</string> <string name="disable_keyguard_features_unredacted_notification">Sansürsüz bildirimleri devre dışı bırak</string>
<string name="disable_keyguard_features_trust_agents">Güvenilir ajanları devre dışı bırak</string> <string name="disable_keyguard_features_trust_agents">Güvenilir ajanları devre dışı bırak</string>
<string name="disable_keyguard_features_fingerprint">Parmak izini devre dışı bırak</string> <string name="disable_keyguard_features_fingerprint">Parmak izini devre dışı bırak</string>
<string name="disable_keyguard_features_remote_input">Uzaktan girişleri devre dışı bırak</string>
<string name="disable_keyguard_features_face">Yüz tanımayı devre dışı bırak</string> <string name="disable_keyguard_features_face">Yüz tanımayı devre dışı bırak</string>
<string name="disable_keyguard_features_iris">İris tarayıcısını devre dışı bırak</string> <string name="disable_keyguard_features_iris">İris tarayıcısını devre dışı bırak</string>
<string name="disable_keyguard_features_biometrics">Biyometrikleri devre dışı bırak</string> <string name="disable_keyguard_features_biometrics">Biyometrikleri devre dışı bırak</string>

View File

@@ -62,6 +62,9 @@
<string name="permission_denied">无权限</string> <string name="permission_denied">无权限</string>
<string name="error">错误</string> <string name="error">错误</string>
<string name="status">状态</string> <string name="status">状态</string>
<string name="edit">编辑</string>
<string name="overview">概览</string>
<string name="features">功能</string>
<!--Permissions--> <!--Permissions-->
<string name="click_to_activate">点击以激活</string> <string name="click_to_activate">点击以激活</string>
@@ -163,10 +166,7 @@
<string name="nearby_notification_streaming">附近通知传输</string> <string name="nearby_notification_streaming">附近通知传输</string>
<string name="enable_if_secure_enough">在足够安全时启用</string> <string name="enable_if_secure_enough">在足够安全时启用</string>
<string name="lock_task_mode">锁定任务模式</string> <string name="lock_task_mode">锁定任务模式</string>
<string name="lock_task_feature">锁定任务功能</string>
<string name="lock_task_packages">锁定任务应用</string>
<string name="specify_activity">指定Activity</string> <string name="specify_activity">指定Activity</string>
<string name="start_lock_task_mode">启动锁定任务模式</string>
<string name="app_not_allowed">应用未被允许</string> <string name="app_not_allowed">应用未被允许</string>
<string name="disable_all">禁用全部</string> <string name="disable_all">禁用全部</string>
<string name="ltf_sys_info">允许状态栏信息</string> <string name="ltf_sys_info">允许状态栏信息</string>
@@ -537,7 +537,6 @@
<string name="disable_keyguard_features_unredacted_notification">禁用未经编辑的通知</string> <string name="disable_keyguard_features_unredacted_notification">禁用未经编辑的通知</string>
<string name="disable_keyguard_features_trust_agents">禁用可信代理</string> <string name="disable_keyguard_features_trust_agents">禁用可信代理</string>
<string name="disable_keyguard_features_fingerprint">禁用指纹解锁</string> <string name="disable_keyguard_features_fingerprint">禁用指纹解锁</string>
<string name="disable_keyguard_features_remote_input">禁止远程输入(弃用)</string>
<string name="disable_keyguard_features_face">禁用人脸解锁</string> <string name="disable_keyguard_features_face">禁用人脸解锁</string>
<string name="disable_keyguard_features_iris">禁用虹膜解锁(?)</string> <string name="disable_keyguard_features_iris">禁用虹膜解锁(?)</string>
<string name="disable_keyguard_features_biometrics">禁用生物识别</string> <string name="disable_keyguard_features_biometrics">禁用生物识别</string>

View File

@@ -69,6 +69,7 @@
<string name="status">Status</string> <string name="status">Status</string>
<string name="edit">Edit</string> <string name="edit">Edit</string>
<string name="overview">Overview</string> <string name="overview">Overview</string>
<string name="features">Features</string>
<!--Permissions--> <!--Permissions-->
<string name="click_to_activate">Click to activate</string> <string name="click_to_activate">Click to activate</string>
@@ -177,10 +178,7 @@
<string name="nearby_notification_streaming">Nearby notification streaming policy</string> <string name="nearby_notification_streaming">Nearby notification streaming policy</string>
<string name="enable_if_secure_enough">Same managed account only</string> <string name="enable_if_secure_enough">Same managed account only</string>
<string name="lock_task_mode">Lock task mode</string> <string name="lock_task_mode">Lock task mode</string>
<string name="lock_task_feature">Lock task feature</string>
<string name="lock_task_packages">Lock task packages</string>
<string name="specify_activity">Specify Activity</string> <string name="specify_activity">Specify Activity</string>
<string name="start_lock_task_mode">Start lock task mode</string>
<string name="app_not_allowed">App is not allowed</string> <string name="app_not_allowed">App is not allowed</string>
<string name="disable_all">Disable all</string> <string name="disable_all">Disable all</string>
<!--ltf: lock task feature--> <!--ltf: lock task feature-->
@@ -556,7 +554,6 @@
<string name="disable_keyguard_features_unredacted_notification">Disable unredacted notification</string> <string name="disable_keyguard_features_unredacted_notification">Disable unredacted notification</string>
<string name="disable_keyguard_features_trust_agents">Disable trust agents</string> <string name="disable_keyguard_features_trust_agents">Disable trust agents</string>
<string name="disable_keyguard_features_fingerprint">Disable fingerprint</string> <string name="disable_keyguard_features_fingerprint">Disable fingerprint</string>
<string name="disable_keyguard_features_remote_input">Disable remote input</string>
<string name="disable_keyguard_features_face">Disable face</string> <string name="disable_keyguard_features_face">Disable face</string>
<string name="disable_keyguard_features_iris">Disable iris</string> <string name="disable_keyguard_features_iris">Disable iris</string>
<string name="disable_keyguard_features_biometrics">Disable biometrics</string> <string name="disable_keyguard_features_biometrics">Disable biometrics</string>