システム アップデートを管理する

このデベロッパー ガイドでは、Device Policy Controller(DPC)がデバイスのユーザーに代わって Android システム アップデートを管理する方法について説明します。

はじめに

Android デバイスは、システム ソフトウェアとアプリケーション ソフトウェアの無線(OTA)アップデートを受信してインストールできます。Android はデバイスのユーザーにシステム アップデートを通知します があり、デバイスのユーザーはすぐに、または後でアップデートをインストールできます。

IT 管理者は DPC を使用して、デバイス ユーザーのシステム アップデートを管理できます。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 を登録したり、宣伝したりする必要はありません。システムは 1 回のアップデートでこのメソッドを複数回呼び出すため、アップデートのステータスを確認してください。 確認する必要があります詳しくは、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 がある場合(フルマネージドの仕事用プロファイルなど) デバイス所有者とプロファイル所有者の両方がコールバックを受信します。

ポリシーを更新する

デバイス所有者は、ローカル システムを設定してアップデートをインストールするタイミングを制御できる 適用することもできます。システム アップデート ポリシーは、次の 3 つのタイプのいずれかになります。

自動
システム アップデートが利用可能になり次第、(ユーザーの操作なしで)インストールします。このポリシータイプを設定すると、保留中の更新がすぐにインストールされます 延期された、またはメンテナンスの時間枠を待っているケース。
窓(まど)つき
毎日のメンテナンス中にシステム アップデートをインストールする クリックします(ユーザーの操作なし)。毎日のメンテナンスの時間枠の開始と終了を、開始時刻と終了時刻の分数で設定します。 新しいウィンドウでポリシーを作成する際に使用します
延期
システム アップデートのインストールを 30 日間延期します。30 日間が経過すると、デバイスのユーザーにアップデートのインストールを求めるメッセージが表示されます。

延期期間

各アップデートの 30 日間の延期は 1 回に制限されます。生理が始まったとき システムはまず更新を延期します。新しい延期ポリシーを設定すると、 生理期間を延長します。

延期以外にも、接続がない、空き容量が不足している、バッテリー残量が少ないなどの理由で、Android がアップデートをインストールできない場合があります。

この期間中に別のアップデートが利用可能になると、システムによって 30 日間の延期タイマーがリセットされます。これにより、IT 管理者は統合されたシステム アップデートを試すことができます。新しいアップデートがない状態で 30 日が経過すると、 ユーザーに依頼して保留中のアップデートをすべてインストールしてもらいます。その後、新しいシステム アップデートが利用可能になると、新たな 30 日間が再開されます。

ポリシーの設定方法

更新ポリシーは、Android 8.0(API レベル 26)以降で設定できます。指定する デバイスによるシステム アップデートのインストールが必要なタイミングについて、 SystemUpdatePolicy(概説している 3 つのタイプのいずれかを使用) ご覧ください。ポリシーを設定するには、デバイス所有者が 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);

ポリシー インスタンスは作成後に変更できません。デバイスがアップデートをインストールするタイミングを変更するには、新しいポリシーを作成して設定します。新しい Deployment からポリシーを削除するには、 デバイスの場合は、setSystemUpdatePolicy() を呼び出して、policy 引数として null を渡します。 DPC がポリシーを削除すると、利用可能なシステム アップデートに関する通知がデバイスのユーザーに表示されます。

アプリは getSystemUpdatePolicy() を呼び出して、 現在のポリシーに適用されます。このメソッドが null を返す場合、ポリシーは現在設定されていません。

凍結期間

休日や繁忙期などの重要な期間に OS のバージョンを凍結する デバイスの所有者はシステム アップデートを最大 90 日間停止できます。デバイスがフリーズ期間中は、次のように動作します。

  • 保留中のシステム アップデートに関する通知がデバイスに届かない。
  • OS のシステム アップデートがインストールされていない。
  • デバイスのユーザーは、[設定] でシステム アップデートを手動で確認できません。

システムでは、端末が無期限に凍結されるのを防ぐために、定義済みの凍結期間のあとに強制的に 60 日間のバッファをもうけます。システム アップデートを停止すると、デバイスで重要なアップデートを受信できなくなる可能性があります。

<ph type="x-smartling-placeholder">
</ph>
図 1.デバイスに 2 つのフリーズ期間が設定されている
60 日間のバッファを備えた 1 年間に 2 つの凍結期間を示すカレンダー。

更新ポリシーで凍結期間を設定しました。ポリシーを設定せずに凍結期間を設定することはできません。設定した凍結期間中以外は、通常のポリシーの動作(自動、期間内、延期)が適用されます。

凍結期間を設定する方法

フリーズ期間は Android 9(API レベル 28)以降で設定できます。デバイス ポリシーを設定する前に、所有者がシステム アップデート ポリシーの凍結期間を設定している 指定します。手順は次のとおりです。

  1. 新しいシステム アップデート ポリシーを作成する(または現在のシステム アップデート ポリシーを取得します)。
  2. 呼び出してポリシーの凍結期間を設定する setFreezePeriods()
  3. を呼び出してデバイスのポリシーと凍結期間を設定する setSystemUpdatePolicy()

凍結期間は毎年繰り返されるため、期間の開始日と終了日は 月と日の値で表されます。開始日は 前回の凍結期間の終了から少なくとも 60 日後。次の例は、既存のシステム アップデート ポリシーに 2 つのフリーズ期間を設定する方法を示しています。

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 では 60 日間隔のチェックが行われるため、 新しい凍結期間を設定できなくなる可能性があります。 生理のデータを削除し続けることができます。デバイスのフリーズ期間レコードを消去するには、Android Debug Bridge(adb)シェルで次のコマンドを実行します。

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 ツールの使用方法は次のとおりです。

  1. マシンで Android Debug Bridge(adb)が実行されている場合は、 adb サービスに干渉しないように、事前に adb サービスを ロールバックできます。adb を停止するには、adb kill-server を実行します。
  2. GPSUR ツールを開きます
  3. [Allow ADB access] をクリックし、ツールが adb 経由でテストデバイスと通信できるようにします。
  4. [Add new device] をクリックします。
  5. リストからデバイスを選択して、[Connect] をクリックします。このリストは 完全なデバイス名を含めます
  6. デバイスの画面で、[このパソコンからの USB デバッグを常に許可する] をオンにし、[OK] をクリックして USB デバッグ接続に同意します。
  7. ブラウザ上で、接続したデバイスを選択します。
  8. デバイスでロールバックが利用可能な場合は、ページのボタンのテキストが [ロールバック不可] から [最近のアップデートをロールバック] に切り替わります。[Rollback Recent Updates] をクリックします。
  9. [ロールバックの確認] モーダルで警告を確認し、[確認] をクリックします。
  10. ロールバックが完了するまで待ちます。完了すると、[Rollback Successful] をクリックすると、 モーダルが表示され、デバイスが再起動します。デバイスの電源を切っても問題ありません。

参考情報

システム アップデートの詳細については、Android オープンソース プロジェクトの OTA アップデートのドキュメントをご覧ください。