管理系统更新

本开发者指南介绍了设备政策控制器 (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 天的缓冲期 以防止无限期冻结设备。记住,系统死机 更新可能会导致设备无法接收重要更新。

<ph type="x-smartling-placeholder">
</ph>
图 1.为设备设置两个冻结期
显示一年中两次冻结期的日历,具有 60 天缓冲期。

您可以为更新政策设置冻结期。您无法设置冻结时段, 设置政策当设备处于您设置的冻结期之外时, 应用正常的政策行为(自动、窗口化或推迟)。

如何设置冻结期

您可以在 Android 9(API 级别 28)或更高版本中设置冻结期。设备 所有者在设置系统更新政策之前设置冻结期 。步骤如下:

  1. 创建新的(或获取当前的)系统更新政策。
  2. 通过调用 setFreezePeriods()
  3. 通过调用为设备设置政策和冻结时段 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 系统更新

其他资源

要详细了解系统更新,请参阅 Android 开源项目的 OTA 更新文档。