Zarządzanie aktualizacjami systemu

W tym przewodniku dla programistów wyjaśniamy, jak kontroler zasad dotyczących urządzeń (DPC) może zarządzać aktualizacjami systemu Android w imieniu użytkownika urządzenia.

Wprowadzenie

Urządzenia z Androidem mogą odbierać i instalować bezprzewodowe aktualizacje systemu oraz aplikacji. Android powiadamia użytkownika urządzenia o dostępnej aktualizacji systemu, a użytkownik może ją zainstalować od razu lub później.

Za pomocą DPC administrator może zarządzać aktualizacjami systemu dla użytkownika urządzenia. DPC może być właścicielem w pełni zarządzanego urządzenia (nazywanego właścicielem urządzenia) lub właścicielem profilu służbowego. Tabela 1 przedstawia, jak właściciele urządzeń mogą zarządzać aktualizacjami systemu, a właściciele profili mogą przesyłać tylko informacje o aktualizacjach systemu.

Tabela 1. Zadania dostępne dla DPC zależą od trybu właściciela

Zadanie Właściciel urządzenia Właściciel profilu
Sprawdzanie oczekujących aktualizacji systemu
Odbieraj wywołania zwrotne, gdy dostępne będą nowe aktualizacje systemu
Ustawianie lokalnych zasad aktualizacji, aby kontrolować, kiedy Android instaluje aktualizacje systemu
Blokowanie wersji systemu operacyjnego w krytycznych okresach

Sprawdź, czy nie ma oczekujących aktualizacji

Oczekująca aktualizacja to aktualizacja systemu urządzenia, które nie zostało jeszcze zainstalowane. DPC może pomóc administratorom IT sprawdzić, które urządzenia mają oczekujące aktualizacje systemu, a także poprosić ich o niezwłoczne zainstalowanie krytycznych aktualizacji.

Właściciele urządzeń i właściciele profili z Androidem 8.0 (poziom interfejsu API 26) lub nowszym mogą sprawdzić, czy urządzenie oczekuje na aktualizację systemu. Wywołaj metodę DevicePolicyManager.getPendingSystemUpdate(), która zwraca wartość null, jeśli urządzenie jest aktualne. Jeśli oczekuje na aktualizację systemu, metoda zwraca informacje o niej.

Więcej informacji o oczekującej aktualizacji

Po wywołaniu metody getPendingSystemUpdate() możesz sprawdzić zwróconą wartość SystemUpdateInfo, aby dowiedzieć się więcej o oczekującej aktualizacji. Z tego przykładu dowiesz się, jak możesz dowiedzieć się, kiedy na urządzeniu pojawiła się po raz pierwszy oczekująca aktualizacja:

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

Wywołania zwrotne systemowe

Po udostępnieniu aktualizacji system Android powiadamia o niej właścicieli urządzeń. W Androidzie 8.0 i nowszych system powiadamia również właścicieli profili.

W podklasie DeviceAdminReceiver zastąp wywołanie zwrotne onSystemUpdatePending(). Nie musisz rejestrować się ani reklamować swojego DPC, aby otrzymać oddzwonienie. W przypadku jednej aktualizacji system może wywoływać tę metodę więcej niż raz, dlatego zanim odpowiesz, sprawdź stan aktualizacji. Zadzwoń pod numer getPendingSystemUpdate(), aby uzyskać w wywołaniu zwrotnym więcej informacji o aktualizacji systemu. Poniższy przykład pokazuje, jak to zrobić:

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

Gdy system ma więcej niż 1 DPC, np. profile służbowe na w pełni zarządzanych urządzeniach, właściciel urządzenia i właściciel profilu otrzymają wywołanie zwrotne.

Zaktualizuj zasady

Właściciel urządzenia może określić, kiedy aktualizacje mają być instalowane, ustawiając na nim lokalną zasadę aktualizacji systemu. Możliwe są 3 typy zasad dotyczących aktualizacji systemu:

