配置 COSU 设备
编写:zenlynn 原文:https://developer.android.com/training/enterprise/cosu.html
作为一个 IT 管理员,你可以将 Android 6.0 Marshmallow 以及更高版本的设备配置为企业拥有、功能单一(COSU)的设备。这些 Android 设备用于单一目的,比如数字标牌、票据打印、销售点或者库存管理。要将 Android 设备作为 COSU 设备使用,你需要开发客户可以管理的 Android 应用。
你的客户可以配置 COSU 设备:
- 锁定一个应用在屏幕上,隐藏主页和最近使用的按钮来防止用户离开该应用。
- 允许多个应用出现在屏幕上,比如有目录的图书馆和网络浏览器。
固定应用 vs 锁定任务模式
Android 5.0 Lollipop 系统引进了两种方式来配置单一目的的 Android 设备:
- 通过固定应用,设备用户可以将特定的应用临时固定在屏幕上。
- 通过锁定任务模式,用户无法离开该应用,且主页和最近使用的按钮都被隐藏了。此外,锁定任务模式使得 IT 管理员可以用更可靠的方式来管理 COSU 设备,如下面所讨论的。
这是固定应用和锁定任务模式之间功能比较的图表:
Figure 1. Lollipop 系统的固定应用和 Marshmallow 以及更高版本系统的锁定任务模式之间的比较
在 Lollipop 系统中,你可以固定一个应用来覆盖整个屏幕,但是只有被设备策略控制器(DPC)加入白名单的应用才可以被锁定。
如何使用锁定任务模式
为了使用锁定任务模式以及管理 COSU 设备的接口,设备必须安装设备所有者应用。设备所有者是一种设备策略控制器(DPC),用来管理整个设备。更多关于 DPC 的信息,请查看 EMM 开发人员概述。
如果你创建了一个新的 COSU 应用,我们建议你为 Marshmallow 以及更高版本的系统开发该应用。因为这些系统包括以下 COSU 特性:
- 控制系统更新
- 设置状态和菜单栏可见
- 禁用屏幕锁定以及睡眠功能
- 在锁定任务模式中允许切换应用
- 在安全模式中防止重启
注意:如果你为 Marshmallow 系统的设备开发 COSU 特性,你的应用仍然可以与 Android 早期版本兼容。
Marshmallow 系统附加的 COSU 管理特性使得开发、部署 Android 设备为功能单一的设备更加容易。如果你想要增强服务端应用限制或服务端 profile 策略控制,你需要使用 EMM 或为你应用添加 DPC。当你创建应用的时候请按照以下说明做。
创建 COSU 解决方案
管理 COSU 设备有两个不同的方法:
- 使用第三方企业移动管理(EMM)解决方案:使用 EMM,你需要做的所有就是设置锁定任务模式。更多信息,请跳到下一个部分,第三方 EMM 管理的解决方案。
- 高级设置——创建你自己的 DPC 应用:这部分内容需要更多的工作,是为了高级开发人员而设。选择这个方法,你需要设置好设备才可以对它进行管理、建立接口、建立 DPC 并测试。更多说明,请跳到创建你自己的 DPC 应用。
第三方 EMM 管理的解决方案
在这个部分,你只需要做少量的开发就可以让你的设备在第三方 EMM 下工作。
使用 startLockTask()
如果你需要添加 COSU 功能到已存在的应用中,要确保客户的 EMM 支持 lockTaskMode。
- 在 setLockTaskPackages 中,设备所有者必须包括你的应用的包。
- 设置可以进入锁定任务模式的包
- 要用 EMM 设置
- 你可以调用 isLockTaskPermitted 来确认你的包已经通过 setLockTaskPackages 添加到白名单里了
- 你的活动调用 startLockTask()
- 请求将用户锁定在当前任务
- 防止启动其他应用、设置以及主页按钮
- 为了退出,你的活动必须调用 stopLockTask()
- 只能在之前调用过 startLockTask()) 的活动里调用
- 应用必须在 onResume() 和 onPause() 之间面向用户时调用
从 Marshmallow 系统开始,如果你的应用被 EMM 用 setLockTaskPackages 添加到白名单中,那么在应用被启动后,你的活动可以自动开始锁定任务模式。
设置锁定任务模式属性
lockTaskMode 允许你在 AndroidManifest.xml 文件里定义你的应用的锁定任务模式行为:
- 如果你将 lockTaskMode 设置为
if_whitelisted
,你不需要调用 startLockTask(),应用会自动进入锁定任务模式。
- 系统应用和特许应用也可以将 lockTaskMode 设置为 always。该设定会让你活动里的任务总是启动到锁定任务模式。对待非特许应用与平常一样。
- lockTaskMode 属性的默认值是 normal。当这个属性设置为 normal 时,任务不会启动到 lockTaskMode,除非调用 startLockTask()。想要调用 startLockTask(),仍然需要使用 setLockTaskPackages 将应用加入白名单,否则,用户会看到同意进入固定模式的对话框。
为了让你的活动自动进入 lockTaskMode,要把这个属性值改为 if_whitelisted
。这么做可以让你的应用以这种方式表现:
- 如果你的应用不是 lockTaskMode 的白名单,它会表现得像平常一样。
- 如果你的应用是系统应用或特许应用,且属于白名单,当应用启动的时候,lockTaskMode 会自动开始。
示例 XML 如下:
<activity android:name=".MainActivity" android:lockTaskMode="if_whitelisted">
有了这些选项,你仍然需要创建一个调用 stopLockTask() 的机制,用户才能退出 ockTaskMode。
高级设置——创建你自己的 DPC 应用
为了在 COSU 中管理应用,你需要一个 DPC 作为设备所有者运行,来设置设备的一些策略。
注意:这个设置是高级的,且需对 EMM 开发人员概述所说的 EMM 概念有透彻的认识。更多关于创建 DPC 的信息,请查看提供用户设备。
为了创建可以管理 COSU 设备配置的 DPC 应用,该 DPC 需要:
提供进入设备所有者模式的设备。我们建议你支持提供近场通讯。更多信息,请查看通过 NFC 提供的设备所有者。
使用以下接口:
- 使用 setKeyguardDisabled() 防止设备键盘锁锁定
- 使用 setStatusBarDisabled() 禁用状态栏
- 通过 STAY_ON_WHILE_PLUGGED_IN 让设备通电的时候保持屏幕点亮
- 通过 addUserRestriction() 设置默认用户限制
- 使用 setSystemUpdatePolicy() 设置系统更新策略
- 通过设定你的应用为默认启动应用,来确保重启时它会启动
这个示例展示了如何实现开始锁定任务模式、执行相关的 COSU 设备管理接口的活动:
public class CosuActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdminComponentName = DeviceAdminReceiver.getComponentName(this);
mDevicePolicyManager = (DevicePolicyManager) getSystemService(
Context.DEVICE_POLICY_SERVICE);
mPackageManager = getPackageManager();
setDefaultCosuPolicies(true);
}
@Override
protected void onStart() {
super.onStart();
// start lock task mode if it's not already active
ActivityManager am = (ActivityManager) getSystemService(
Context.ACTIVITY_SERVICE);
// ActivityManager.getLockTaskModeState api is not available in pre-M.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
if (!am.isInLockTaskMode()) {
startLockTask();
}
} else {
if (am.getLockTaskModeState() ==
ActivityManager.LOCK_TASK_MODE_NONE) {
startLockTask();
}
}
}
private void setDefaultCosuPolicies(boolean active) {
// set user restrictions
setUserRestriction(DISALLOW_SAFE_BOOT, active);
setUserRestriction(DISALLOW_FACTORY_RESET, active);
setUserRestriction(DISALLOW_ADD_USER, active);
setUserRestriction(DISALLOW_MOUNT_PHYSICAL_MEDIA, active);
setUserRestriction(DISALLOW_ADJUST_VOLUME, active);
// disable keyguard and status bar
mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, active);
mDevicePolicyManager.setStatusBarDisabled(mAdminComponentName, active);
// enable STAY_ON_WHILE_PLUGGED_IN
enableStayOnWhilePluggedIn(active);
// set System Update policy
if (active){
mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName,
SystemUpdatePolicy.createWindowedInstallPolicy(60,120));
}
else
// set this Activity as a lock task package
mDevicePolicyManager.setLockTaskPackages(mAdminComponentName,
active ? new String[]{getPackageName()} : new String[]{});
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
intentFilter.addCategory(Intent.CATEGORY_HOME);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
if (active) {
// set Cosu activity as home intent receiver so that it is started
// on reboot
mDevicePolicyManager.addPersistentPreferredActivity(
mAdminComponentName, intentFilter, new ComponentName(
getPackageName(), CosuModeActivity.class.getName()))
} else {
mDevicePolicyManager.clearPackagePersistentPreferredActivities(
mAdminComponentName, getPackageName());
}
}
private void setUserRestriction(String restriction, boolean disallow) {
if (disallow) {
mDevicePolicyManager.addUserRestriction(mAdminComponentName,
restriction);
} else {
mDevicePolicyManager.clearUserRestriction(mAdminComponentName,
restriction);
}
}
private void enableStayOnWhilePluggedIn(boolean enabled) {
if (enabled) {
mDevicePolicyManager.setGlobalSetting(
mAdminComponentName,
Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_USB
| BatteryManager.BATTERY_PLUGGED_WIRELESS);
} else {
mDevicePolicyManager.setGlobalSetting(
mAdminComponentName,
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
}
}
// TODO: Implement the rest of the Activity
}
为 COSU 开发测试计划
如果你计划支持第三方 EMM,那么利用 EMM 应用开发一个终端到终端的测试计划。我们同样提供测试资源,让你可以用来创建你自己的测试设备策略客户端(测试 DPC):