Systemupdates verwalten

In diesem Entwicklerhandbuch wird erläutert, wie Ihr Device Policy Controller (DPC) Android-Systemupdates im Namen des Gerätenutzers verwalten kann.

Einführung

Android-Geräte können OTA-Updates (Over The Air) für die System- und Anwendungssoftware empfangen und installieren. Android informiert den Gerätenutzer darüber, dass ein Systemupdate verfügbar ist und er es sofort oder später installieren kann.

Mit Ihrem DPC kann ein IT-Administrator Systemupdates für den Gerätenutzer verwalten. DPCs können Inhaber eines vollständig verwalteten Geräts (Geräteinhaber) oder eines Arbeitsprofils (Profilinhaber) sein. Tabelle 1 zeigt, wie Geräteinhaber Systemupdates verwalten können, während Profilinhaber nur Informationen zu Systemupdates melden können.

Tabelle 1: Für DPCs verfügbare Aufgaben hängen vom Inhabermodus ab.

Aufgabe Geräteeigentümer Profilinhaber
Nach ausstehenden Systemupdates suchen
Rückrufe erhalten, wenn neue Systemupdates verfügbar sind
Lokale Update-Richtlinien festlegen, um zu steuern, wann Android Systemupdates installiert
Betriebssystemversion in kritischen Zeiträumen einfrieren

Nach ausstehenden Updates suchen

Ein ausstehendes Update ist ein Systemupdate für ein Gerät, das noch nicht installiert wurde. Ihr DPC kann IT-Administratoren dabei helfen, zu prüfen, auf welchen Geräten Systemupdates ausstehen, und Gerätenutzer auffordern, wichtige Updates sofort zu installieren.

Geräteinhaber und Profilinhaber mit Android 8.0 (API-Level 26) oder höher können prüfen, ob ein Systemupdate für ein Gerät aussteht. Rufen Sie DevicePolicyManager.getPendingSystemUpdate() auf. Wenn das Gerät auf dem neuesten Stand ist, wird null zurückgegeben. Wenn ein Systemupdate aussteht, gibt die Methode Informationen über das Update zurück.

Weitere Informationen zu ausstehenden Updates

Nachdem Sie getPendingSystemUpdate() aufgerufen haben, können Sie den zurückgegebenen SystemUpdateInfo-Wert überprüfen, um mehr über das ausstehende Update zu erfahren. Das folgende Beispiel zeigt, wie du herausfinden kannst, wann ein ausstehendes Update zum ersten Mal für das Gerät verfügbar war:

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));
}

System-Callbacks

Wenn ein Update verfügbar ist, benachrichtigt das Android-System die Geräteeigentümer über das neue Update. Unter Android 8.0 und höher werden auch die Profilinhaber benachrichtigt.

Überschreiben Sie in der Unterklasse DeviceAdminReceiver den onSystemUpdatePending()-Callback. Sie müssen sich nicht für Ihren DPC registrieren oder bewerben, um den Callback zu erhalten. Das System ruft diese Methode bei einem einzelnen Update möglicherweise mehrmals auf. Prüfen Sie daher den Status des Updates, bevor Sie antworten. Rufen Sie getPendingSystemUpdate() auf, um mehr über das Systemupdate im Callback zu erfahren. Das folgende Beispiel zeigt, wie Sie das tun können:

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.
    // ...
  }
}

Wenn ein System mehr als einen DPC hat, z. B. Arbeitsprofile auf vollständig verwalteten Geräten, erhalten sowohl der Geräteinhaber als auch der Profilinhaber den Callback.

Richtlinien aktualisieren

Ein Geräteeigentümer kann steuern, wann Updates installiert werden, indem er eine lokale Richtlinie für Systemupdates für ein Gerät festlegt. Es gibt drei Arten von Richtlinien für Systemupdates:

