本开发者指南介绍了设备政策控制器 (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 更新文档。