设备管理弃用。部分管理政策在被调用时被标记为已弃用 由设备管理员管理如需了解详情并查看迁移选项,请参阅 <ph type="x-smartling-placeholder"></ph> 设备管理服务的弃用。
从 Android 2.2(API 级别 8)开始,Android 平台将提供系统级设备管理功能。 功能。
在本课程中,您将学习如何创建一个安全感知型应用来管理 通过强制执行设备管理政策来移除其内容。具体来说,您可以将应用配置为 这样可确保在显示前设置足够强度的屏幕锁定密码 限制内容提供给用户。
定义并声明您的政策
首先,您需要定义要在功能级别支持的政策类型。政策 包括屏幕锁定密码强度、过期超时、加密等
您必须在
res/xml/device_admin.xml
文件。Android 清单还应引用
声明的政策集。
每个声明的政策都对应于 DevicePolicyManager
中一些相关的设备政策方法(定义最小密码长度和
大写字符是两个示例)。如果应用尝试调用的方法
相应政策未在 XML 中声明,则会导致在运行时出现 SecurityException
。其他权限
(例如 force-lock
),如果应用要管理
其他类型的政策正如您稍后看到的,在设备管理器激活过程中,
系统会在系统屏幕上向用户显示声明的政策的列表。
以下代码段在 res/xml/device_admin.xml
中声明了密码限制政策:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
</uses-policies>
</device-admin>
Android 清单中引用的政策声明 XML:
<receiver android:name=".Policy$PolicyAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
创建设备管理接收器
创建设备管理广播接收器,以便接收与您声明支持的政策相关的事件通知。应用可以有选择地替换回调方法。
在示例应用“Device Admin”中,当设备管理器由 配置的政策将从共享偏好设置中清除。您应当考虑 与应用场景相关的业务逻辑例如,应用可能需要一段时间 删除敏感数据,从而降低安全风险 设备、停用远程同步、提醒管理员等。
为使广播接收器正常工作,请务必在 Android 清单中注册它,如上面的代码段所示。
class PolicyAdmin : DeviceAdminReceiver() {
override fun onDisabled(context: Context, intent: Intent) {
// Called when the app is about to be deactivated as a device administrator.
// Deletes previously stored password policy.
super.onDisabled(context, intent)
context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE).edit().apply {
clear()
apply()
}
}
}
public static class PolicyAdmin extends DeviceAdminReceiver {
@Override
public void onDisabled(Context context, Intent intent) {
// Called when the app is about to be deactivated as a device administrator.
// Deletes previously stored password policy.
super.onDisabled(context, intent);
SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
prefs.edit().clear().commit();
}
}
激活设备管理器
在强制执行任何政策之前,用户都需要手动将应用作为设备激活
管理员。以下代码段说明了如何触发设置 activity,其中
用户即可激活您的应用。最好添加要重点强调的说明文字
通过指定
EXTRA_ADD_EXPLANATION
extra。

图 1. 用户激活屏幕,您可以在其中 提供设备政策的说明。
if (!policy.isAdminActive()) {
val activateDeviceAdminIntent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN,
policy.getPolicyAdmin()
)
// It is good practice to include the optional explanation text to
// explain to user why the application is requesting to be a device
// administrator. The system will display this message on the activation
// screen.
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
resources.getString(R.string.device_admin_activation_message)
)
startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN)
}
if (!policy.isAdminActive()) {
Intent activateDeviceAdminIntent =
new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN,
policy.getPolicyAdmin());
// It is good practice to include the optional explanation text to
// explain to user why the application is requesting to be a device
// administrator. The system will display this message on the activation
// screen.
activateDeviceAdminIntent.putExtra(
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
getResources().getString(R.string.device_admin_activation_message));
startActivityForResult(activateDeviceAdminIntent,
REQ_ACTIVATE_DEVICE_ADMIN);
}
如果用户选择“启用”应用会成为设备管理器,并且可以开始 配置和强制执行政策。
应用还需要做好准备,以应对用户放弃
取消按钮、“返回”键或“主屏幕”键,执行激活流程。因此,
政策设置 activity 中的 onResume()
需要具有逻辑
重新评估条件,并在以下情况下向用户显示“设备管理员激活”选项:
所需的资源。
实现设备政策控制器
成功激活设备管理器后,应用随后会配置设备 包含所请求政策的政策管理中心。请注意,我们即将在 Google Ads 中 每个版本的 Android 系统。如果使用 同时支持旧版本平台。例如,密码下限 大写政策仅适用于 API 级别 11 (Honeycomb) 及更高版本。以下代码 演示了如何在运行时检查版本。
private lateinit var dpm: DevicePolicyManager
private lateinit var policyAdmin: ComponentName
dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
policyAdmin = ComponentName(context, PolicyAdmin::class.java)
dpm.apply {
setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality])
setPasswordMinimumLength(policyAdmin, passwordLength)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase)
}
}
DevicePolicyManager dpm = (DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName policyAdmin = new ComponentName(context, PolicyAdmin.class);
dpm.setPasswordQuality(policyAdmin, PASSWORD_QUALITY_VALUES[passwordQuality]);
dpm.setPasswordMinimumLength(policyAdmin, passwordLength);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
dpm.setPasswordMinimumUpperCase(policyAdmin, passwordMinUpperCase);
}
此时,应用能够强制执行该政策。虽然应用无权访问 与实际使用的屏幕锁定密码不同,它可以通过 Device Policy Manager API 确定 现有密码是否符合必需的政策。如果结果表明 屏幕锁定密码不足以满足要求,设备管理 API 不会自动获取 纠正措施。由应用负责显式启动系统 密码更改屏幕。例如:
if (!dpm.isActivePasswordSufficient) {
// Triggers password change screen in Settings.
Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD).also { intent ->
startActivity(intent)
}
}
if (!dpm.isActivePasswordSufficient()) {
...
// Triggers password change screen in Settings.
Intent intent =
new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivity(intent);
}
通常,用户可以从可用的锁定机制之一中进行选择,例如“无”“模式” PIN 码(数字)或密码(字母数字)。配置密码政策后, 安全系数低于此政策中定义的类型的值会被停用。例如,如果 已配置“数字”密码质量,用户可以选择 PIN 码(数字)或“密码” (字母数字)密码。
通过设置适当的屏幕锁定密码为设备提供适当的保护后,应用 允许访问受保护内容。
when {
!dpm.isAdminActive(policyAdmin) -> {
// Activates device administrator.
...
}
!dpm.isActivePasswordSufficient -> {
// Launches password set-up screen in Settings.
...
}
else -> {
// Grants access to secure content.
...
startActivity(Intent(context, SecureActivity::class.java))
}
}
if (!dpm.isAdminActive(..)) {
// Activates device administrator.
...
} else if (!dpm.isActivePasswordSufficient()) {
// Launches password set-up screen in Settings.
...
} else {
// Grants access to secure content.
...
startActivity(new Intent(context, SecureActivity.class));
}