Device Administration
概述
DeviceAdmin是Android2.2引入的方案,通过用户授权自己的应用设备管理权限后,可以在代码中修改一些系统设置,主要的功能是围绕锁屏这一块对权限比较“敏感”的区域。Android系统在同一时间可以拥有多个Device Admin程序,并且可以有多个同时处于激活状态。
Device Administration 在Android9.0(Android Pie)被废弃,Google推荐企业管理使用ProfileOwner或DeviceOwner。
DeviceAdminReceiver
要使一个应用成为DeviceAdmin,首先必须要注册一个DeviceAdminReceiver,并且在AndroidManifest中配置这个Receiver。当这个程序被启用/移除为DeviceAdmin时,会收到相应的信息,代码如下:
public class DPMTestReceiver extends DeviceAdminReceiver {
private final static String TAG = "deviceAdmin";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.d(TAG, "DeviceAdmin onReceive");
}
@Override
public void onEnabled(Context context, Intent intent) {
super.onEnabled(context, intent);
Log.d(TAG, "设备管理器已激活");
}
@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
Log.d(TAG, "发起禁用设备管理器的请求");
return super.onDisableRequested(context, intent);
}
@Override
public void onDisabled(Context context, Intent intent) {
super.onDisabled(context, intent);
Log.d(TAG, "设备管理器未激活");
}
@Override
public void onPasswordChanged(Context context, Intent intent) {
super.onPasswordChanged(context, intent);
Log.d(TAG, "密码己经改变");
}
@Override
public void onPasswordExpiring(Context context, Intent intent) {
super.onPasswordExpiring(context, intent);
Log.d(TAG, "密码已过期");
}
@Override
public void onPasswordFailed(Context context, Intent intent) {
super.onPasswordFailed(context, intent);
Log.d(TAG, "密码修改失败");
}
@Override
public void onPasswordSucceeded(Context context, Intent intent) {
super.onPasswordSucceeded(context, intent);
Log.d(TAG, "密码修改成功");
}
}
AndroidManifest.xml中的配置
<receiver
android:name="com.action.deviceadmin.DPMTestReceiver"
// 必须声明权限
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" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
</intent-filter>
</receiver>
device_admin.xml文件内容
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<!-- 密码长度限制 -->
<limit-password />
<!-- 监控屏幕解锁尝试次数 -->
<watch-login />
<!-- 更改锁屏密码 -->
<reset-password />
<!-- 锁屏(可实现一键锁屏功能) -->
<force-lock />
<!-- 清除所有数据 -->>
<wipe-data />
<!-- 设置锁屏密码的有效期 -->
<expire-password />
<!-- 设置存储设备加密 -->
<encrypted-storage />
<!-- 禁用相机 -->
<disable-camera />
</uses-policies>
</device-admin>
DevicePolicyManager
要将应用程序设置为DeviceAdmin,必须使用DevicePolicyManager。
声明一个DevicePolicyManager
// 获取设备管理服务
DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
// 需要激活的DeviceAdminReceiver组件
ComponentName mComponentName = new ComponentName(this, DPMTestReceiver.class);
激活组件
必须先激活该组件,才能得到DeviceAdmin的能力。当组件被激活,会调用DPMTestReceiver中的onEnabled()方法。
// 判断该组件是否已经是DeviceAdmin
if (!mDevicePolicyManager.isAdminActive(mComponentName)) {
Intent intent = new Intent(
DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mComponentName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "提示文字");
startActivityForResult(intent, 1);
} else {
Toast.makeText(DPMDemoMain.this, "设备已经激活,请勿重复激活",
Toast.LENGTH_SHORT).show();
}
使用如上方法,将跳转到系统Settings中,将激活DeviceAdmin的工作转交给Settings处理。第三方应用只能这样设置,必须得到用户的允许才能设置成为DeviceAdmin程序。
激活的组件会在系统data/system/目录下生成device_policies.xml文件,内容如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<policies setup-complete="true">
<admin name="com.action.deviceadmin/com.action.deviceadmin.DPMTestReceiver">
<policies flags="479" />
<strong-auth-unlock-timeout value="0" />
</admin>
<password-validity value="false" />
</policies>
移除激活组件
mDevicePolicyManager.removeActiveAdmin(mComponentName);
移除后,该组件将失去DeviceAdmin的能力,重新激活即可恢复。
设置解锁方式
// PASSWORD_QUALITY_ALPHABETIC
// 用户输入的密码必须要有字母(或者其他字符)。
// PASSWORD_QUALITY_ALPHANUMERIC
// 用户输入的密码必须要有字母和数字。
// PASSWORD_QUALITY_NUMERIC
// 用户输入的密码必须要有数字
// PASSWORD_QUALITY_SOMETHING
// 由设计人员决定的。
// PASSWORD_QUALITY_UNSPECIFIED
// 对密码没有要求。
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
Intent intent = new Intent(
DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
mDevicePolicyManager.setPasswordQuality(mComponentName,
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
startActivity(intent);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
立刻锁屏
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.lockNow();
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
设置多长时间后锁屏
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.setMaximumTimeToLock(mComponentName, time);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
恢复出厂设置
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager
.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
设置密码锁
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.resetPassword(password,
DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
设置禁用所有摄像头
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.setCameraDisabled(mComponentName, disabled);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
设置存储设备加密
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.setStorageEncryption(mComponentName, encrypt);
} else {
Toast.makeText(DPMDemoMain.this, "请先激活设备", Toast.LENGTH_SHORT)
.show();
}
以上是Android官方推荐的将一个应用设置为DeviceAdmin的方法,系统平台可以添加一个接口供第三方调用,实现一键设置DeviceAdmin的功能。
/**
* packageName: 应用包名
* policyReceiver: 实现DeviceAdminReceiver的组件类名
*/
setActiveAdmin(String packageName, String policyReceiver)