mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-27 20:36:00 +00:00
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:
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
- 应用:禁止安装/卸载应用...
|
- 应用:禁止安装/卸载应用...
|
||||||
- 用户:禁止添加/删除/切换用户...
|
- 用户:禁止添加/删除/切换用户...
|
||||||
- 媒体:禁止调整亮度、禁止调整音量...
|
- 媒体:禁止调整亮度、禁止调整音量...
|
||||||
- 其他:禁止修改账号、禁止修改语言、禁止恢复出场设置、禁用调试功能...
|
- 其他:禁止修改账号、禁止修改语言、禁止恢复出厂设置、禁用调试功能...
|
||||||
- 用户管理
|
- 用户管理
|
||||||
- 用户信息
|
- 用户信息
|
||||||
- 启动/切换/停止/删除用户
|
- 启动/切换/停止/删除用户
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 != "") {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user