本开发者指南介绍了设备政策控制器 (DPC) 可以如何 代表设备用户管理 Android 系统更新。
简介
Android 设备可以接收和安装系统的无线下载 (OTA) 更新 和应用程序软件Android 会通知设备用户系统更新 可用,且设备用户可以立即安装更新,也可以稍后安装。
IT 管理员可以使用您的 DPC 为设备用户管理系统更新。设备政策控制器 (DPC) 可以拥有全托管式设备(称为设备所有者),也可以拥有工作资料 (称为商家资料所有者)。表 1 显示了设备所有者如何管理系统 更新,而个人资料所有者只能报告系统更新的相关信息。
表 1:可供 DPC 执行的任务取决于所有者模式
任务 | 设备所有者 | 个人资料所有者 |
---|---|---|
检查是否有待处理的系统更新 | ||
有新的系统更新可用时收到回调 | ||
设置本地更新政策以控制 Android 何时安装系统更新 | ||
在关键时间段内冻结操作系统版本 |
检查是否有待处理的更新
待处理的更新是指尚未安装的设备的系统更新。 设备政策控制器 (DPC) 可帮助 IT 管理员检查哪些设备有待处理的系统更新,以及 要求设备用户立即安装重要更新。
在 Android 8.0(API 级别 26)或更高版本上运行的设备所有者和资料所有者
可以检查设备是否有待处理的系统更新。致电
DevicePolicyManager.getPendingSystemUpdate()
如果设备是最新版本,则返回 null
。如果系统更新在等待处理,
该方法会返回有关更新的信息。
详细了解待处理的更新
调用 getPendingSystemUpdate()
后,您可以检查返回的
SystemUpdateInfo
值,以详细了解待处理的更新。通过
以下示例展示了如何找出待处理的更新
可用:
Kotlin
val firstAvailable = dpm.getPendingSystemUpdate(adminName)?.receivedTime firstAvailable?.let { Log.i(TAG, "Update first available: ${Date(firstAvailable)}") }
Java
SystemUpdateInfo updateInfo = dpm.getPendingSystemUpdate(adminName); if (updateInfo != null) { Long firstAvailable = updateInfo.getReceivedTime(); Log.i(TAG, "Update first available: " + new Date(firstAvailable)); }
系统回调
有可用更新时,Android 系统会通知设备所有者 更新。在 Android 8.0 或更高版本中,系统还会通知个人资料所有者。
在 DeviceAdminReceiver
子类中,替换
onSystemUpdatePending()
回调。您不需要
来注册或通告您的 DPC,以接收回调。系统可能会
针对单个更新多次调用此方法,因此请检查更新的状态
然后再回复。致电 getPendingSystemUpdate()
,详细了解
系统更新以下示例展示如何执行此操作:
Kotlin
/** * Called when a new update is available. */ override fun onSystemUpdatePending(context: Context?, intent: Intent?, receivedTime: Long) { // System update information is supported in API level 26 or higher. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { return } val updateInfo = getManager(context) .getPendingSystemUpdate(getWho(context)) ?: return if (updateInfo.securityPatchState == SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE) { // Perhaps install because this is a security patch. // ... } }
Java
/** * Called when a new update is available. */ public void onSystemUpdatePending (Context context, Intent intent, long receivedTime) { // System update information is supported in API level 26 or higher. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { return; } SystemUpdateInfo updateInfo = getManager(context) .getPendingSystemUpdate(getWho(context)); if (updateInfo == null) { return; } if (updateInfo.getSecurityPatchState() == SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE) { // Perhaps install because this is a security patch. // ... } }
系统具有多个设备政策控制器 (DPC) 时(例如完全受管的工作资料) 设备,那么设备所有者和资料所有者都会收到回调。
更新政策
设备所有者可以通过设置本地系统来控制何时安装更新 更新政策。系统更新政策可以是以下三种类型之一:
- 自动
- 有系统更新后立即安装 (无需用户互动)。设置此政策类型后,系统会立即安装所有待处理的更新 可能会推迟或等待维护期。
- 带窗
- 在日常维护期间安装系统更新 窗口(无需用户互动)。创建新的基于时间段的政策时,将每日维护窗口的开始时间和结束时间设置为分钟数。
- 已延期
- 将系统更新安装推迟 30 天。30 天后 周期结束时,系统会提示设备用户安装更新。
推迟期
系统会限制每次更新只能推迟 30 天。该周期从以下时间开始算起 系统会首先推迟更新,而设置新的推迟政策 延长时间。
除了推迟之外,Android 可能还会因其他原因(例如无连接、磁盘空间不足或电池电量不足)而无法安装更新。
如果发生其他更新,系统会重置 30 天的推迟计时器 - 让 IT 管理员有机会试用合并的系统 更新。30 天过后,如果没有任何新的更新,系统就会提示 用户安装所有待安装的更新。之后,当出现新的系统更新时 30 天期限将重新开始。
如何设置政策
您可以在 Android 8.0(API 级别 26)或更高版本中设置更新政策。要指定
当设备应安装系统更新时,创建一个
SystemUpdatePolicy
,并使用列出的三种类型之一
。如需设置政策,您的设备所有者会调用 DevicePolicyManager
方法
setSystemUpdatePolicy()
。以下代码示例展示了如何执行此操作。要查看窗口化政策的示例,请查看
SystemUpdatePolicy
文档。
Kotlin
// Create the system update policy to postpone installation for 30 days. val policy = SystemUpdatePolicy.createPostponeInstallPolicy() // Get a DevicePolicyManager instance to set the policy on the device. val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val adminName = getComponentName(context) // Set the policy. dpm.setSystemUpdatePolicy(adminName, policy)
Java
// Create the system update policy to postpone installation for 30 days. SystemUpdatePolicy policy = SystemUpdatePolicy.createPostponeInstallPolicy(); // Get a DevicePolicyManager instance to set the policy on the device. DevicePolicyManager dpm = (DevicePolicyManager) context .getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminName = getComponentName(context); // Set the policy. dpm.setSystemUpdatePolicy(adminName, policy);
政策实例一经创建便无法更改。要更改设备
安装更新,您可以创建和设置新政策。如需从设备中移除政策,请调用 setSystemUpdatePolicy()
,并将 null
作为 policy
参数传递。DPC 移除政策后,设备用户会看到任何
可用的系统更新
应用可以调用 getSystemUpdatePolicy()
来获取
设备的当前政策。如果此方法返回 null
,则表示
政策。
冻结期
在重要时段(例如节假日或其他繁忙时段)冻结操作系统版本 次,设备所有者最长可以暂停系统更新 90 天。当 设备处于冻结期内,其行为如下:
- 设备不会收到任何有关待处理系统更新的通知。
- 未安装操作系统的系统更新。
- 设备用户无法在“设置”中手动检查系统更新。
在出现任何定义的冻结之后,系统会强制执行 60 天的缓冲期 以防止无限期冻结设备。记住,系统死机 更新可能会导致设备无法接收重要更新。
您可以为更新政策设置冻结期。您无法设置冻结时段, 设置政策当设备处于您设置的冻结期之外时, 应用正常的政策行为(自动、窗口化或推迟)。
如何设置冻结期
您可以在 Android 9(API 级别 28)或更高版本中设置冻结期。设备 所有者在设置系统更新政策之前设置冻结期 。步骤如下:
- 创建新的(或获取当前的)系统更新政策。
- 调用
setFreezePeriods()
来设置政策的冻结期。 - 通过调用为设备设置政策和冻结时段
setSystemUpdatePolicy()
。
由于冻结期每年都会重复,因此冻结期的开始日期和结束日期 都用月值和日值表示开始日期必须于 至少 60 天。以下示例 展示了如何为现有系统更新政策设置两个冻结期:
Kotlin
// Get the existing policy from the DevicePolicyController instance. val policy = dpm.systemUpdatePolicy ?: return try { // Set the two annual freeze periods on the policy for our retail // point-of-sale devices. val summerSale = FreezePeriod( MonthDay.of(6, 1), MonthDay.of(7, 31)) // Jun 1 - Jul 31 inclusive val winterSale = FreezePeriod( MonthDay.of(11, 20), MonthDay.of(1, 12)) // Nov 20 - Jan 12 inclusive policy.freezePeriods = Arrays.asList(summerSale, winterSale) // Set the policy again to activate the freeze periods. dpm.setSystemUpdatePolicy(adminName, policy) } catch (e: SystemUpdatePolicy.ValidationFailedException) { // There must be previous periods recorded on the device because // summerSale and winterSale don’t overlap and are separated by more // than 60 days. Report the overlap ... }
Java
// Get the existing policy from the DevicePolicyController instance. SystemUpdatePolicy policy = dpm.getSystemUpdatePolicy(); try { // Set the two annual freeze periods on the policy for our // retail point-of-sale devices. FreezePeriod summerSale = new FreezePeriod( MonthDay.of(6, 1), MonthDay.of(7, 31)); // Jun 1 - Jul 31 inclusive FreezePeriod winterSale = new FreezePeriod( MonthDay.of(11, 20), MonthDay.of(1, 12)); // Nov 20 - Jan 12 inclusive policy.setFreezePeriods(Arrays.asList(summerSale, winterSale)); // Don’t forget to set the policy again to activate the freeze periods. dpm.setSystemUpdatePolicy(adminName, policy); } catch (SystemUpdatePolicy.ValidationFailedException e) { // There must be previous periods recorded on the device because summerSale // and winterSale don’t overlap and are separated by more than 60 days. // Report the overlap ... }
开始日期和结束日期都包含在内。如果开始日期晚于
比结束日期(例如,上例中的 winterSale
)多,则冻结
延长至下一年。
设置冻结时 系统更新政策的期限内,Android 会测试以下要求:
- 冻结期不会超过 90 天。
- 冻结期之间的间隔至少为 60 天。
- 冻结期不会重叠。
- 没有重复的冻结期。
为设备设置系统更新政策时,Android 会重复这些测试 包括设备当前或过去的任何冻结期。
当发生以下情况时,Android 会抛出 SystemUpdatePolicy.ValidationFailedException
:
任何一项测试失败
要获取之前在系统更新政策对象上设置的冻结期列表,
所有已安装的应用都可以调用
SystemUpdatePolicy.getFreezePeriods()
。以下
示例会调用此方法来记录设备的冻结期:
Kotlin
// Log any freeze periods that might be set on a system update policy. dpm.systemUpdatePolicy?.freezePeriods?.forEach { Log.i(TAG, "Freeze period: $it") }
Java
// Log any freeze periods that might be set on a system update policy. SystemUpdatePolicy currentPolicy = dpm.getSystemUpdatePolicy(); if (currentPolicy != null) { // A policy might not be set. for (FreezePeriod freezePeriod : currentPolicy.getFreezePeriods()) { Log.i(TAG, "Freeze period: " + freezePeriod.toString()); } }
闰年
Android 使用 ISO 8601 日历(也称为公历)来 计算冻结期,并且忽略闰年。也就是说 被识别为有效日期,会被视为 2 月 28 日。 因此在计算冻结时长时,系统不会将 2 月 29 日的数据统计在内 。
开发和测试
在开发和测试 DPC 的系统更新功能时,您可能 就需要创建多个冻结期因为 Android 会以 60 天为时间间隔进行检查 ,那么您可能无法设置新的冻结期 而不会先清除过去经期的记录。清除设备冻结状态 记录期间,请在 Android 调试桥中运行以下命令 (adb) shell:
adb shell dpm clear-freeze-period-record
您可以通过检查用户是否 系统更新界面已停用。
Google Play 系统更新 (Mainline)
Google Play 系统更新(也称为 Mainline 更新)是指 自动下载,但需要重新启动设备才能安装。这些 更新不会触发自动重新启动,而是会安装在 下次用户、管理员或政策启动的重新启动时。由系统更新政策触发的重启会安装关联的 Google/OEM 系统更新以及之前下载的所有 Google Play 系统更新。
Google Play 系统更新也可以手动安装,方法是转到 设置 >关于 >Android 版本 >Google Play 系统更新。
回滚更新
在某些情况下,Google Play 系统更新回滚 (GPSUR) 工具可以 用于恢复设备状态(由于 Google Play 系统更新出现问题) 安装。只有高级用户或在支持人员指示的情况下才能使用此工具,因为它可能会导致数据丢失。使用 GPSUR 的 工具:
- 如果您在计算机上运行 Android 调试桥 (adb),请先停止 adb 服务,然后再继续操作,以免该服务干扰回滚过程。如需停止 adb,请运行
adb kill-server
。 - 打开 GPSUR 工具。
- 点击允许 ADB 访问,以允许该工具通过 adb 与您的测试设备通信。
- 点击添加新设备。
- 从列表中选择您的设备,然后点击连接。此列表可能未 包含完整的设备名称。
- 在设备屏幕上,选择一律允许使用这台计算机进行调试,然后点击 确定接受 USB 调试连接。
- 在浏览器中选择已连接的设备。
- 如果您的设备上有可用的回滚,页面上的按钮文本应从无可用的回滚切换为回滚近期更新。点击回滚最近更新。
- 阅读确认回滚模态窗口中的警告,然后点击确认。
- 等待回滚完成。完成后,系统会显示回滚成功 模态窗口,设备将重新启动。现在可以安全地拔下 设备。
其他资源
要详细了解系统更新,请参阅 Android 开源项目的 OTA 更新文档。