mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
require password complexity or quality
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"/>
|
||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS"/>
|
||||||
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"/>
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"/>
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS"/>
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS"/>
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
@@ -21,11 +23,17 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize|stateHidden"
|
||||||
android:theme="@style/Theme.AndroidOwner">
|
android:theme="@style/Theme.AndroidOwner">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<action android:name="android.app.action.PROVISIONING_SUCCESSFUL" />
|
||||||
|
<action android:name="android.app.action.PROVISION_MANAGED_PROFILE"/>
|
||||||
|
<action android:name="android.app.action.MANAGED_PROFILE_PROVISIONED"/>
|
||||||
|
<action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.INFO"/>
|
||||||
|
<category android:name="android.intent.category.HOME"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
@@ -39,6 +47,10 @@
|
|||||||
android:name="android.app.device_admin"
|
android:name="android.app.device_admin"
|
||||||
android:resource="@xml/device_admin"/>
|
android:resource="@xml/device_admin"/>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<action android:name="android.app.action.PROVISIONING_SUCCESSFUL" />
|
||||||
|
<action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
|
||||||
|
<action android:name="android.app.action.PROVISION_MANAGED_PROFILE"/>
|
||||||
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
|
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
|
||||||
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"/>
|
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"/>
|
||||||
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED"/>
|
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED"/>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.content.pm.PackageInstaller
|
|||||||
import android.content.pm.PackageManager.NameNotFoundException
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -48,13 +49,13 @@ fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName,myCon
|
|||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Text("以下功能都需要DeviceOwner权限")
|
|
||||||
TextField(
|
TextField(
|
||||||
value = pkgName,
|
value = pkgName,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
pkgName = it
|
pkgName = it
|
||||||
},
|
},
|
||||||
label = { Text("包名") },
|
label = { Text("包名") },
|
||||||
|
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
@@ -94,6 +95,41 @@ fun ApplicationManage(myDpm:DevicePolicyManager, myComponent:ComponentName,myCon
|
|||||||
Text("防卸载")
|
Text("防卸载")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 5.dp, vertical = 4.dp)
|
||||||
|
.clip(RoundedCornerShape(14.dp))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
Text(text = "许可的输入法", style = MaterialTheme.typography.titleLarge)
|
||||||
|
val imeList = myDpm.getPermittedInputMethods(myComponent)
|
||||||
|
var imeListText = ""
|
||||||
|
if (imeList != null) {
|
||||||
|
for(eachIme in imeList){
|
||||||
|
imeListText += "$eachIme \n"
|
||||||
|
//Log.e("",eachIme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(imeListText)
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
imeList?.plus(pkgName)
|
||||||
|
myDpm.setPermittedInputMethods(myComponent, imeList)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("设为许可的输入法")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
imeList?.remove(pkgName)
|
||||||
|
myDpm.setPermittedInputMethods(myComponent,imeList)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("从列表中移除")
|
||||||
|
}
|
||||||
|
}
|
||||||
/*Button(
|
/*Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
uninstallPkg(pkgName,myContext)
|
uninstallPkg(pkgName,myContext)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val context = applicationContext
|
val context = applicationContext
|
||||||
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
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.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -16,7 +15,6 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
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
|
||||||
@@ -34,6 +32,7 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -83,7 +82,10 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
|
|||||||
) {
|
) {
|
||||||
if(VERSION.SDK_INT>=29){
|
if(VERSION.SDK_INT>=29){
|
||||||
val pwdComplex = myDpm.passwordComplexity
|
val pwdComplex = myDpm.passwordComplexity
|
||||||
Text(text = "密码复杂度:$pwdComplex")
|
Text(text = "当前密码复杂度:$pwdComplex")
|
||||||
|
}
|
||||||
|
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
|
||||||
|
Text("密码达到要求:${myDpm.isActivePasswordSufficient}")
|
||||||
}
|
}
|
||||||
val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts
|
val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts
|
||||||
Text(text = "密码已错误次数:$pwdFailedAttempts")
|
Text(text = "密码已错误次数:$pwdFailedAttempts")
|
||||||
@@ -204,12 +206,100 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordItem(R.string.max_pwd_fail,R.string.max_pwd_fail_desc,R.string.max_pwd_fail_textfield, myDpm,focusMgr,false,
|
PasswordItem(R.string.max_pwd_fail,R.string.max_pwd_fail_desc,R.string.max_pwd_fail_textfield, myDpm,focusMgr,false,
|
||||||
{myDpm.getMaximumFailedPasswordsForWipe(null).toString()},{ic -> myDpm.setMaximumFailedPasswordsForWipe(myComponent, ic.toInt()) })
|
{myDpm.getMaximumFailedPasswordsForWipe(null).toString()},{ic -> myDpm.setMaximumFailedPasswordsForWipe(myComponent, ic.toInt()) })
|
||||||
PasswordItem(R.string.pwd_timeout,R.string.pwd_timeout_desc,R.string.pwd_timeout_textfield, myDpm,focusMgr,true,
|
PasswordItem(R.string.pwd_timeout,R.string.pwd_timeout_desc,R.string.pwd_timeout_textfield, myDpm,focusMgr,true,
|
||||||
{myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) })
|
{myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) })
|
||||||
PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield,myDpm, focusMgr,true,
|
PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield,myDpm, focusMgr,true,
|
||||||
{myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) })
|
{myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) })
|
||||||
|
|
||||||
|
if(VERSION.SDK_INT>=31){
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
val passwordComplexity = mapOf(
|
||||||
|
DevicePolicyManager.PASSWORD_COMPLEXITY_NONE to "无复杂度(允许不设密码)",
|
||||||
|
DevicePolicyManager.PASSWORD_COMPLEXITY_LOW to "低复杂度(允许图案和连续性)",
|
||||||
|
DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM to "中复杂度(无连续性,至少4位)",
|
||||||
|
DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH to "高复杂度(无连续性,至少6位)"
|
||||||
|
).toList()
|
||||||
|
var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) }
|
||||||
|
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
|
||||||
|
selectedItem=myDpm.requiredPasswordComplexity
|
||||||
|
}
|
||||||
|
Text(text = "密码复杂度要求", style = MaterialTheme.typography.titleLarge)
|
||||||
|
Text(text = "不是实际密码复杂度")
|
||||||
|
Text(text = "设置密码复杂度将会取代密码质量")
|
||||||
|
RadioButtonItem(passwordComplexity[0].second,{selectedItem==passwordComplexity[0].first},{selectedItem=passwordComplexity[0].first})
|
||||||
|
RadioButtonItem(passwordComplexity[1].second,{selectedItem==passwordComplexity[1].first},{selectedItem=passwordComplexity[1].first})
|
||||||
|
RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first})
|
||||||
|
RadioButtonItem(passwordComplexity[3].second,{selectedItem==passwordComplexity[3].first},{selectedItem=passwordComplexity[3].first})
|
||||||
|
Text(text = "连续性:密码重复(6666)或密码递增递减(4321、2468)", modifier = Modifier.padding(vertical = 3.dp))
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.requiredPasswordComplexity = selectedItem
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
},
|
||||||
|
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm)
|
||||||
|
) {
|
||||||
|
Text("应用")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
val passwordQuality = mapOf(
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED to "未指定",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING to "需要密码或图案,不管复杂度",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC to "至少1个字母",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC to "至少1个数字",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC to "数字字母各至少一个",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK to "生物识别(弱)",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX to "复杂数字(无连续性)",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX to "自定义",
|
||||||
|
).toList()
|
||||||
|
var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) }
|
||||||
|
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
|
||||||
|
selectedItem=myDpm.getPasswordQuality(myComponent)
|
||||||
|
}
|
||||||
|
Text(text = "密码质量要求", style = MaterialTheme.typography.titleLarge)
|
||||||
|
Text(text = "不是实际密码质量")
|
||||||
|
if(VERSION.SDK_INT>=31){
|
||||||
|
Text(text = "已弃用,请使用上面的”密码复杂度要求“", color = MaterialTheme.colorScheme.error)
|
||||||
|
}
|
||||||
|
RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first})
|
||||||
|
RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first})
|
||||||
|
RadioButtonItem(passwordQuality[2].second,{selectedItem==passwordQuality[2].first},{selectedItem=passwordQuality[2].first})
|
||||||
|
RadioButtonItem(passwordQuality[3].second,{selectedItem==passwordQuality[3].first},{selectedItem=passwordQuality[3].first})
|
||||||
|
RadioButtonItem(passwordQuality[4].second,{selectedItem==passwordQuality[4].first},{selectedItem=passwordQuality[4].first})
|
||||||
|
RadioButtonItem(passwordQuality[5].second,{selectedItem==passwordQuality[5].first},{selectedItem=passwordQuality[5].first})
|
||||||
|
RadioButtonItem(passwordQuality[6].second,{selectedItem==passwordQuality[6].first},{selectedItem=passwordQuality[6].first})
|
||||||
|
RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first})
|
||||||
|
Text(text = "连续性:密码重复(6666)或密码递增递减(4321、2468)", modifier = Modifier.padding(vertical = 3.dp))
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
myDpm.setPasswordQuality(myComponent,selectedItem)
|
||||||
|
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
|
||||||
|
},
|
||||||
|
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm)
|
||||||
|
) {
|
||||||
|
Text("应用")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(Modifier.padding(vertical = 20.dp))
|
Spacer(Modifier.padding(vertical = 20.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
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.KeyboardOptions
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
@@ -33,6 +35,8 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.focus.FocusManager
|
import androidx.compose.ui.focus.FocusManager
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
@@ -79,9 +83,9 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
|
|||||||
Text("撤销")
|
Text("撤销")
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
/*Button(onClick = { activateDeviceAdmin(myContext,myComponent) }) {
|
Button(onClick = { activateDeviceAdmin(myContext,myComponent) }) {
|
||||||
Text("激活")
|
Text("激活")
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!isda){
|
if(!isda){
|
||||||
@@ -220,18 +224,96 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 5.dp)
|
.padding(vertical = 5.dp)
|
||||||
.clip(RoundedCornerShape(15))
|
.clip(RoundedCornerShape(15.dp))
|
||||||
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
Text(text = "设备信息", style = MaterialTheme.typography.titleLarge)
|
Text(text = "设备信息", style = MaterialTheme.typography.titleLarge)
|
||||||
val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile
|
val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile
|
||||||
Text("由组织拥有的受管理资料设备:$orgDevice")
|
Text("由组织拥有的受管理资料设备:$orgDevice")
|
||||||
|
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
|
||||||
Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}")
|
Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}")
|
||||||
|
}
|
||||||
if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){
|
if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){
|
||||||
val financed = myDpm.isDeviceFinanced
|
val financed = myDpm.isDeviceFinanced
|
||||||
Text("企业资产 : $financed")
|
Text("企业资产 : $financed")
|
||||||
}
|
}
|
||||||
|
if(VERSION.SDK_INT>=33){
|
||||||
|
Text("最小WiFi安全等级:${myDpm.minimumRequiredWifiSecurityLevel}")
|
||||||
|
Text("设备策略管理器角色:${myDpm.devicePolicyManagementRoleHolderPackage}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(VERSION.SDK_INT>=31&&(isProfileOwner(myDpm)|| isDeviceOwner(myDpm))){
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.clip(RoundedCornerShape(15.dp))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
val specificId = myDpm.enrollmentSpecificId
|
||||||
|
Text(text = "设备唯一标识码", style = MaterialTheme.typography.titleLarge)
|
||||||
|
Text("(恢复出厂设置不变)")
|
||||||
|
Text("(如果下面没有一长串数字字母组合,说明你的设备不支持)")
|
||||||
|
Text(specificId)
|
||||||
|
Button(onClick = {myDpm.setOrganizationId(specificId)}, enabled = specificId!="") {
|
||||||
|
Text("设置为组织ID")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.clip(RoundedCornerShape(15.dp))
|
||||||
|
.background(color = MaterialTheme.colorScheme.primaryContainer)
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
Text(text = "不受控制的账号类型", style = MaterialTheme.typography.titleLarge)
|
||||||
|
Text("作用未知")
|
||||||
|
var noManageAccount = myDpm.accountTypesWithManagementDisabled?.toMutableList()
|
||||||
|
var accountlist by remember{ mutableStateOf("") }
|
||||||
|
val refreshList = {
|
||||||
|
accountlist = ""
|
||||||
|
if (noManageAccount != null) {
|
||||||
|
for(eachAccount in noManageAccount!!){
|
||||||
|
accountlist+="$eachAccount \n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
refreshList()
|
||||||
|
if(accountlist!=""){
|
||||||
|
Text(accountlist)
|
||||||
|
}else{
|
||||||
|
Text("列表为空 \n")
|
||||||
|
}
|
||||||
|
var inputText by remember{ mutableStateOf("") }
|
||||||
|
TextField(
|
||||||
|
value = inputText,
|
||||||
|
onValueChange = {inputText=it},
|
||||||
|
label = {Text("账号类型")},
|
||||||
|
modifier = Modifier.padding(bottom = 4.dp),
|
||||||
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
|
keyboardActions = KeyboardActions(onDone = {focusManager.clearFocus()})
|
||||||
|
)
|
||||||
|
Button(onClick={focusManager.clearFocus()
|
||||||
|
myDpm.setAccountManagementDisabled(myComponent,inputText,true)
|
||||||
|
noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList()
|
||||||
|
refreshList()
|
||||||
|
}){
|
||||||
|
Text("添加至列表")
|
||||||
|
}
|
||||||
|
Button(onClick={focusManager.clearFocus()
|
||||||
|
myDpm.setAccountManagementDisabled(myComponent,inputText,false)
|
||||||
|
noManageAccount=myDpm.accountTypesWithManagementDisabled?.toMutableList()
|
||||||
|
refreshList()
|
||||||
|
}){
|
||||||
|
Text("从列表中移除")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.binbin.androidowner
|
package com.binbin.androidowner
|
||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.Activity
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
|
import android.os.Build.VERSION_CODES
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@@ -34,8 +37,11 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.app.ActivityCompat.startActivityForResult
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.core.os.UserManagerCompat
|
import androidx.core.os.UserManagerCompat
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Context){
|
fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Context){
|
||||||
Column(
|
Column(
|
||||||
@@ -66,8 +72,10 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
|
|||||||
if (VERSION.SDK_INT >= 28) {
|
if (VERSION.SDK_INT >= 28) {
|
||||||
val logoutable = myDpm.isLogoutEnabled
|
val logoutable = myDpm.isLogoutEnabled
|
||||||
Text(text = "用户可以退出 : $logoutable")
|
Text(text = "用户可以退出 : $logoutable")
|
||||||
|
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
|
||||||
val ephemeralUser = myDpm.isEphemeralUser(myComponent)
|
val ephemeralUser = myDpm.isEphemeralUser(myComponent)
|
||||||
Text(text = "临时用户: $ephemeralUser")
|
Text(text = "临时用户: $ephemeralUser")
|
||||||
|
}
|
||||||
val affiliatedUser = myDpm.isAffiliatedUser
|
val affiliatedUser = myDpm.isAffiliatedUser
|
||||||
Text(text = "次级用户: $affiliatedUser")
|
Text(text = "次级用户: $affiliatedUser")
|
||||||
}
|
}
|
||||||
@@ -94,18 +102,19 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
|
|||||||
if(resultForLogout!=-1){
|
if(resultForLogout!=-1){
|
||||||
Text(userOperationResultCode(resultForLogout))
|
Text(userOperationResultCode(resultForLogout))
|
||||||
}
|
}
|
||||||
|
Button(onClick = {myDpm.switchUser(myComponent,currentUser)}, enabled = isDeviceOwner(myDpm)) {
|
||||||
|
Text("切换用户")
|
||||||
|
}
|
||||||
Button(onClick = {resultForStop = myDpm.stopUser(myComponent,currentUser)}, enabled = isDeviceOwner(myDpm)) {
|
Button(onClick = {resultForStop = myDpm.stopUser(myComponent,currentUser)}, enabled = isDeviceOwner(myDpm)) {
|
||||||
Text("停止用户")
|
Text("停止用户")
|
||||||
}
|
}
|
||||||
if(resultForStop!=-1){
|
if(resultForStop!=-1){
|
||||||
Text(userOperationResultCode(resultForStop))
|
Text(userOperationResultCode(resultForStop))
|
||||||
}
|
}
|
||||||
if(isProfileOwner(myDpm)){
|
Button(onClick = {myDpm.setProfileEnabled(myComponent)}, enabled = isProfileOwner(myDpm)||isDeviceOwner(myDpm)) {
|
||||||
Button(onClick = {myDpm.setProfileEnabled(myComponent)}) {
|
|
||||||
Text(text = "启用资料")
|
Text(text = "启用资料")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
val success = myDpm.removeUser(myComponent,currentUser)
|
val success = myDpm.removeUser(myComponent,currentUser)
|
||||||
@@ -119,6 +128,10 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co
|
|||||||
) {
|
) {
|
||||||
Text("移除用户")
|
Text("移除用户")
|
||||||
}
|
}
|
||||||
|
Button(onClick = { createWorkProfile(myContext,myComponent) }) {
|
||||||
|
Text("创建工作资料")
|
||||||
|
}
|
||||||
|
Text("可能无法创建工作资料")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VERSION.SDK_INT>=24){
|
if(VERSION.SDK_INT>=24){
|
||||||
@@ -250,3 +263,21 @@ fun userOperationResultCode(result:Int): String {
|
|||||||
else->"Unknown"
|
else->"Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createWorkProfile(myContext: Context,myComponent: ComponentName) {
|
||||||
|
val intent = Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE)
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, "com.binbin.androidowner")
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, myComponent)
|
||||||
|
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE, true)
|
||||||
|
}
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"hello")
|
||||||
|
/*
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_CONSENT, false)
|
||||||
|
val adminExtras = PersistableBundle()
|
||||||
|
if (adminExtras.size() > 0) {
|
||||||
|
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtras)
|
||||||
|
}*/
|
||||||
|
intent.setFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
startActivity(myContext,intent,null)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user