Automatyczny
Instaluje aktualizacje systemu, gdy tylko stają się dostępne (bez interakcji ze strony użytkownika). Jeśli zasada jest skonfigurowana, natychmiast instaluje wszystkie oczekujące aktualizacje, które mogą zostać przełożone lub czekają na okres konserwacji.
Z oknami
Instaluje aktualizacje systemu podczas codziennego okresu konserwacji (bez interakcji ze strony użytkownika). Podczas tworzenia nowej zasady okresowej ustaw początek i koniec codziennego okresu konserwacji jako minuty dnia.
Przełożone
Przełóż instalację aktualizacji systemu o 30 dni. Po upływie 30 dni system prosi użytkownika o zainstalowanie aktualizacji.

Okresy opóźnienia

System ogranicza każdą aktualizację do jednego 30-dniowego okresu. Ten okres rozpoczyna się w momencie, gdy system po raz pierwszy przełoży aktualizację, a ustanowienie nowych zasad odroczenia jej nie wydłuży.

Android może nie być w stanie zainstalować aktualizacji z innych powodów, takich jak brak połączenia, niewystarczająca ilość miejsca na dysku lub słaba bateria.

Jeśli w tym czasie dostępna będzie inna aktualizacja, system resetuje 30-dniowy czas odsunięcia, dzięki czemu administratorzy IT mogą wypróbować połączone aktualizacje systemu. Po upływie 30 dni bez aktualizacji system poprosi użytkownika o zainstalowanie wszystkich oczekujących aktualizacji. Później, gdy pojawi się nowa aktualizacja systemu, 30-dniowy okres rozpocznie się od nowa.

Jak skonfigurować zasadę

Zasady aktualizacji możesz skonfigurować na Androidzie 8.0 (poziom interfejsu API 26) lub nowszym. Aby określić, kiedy urządzenie ma instalować aktualizacje systemu, utwórz instancję SystemUpdatePolicy, używając jednego z 3 rodzajów opisanych powyżej. Aby skonfigurować zasady, właściciel urządzenia wywołuje metodę DevicePolicyManager setSystemUpdatePolicy(). Poniższy przykładowy kod pokazuje, jak to zrobić. Aby zobaczyć przykład zasady w oknie, zapoznaj się z dokumentacją 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);

Po utworzeniu instancji zasad nie można ich zmienić. Aby zmienić czas instalowania aktualizacji na urządzeniu, możesz utworzyć i ustawić nową zasadę. Aby usunąć zasadę z urządzenia, wywołaj setSystemUpdatePolicy(), przekazując null jako argument policy. Gdy DPC usunie zasadę, użytkownik urządzenia zobaczy powiadomienia o dostępnych aktualizacjach systemu.

Aplikacje mogą wywoływać metodę getSystemUpdatePolicy(), aby pobrać aktualną zasadę dotyczącą urządzenia. Jeśli ta metoda zwraca wartość null, oznacza to, że zasada nie jest obecnie ustawiona.

Okresy blokady

Aby zablokować wersję systemu operacyjnego w okresach krytycznych, takich jak święta lub inne ruchy, właściciele urządzeń mogą zawiesić aktualizacje systemu na maksymalnie 90 dni. Gdy urządzenie jest w okresie blokady, działa tak:

  • Urządzenie nie otrzymuje żadnych powiadomień o oczekujących aktualizacjach systemu.
  • Aktualizacje systemu operacyjnego nie są instalowane.
  • Użytkownicy urządzeń nie mogą ręcznie sprawdzać dostępności aktualizacji systemu w Ustawieniach.

Po każdym ustalonym okresie blokady system wymusza 60-dniowy okres buforowania, aby zapobiec zablokowaniu urządzenia w nieskończoność. Pamiętaj, że wstrzymanie aktualizacji systemu może uniemożliwić urządzeniom otrzymywanie krytycznych aktualizacji.

Rysunek 1. Ustawiono 2 okresy blokady dla urządzenia
Kalendarz z 2 okresami blokady w roku z 60-dniowymi buforami.

