管理系統更新

本開發人員指南將說明裝置政策控制器 (DPC) 如何 代表裝置使用者管理 Android 系統更新。

簡介

Android 裝置可以接收並安裝系統無線更新 (OTA) 和應用程式軟體Android 會通知裝置使用者有可用的系統更新,裝置使用者可以立即或稍後安裝更新。

透過您的 DPC,IT 管理員可以管理裝置使用者的系統更新。DPC 可以擁有全代管裝置 (稱為裝置擁有者),也可以擁有工作資料夾 (稱為設定檔擁有者)。表 1 說明裝置擁有者如何管理系統 更新,但個人資料擁有者只能回報系統更新相關資訊。

表 1:DPC 可執行的工作取決於擁有者模式

工作 裝置擁有者 設定檔擁有者
檢查是否有待處理的系統更新
有可用的新系統更新時接收回呼
設定本機更新政策,控制 Android 安裝系統更新的時間
凍結重要期間的 OS 版本

檢查待更新

待更新是指尚未安裝的裝置系統更新。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 天緩衝期 ,以避免裝置無限期凍結。記住,系統凍結 更新可能會使裝置無法接收重大更新。

圖 1.為裝置設定兩個凍結期間
Google 日曆顯示一年內的兩個凍結期間,並提供 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 月 29 日 無法識別為有效日期,並視為 2 月 28 日。 因此,2 月 29 日的凍結期間不會列入計算 。

開發和測試

開發及測試 DPC 的系統更新功能時,您可能需要建立許多凍結期間。由於 Android 會檢查 因此你可能無法設定新的凍結期間 而不需要先清除過去的經期記錄。如何清除裝置的凍結狀態 請在 Android Debug Bridge 中執行下列指令 (ADB) 殼層:

adb shell dpm clear-freeze-period-record

如要確認裝置是否處於凍結期間,請查看使用者 系統更新的介面已停用。

Google Play 系統更新 (Mainline)

Google Play 系統更新 (也稱為 Mainline 更新) 是 自動下載,但需要重新啟動裝置才能安裝。這類更新不會讓裝置自動重新啟動,而且會等待使用者、管理員或政策下次重新啟動裝置時再安裝。由系統觸發的重新啟動 更新政策會安裝相關聯的 Google/原始設備製造商 (OEM) 系統更新 下載先前下載的 Google Play 系統更新

您也可以前往 設定 >關於 >Android 版本 >Google Play 系統更新

復原更新

在某些情況下,Google Play 系統更新復原 (GPSUR) 工具可以 用來復原 Google Play 系統更新造成的裝置狀態 安裝。這項工具適合進階使用者或指示 所以可能會遺失資料GPSUR 的使用方法如下 工具:

  1. 如果機器上執行 Android Debug Bridge (adb),請先停止 adb 服務再繼續操作,以免干擾回復程序。如要停止 ADB,請執行 adb kill-server
  2. 開啟 GPSUR 工具
  3. 按一下「允許 ADB 存取」,允許工具與測試通訊 透過 ADB 監控裝置
  4. 按一下「新增裝置」
  5. 從清單中選取您的裝置,然後按一下「連線」。這份清單不一定 包含完整裝置名稱。
  6. 在裝置的螢幕上選取「一律允許透過這台電腦進行」,然後按一下 確定接受 USB 偵錯連線。
  7. 在瀏覽器中選取已連結的裝置。
  8. 頁面上的按鈕文字應從「No Rollbacks available」切換成「No Rollbacks available」 如果裝置有復原版本,可以復原近期更新。 按一下「還原最近的更新」
  9. 閱讀「確認回溯」對話方塊中的警告,然後按一下「確認」
  10. 等待復原作業完成。完成後,就復原成功 互動視窗出現,裝置將重新啟動。現在可以放心拔除裝置了。

其他資源

如要進一步瞭解系統更新,請參閱 Android 開放原始碼專案的「OTA 更新」說明文件。