Automatisch
Installiert Systemupdates, sobald sie verfügbar sind (ohne Nutzerinteraktion). Wenn Sie diesen Richtlinientyp festlegen, werden alle ausstehenden Updates sofort installiert, die verschoben wurden oder auf ein Wartungsfenster warten.
Mit Fenster
Installiert Systemupdates während eines täglichen Wartungsfensters (ohne Nutzerinteraktion). Legen Sie beim Erstellen einer neuen Windowing-Richtlinie den Beginn und das Ende des täglichen Wartungsfensters in Minuten des Tages fest.
Verschoben
Die Installation von Systemupdates wird um 30 Tage verschoben. Nach Ablauf der 30 Tage wird der Gerätenutzer vom System aufgefordert, das Update zu installieren.

Verschiebungszeiträume

Jedes Update wird nur um 30 Tage verschoben. Der Zeitraum beginnt, wenn das System die Aktualisierung zum ersten Mal verschiebt und durch das Festlegen neuer Richtlinien für diese Verschiebung nicht verlängert wird.

Neben der Verschiebung kann Android möglicherweise ein Update auch aus anderen Gründen nicht installieren, z. B. aus fehlenden Verbindungen, unzureichendem Speicherplatz oder niedrigem Akkustand.

Das System setzt den Timer für die 30-tägige Verschiebung zurück, wenn innerhalb dieses Zeitraums ein anderes Update verfügbar wird. So haben IT-Administratoren die Möglichkeit, die kombinierten Systemupdates auszuprobieren. Sobald 30 Tage ohne ein neues Update vergangen sind, fordert das System den Nutzer auf, alle ausstehenden Updates zu installieren. Wenn später ein neues Systemupdate verfügbar wird, beginnt der 30-Tage-Zeitraum von vorn.

Richtlinie festlegen

Sie können Updaterichtlinien in Android 8.0 (API-Level 26) oder höher festlegen. Wenn Sie angeben möchten, wann auf dem Gerät Systemupdates installiert werden sollen, erstellen Sie eine Instanz von SystemUpdatePolicy. Verwenden Sie dazu einen der drei oben beschriebenen Typen. Zum Festlegen einer Richtlinie ruft der Eigentümer des Geräts die Methode DevicePolicyManager setSystemUpdatePolicy() auf. Das folgende Codebeispiel zeigt, wie Sie dies tun können. Ein Beispiel für eine Windowing-Richtlinie finden Sie in der Dokumentation zu 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);

Richtlinieninstanzen können nach dem Erstellen nicht mehr geändert werden. Wenn Sie ändern möchten, wann Updates auf einem Gerät installiert werden, können Sie eine neue Richtlinie erstellen und festlegen. Wenn Sie eine Richtlinie von einem Gerät entfernen möchten, rufen Sie setSystemUpdatePolicy() auf und übergeben Sie null als policy-Argument. Nachdem der DPC eine Richtlinie entfernt hat, erhält der Gerätenutzer Benachrichtigungen über alle verfügbaren Systemupdates.

Apps können getSystemUpdatePolicy() aufrufen, um die aktuelle Richtlinie für das Gerät abzurufen. Wenn diese Methode null zurückgibt, ist derzeit keine Richtlinie festgelegt.

Wartezeiten

Damit die Betriebssystemversion in kritischen Zeiträumen wie Feiertagen oder anderen Zeiten mit vielen Zugriffen eingefroren wird, können Geräteeigentümer Systemupdates bis zu 90 Tage lang aussetzen. Wenn sich ein Gerät in einer Sperrzeit befindet, verhält es sich so:

  • Das Gerät erhält keine Benachrichtigungen über ausstehende Systemupdates.
  • Systemupdates für das Betriebssystem sind nicht installiert.
  • Gerätenutzer können nicht manuell in den Einstellungen nach Systemupdates suchen.

Das System erzwingt einen obligatorischen Puffer von 60 Tagen nach festgelegten Sperrzeiträumen, um zu verhindern, dass das Gerät auf unbestimmte Zeit einfriert. Denken Sie daran, dass eingefrorene Systemupdates dazu führen können, dass Geräte keine wichtigen Updates erhalten.

Abbildung 1: Zwei Sperrzeiträume für ein Gerät festgelegt
Kalender, der zwei Zeiträume mit Puffern von 60 Tagen in einem Jahr zeigt.