Ustawiasz okresy blokady dla zasady aktualizacji. Nie możesz ustawić okresów blokady bez ustawienia zasad. Gdy urządzenie wykracza poza ustawiony przez Ciebie okres blokady, obowiązuje normalne działanie zasad (automatyczne, w oknie lub odłożone w czasie).

Jak ustawić okres blokady

Okresy blokady możesz ustawić w Androidzie 9 (poziom interfejsu API 28) i nowszych. Przed ustawieniem zasady dla urządzenia właściciel urządzenia ustawia okres blokady w zasadach aktualizacji systemu. Kroki:

  1. Utwórz nowe zasady aktualizacji systemu (lub pobierz bieżące).
  2. Ustaw okresy blokady dla zasady, wywołując metodę setFreezePeriods().
  3. Ustaw zasady i okresy blokady urządzenia, wywołując metodę setSystemUpdatePolicy().

Okres blokady powtarza się co roku, dlatego daty jego rozpoczęcia i zakończenia są przedstawiane za pomocą wartości miesięcy i dni. Dzień początkowy musi rozpoczynać się co najmniej 60 dni po zakończeniu dowolnego poprzedniego okresu blokady. Poniższy przykład pokazuje, jak można ustawić 2 okresy blokady dla istniejącej zasady aktualizacji systemu:

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

Dzień rozpoczęcia i dzień zakończenia są uwzględnione. Jeśli dzień rozpoczęcia jest późniejszy niż dzień zakończenia (jak np. winterSale w poprzednim przykładzie), okres blokady zaczyna się od następnego roku.

Podczas ustawiania okresów blokady w zasadach aktualizacji systemu Android sprawdza te wymagania:

  • Żaden okres blokady nie może być dłuższy niż 90 dni.
  • Odstęp między okresami blokady wynosi co najmniej 60 dni.
  • Okresy blokady nie nakładają się na siebie.
  • Nie ma zduplikowanych okresów blokady.

Przy ustawianiu zasad aktualizacji systemu na urządzeniu Android powtarza te testy i uwzględnia wszystkie bieżące oraz wcześniejsze okresy blokady urządzenia.

Gdy któryś z tych testów się nie powiedzie, Android generuje błąd SystemUpdatePolicy.ValidationFailedException.

Aby uzyskać listę okresów blokady ustawionych wcześniej w obiekcie zasad aktualizacji systemu, wszystkie zainstalowane aplikacje mogą wywołać metodę SystemUpdatePolicy.getFreezePeriods(). Poniższy przykład wywołuje tę metodę w celu rejestrowania okresów blokady urządzenia:

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

Lata przestępne

Android oblicza okresy blokady za pomocą kalendarza ISO 8601 (nazywanego też kalendarzem gregoriańskim). Nie uwzględnia lat przestępnych. Oznacza to, że 29 lutego nie jest rozpoznawany jako prawidłowy i traktowany jak 28 lutego. Dlatego podczas obliczania czasu trwania okresu blokady data 29 lutego nie jest uwzględniana.

Programowanie i testowanie

Podczas programowania i testowania funkcji aktualizacji systemu DPC może być konieczne ustawienie wielu okresów blokady. Android sprawdza, czy odstępy między poprzednimi okresami blokady były 60-dniowe, dlatego ustawienie nowego okresu blokady bez wcześniejszego wyczyszczenia poprzednich okresów może być niemożliwe. Aby wyczyścić rekord okresu blokady urządzenia, uruchom to polecenie w powłoce Android Debug Bridge (adb):

adb shell dpm clear-freeze-period-record

Aby upewnić się, że urządzenie jest w okresie blokady, sprawdź, czy interfejs użytkownika do aktualizacji systemu jest wyłączony.

Dodatkowe materiały

Więcej informacji o aktualizacjach systemu znajdziesz w dokumentacji aktualizacji OTA w projekcie Android Open Source.