Sie legen Sperrzeiträume für eine Updaterichtlinie fest. Sperrzeiträume können nur festgelegt werden, wenn eine Richtlinie festgelegt ist. Wenn das Gerät außerhalb der festgelegten Sperrzeiträume liegt, gilt das normale Richtlinienverhalten („automatisch“, „im Fenstermodus“ oder „verschoben“).

So legen Sie eine Sperrzeit fest

Unter Android 9 (API-Level 28) und höher können Sie Zeiträume für die Sperrzeit festlegen. Ein Geräteeigentümer legt eine Sperrzeit für eine Richtlinie für Systemupdates fest, bevor er die Richtlinie für das Gerät festlegt. Die Schritte:

  1. Erstellen Sie eine neue Richtlinie oder rufen Sie die aktuelle Richtlinie für Systemupdates ab.
  2. Legen Sie die Sperrzeiträume für die Richtlinie durch Aufrufen von setFreezePeriods() fest.
  3. Legen Sie die Richtlinien und Sperrzeiträume für das Gerät fest, indem Sie setSystemUpdatePolicy() aufrufen.

Da sich die Sperrzeit jährlich wiederholt, werden Start- und Enddatum des Zeitraums durch Monats- und Tageswerte dargestellt. Der Starttag muss mindestens 60 Tage nach dem Ende des vorherigen Sperrzeitraums beginnen. Das folgende Beispiel zeigt, wie Sie zwei Sperrzeiträume für eine vorhandene Richtlinie für Systemupdates festlegen können:

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 ...
}

Sowohl der Start- als auch der Endtag werden einbezogen. Wenn der Starttag nach dem Endtag liegt (wie z. B. winterSale im vorherigen Beispiel), erstreckt sich der Sperrzeitraum auf das Folgejahr.

Beim Festlegen von Sperrzeiten für eine Richtlinie für Systemupdates testet Android die folgenden Anforderungen:

  • Die Sperrzeit beträgt nicht länger als 90 Tage.
  • Der Abstand zwischen den Sperrzeiträumen beträgt mindestens 60 Tage.
  • Die Zeiträume überschneiden sich nicht.
  • Es gibt keine doppelten Sperrzeiträume.

Wenn die Richtlinie für Systemupdates für ein Gerät festgelegt wird, wiederholt Android diese Tests und schließt aktuelle oder vergangene Sperrzeiten für das Gerät ein.

Android gibt ein SystemUpdatePolicy.ValidationFailedException aus, wenn einer dieser Tests fehlschlägt.

Alle installierten Apps können SystemUpdatePolicy.getFreezePeriods() aufrufen, um eine Liste der Sperrzeiträume abzurufen, die zuvor für ein Richtlinienobjekt für Systemupdates festgelegt wurden. Im folgenden Beispiel wird diese Methode aufgerufen, um die Sperrzeiträume eines Geräts zu protokollieren:

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());
  }
}

Schaltjahre

Android verwendet den Kalender nach ISO 8601 (auch als gregorianischer Kalender bezeichnet), um die Fixierungszeiträume zu berechnen, und ignoriert Schaltjahre. Das bedeutet, dass der 29. Februar nicht als gültiges Datum erkannt und so behandelt wird, als wäre es der 28. Februar. Daher wird der 29. Februar bei der Berechnung der Dauer einer Sperrzeit nicht berücksichtigt.

Entwicklung und Tests

Während Sie die Systemupdate-Funktion Ihres DPC entwickeln und testen, müssen Sie möglicherweise viele Sperrzeiträume einplanen. Da Android ein 60-tägiges Intervall zwischen vergangenen Sperrzeiträumen prüft, können Sie möglicherweise keinen neuen Sperrzeitraum festlegen, ohne zuerst den Datensatz für frühere Zeiträume zu löschen. Führen Sie den folgenden Befehl in der ADB-Shell (Android Debug Bridge) aus, um den Eintrag für den Sperrzeitraum des Geräts zu löschen:

adb shell dpm clear-freeze-period-record

Um zu überprüfen, ob ein Gerät in der Sperrzeit ist, überprüfen Sie, ob die Benutzeroberfläche für Systemupdates deaktiviert ist.

Weitere Informationen

Weitere Informationen zu Systemupdates finden Sie in der Dokumentation zu OTA-Updates des Android Open Source-Projekts.