Gestire gli aggiornamenti di sistema

Questa guida per gli sviluppatori spiega in che modo il controller dei criteri dei dispositivi (DPC) può gestire gli aggiornamenti di sistema Android per conto dell'utente del dispositivo.

Introduzione

I dispositivi Android possono ricevere e installare aggiornamenti over-the-air (OTA) del sistema e applicazioni software. Android comunica all'utente del dispositivo che è disponibile un aggiornamento di sistema e l'utente può installarlo immediatamente o in un secondo momento.

Utilizzando il DPC, un amministratore IT può gestire gli aggiornamenti di sistema per l'utente del dispositivo. DPC (controller criteri dispositivi) possono possedere un dispositivo completamente gestito (chiamato proprietario del dispositivo) o un profilo di lavoro (denominato proprietario del profilo). La tabella 1 mostra come i proprietari dei dispositivi possono gestire il sistema degli aggiornamenti di sistema, mentre i proprietari dei profili possono segnalare solo le informazioni relative agli aggiornamenti di sistema.

Tabella 1: le attività disponibili per i PDC dipendono dalla modalità di proprietà

Attività Proprietario del dispositivo Proprietario del profilo
Verificare la presenza di aggiornamenti di sistema in attesa
Ricevere chiamate di ritorno quando sono disponibili nuovi aggiornamenti di sistema
Impostare un criterio di aggiornamento locale per stabilire quando Android installa gli aggiornamenti di sistema
Blocca la versione del sistema operativo durante i periodi critici

Verificare la presenza di aggiornamenti in attesa

Un aggiornamento in attesa è un aggiornamento di sistema per un dispositivo che non è stato ancora installato. Il DPC può aiutare gli amministratori IT a controllare quali dispositivi hanno aggiornamenti di sistema in attesa e, se necessario, chiedere agli utenti di installare tempestivamente gli aggiornamenti critici.

Proprietari di dispositivi e proprietari di profili con Android 8.0 (livello API 26) o versioni successive può controllare se su un dispositivo esiste un aggiornamento di sistema in sospeso. Chiama DevicePolicyManager.getPendingSystemUpdate() che restituisce null se il dispositivo è aggiornato. Se è in attesa un aggiornamento di sistema, il metodo restituisce informazioni sull'aggiornamento.

Scopri di più su un aggiornamento in attesa

Dopo aver chiamato getPendingSystemUpdate(), puoi controllare il valore SystemUpdateInfo restituito per scoprire di più sull'aggiornamento in attesa. La l'esempio seguente mostra come scoprire quando è stato eseguito per la prima volta un aggiornamento in sospeso disponibili per il dispositivo:

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

Richiami di sistema

Quando un aggiornamento diventa disponibile, il sistema Android invia una notifica ai proprietari del dispositivo. In Android 8.0 o versioni successive, il sistema invia notifiche anche ai proprietari dei profili.

Nella sottoclasse DeviceAdminReceiver, sostituisci il callback onSystemUpdatePending(). Non è necessario registrarsi o fare pubblicità per il tuo DPC per ricevere la chiamata. Il sistema potrebbe chiamare questo metodo più di una volta per un singolo aggiornamento, quindi controlla lo stato dell'aggiornamento prima di rispondere. Chiama il numero getPendingSystemUpdate() per scoprire di più sul un aggiornamento di sistema nel callback. L'esempio seguente mostra come eseguire questa operazione:

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

Quando un sistema ha più di un DPC, ad esempio profili di lavoro su dispositivi completamente gestiti, sia il proprietario del dispositivo sia il proprietario del profilo ricevono il callback.

Aggiorna i criteri

Il proprietario di un dispositivo può controllare quando vengono installati gli aggiornamenti impostando un criterio di aggiornamento di sistema locale per il dispositivo. Il criterio di aggiornamento di sistema può essere di tre tipi:

Automatico
Installa gli aggiornamenti di sistema non appena diventano disponibili (senza interazione da parte dell'utente). L'impostazione di questo tipo di criterio installa immediatamente gli aggiornamenti in attesa che potrebbero essere posticipati o in attesa di una finestra di manutenzione.
Con finestra
Installa aggiornamenti di sistema durante una manutenzione giornaliera (senza interazione dell'utente). Imposta l'inizio e la fine del periodo di manutenzione giornaliera, come minuti di giorno, durante la creazione di un nuovo criterio con finestre.
Rinviato
Rinvia di 30 giorni l'installazione degli aggiornamenti di sistema. Al termine del periodo di 30 giorni, il sistema chiede all'utente del dispositivo di installare l'aggiornamento.

Periodi di posticipazione

Il sistema limita ogni aggiornamento a un rinvio di 30 giorni. Il periodo inizia quando il sistema rinvia per la prima volta l'aggiornamento e l'impostazione di nuovi criteri di rinvio non prolunga il periodo.

Oltre al posticipo, Android potrebbe non essere in grado di installare un aggiornamento per altri motivi, ad esempio assenza di connettività, spazio su disco insufficiente o batteria in esaurimento.

Il sistema reimposta il timer di posticipazione di 30 giorni se un aggiornamento diverso disponibili durante il periodo, offrendo agli amministratori IT la possibilità di provare il sistema combinato aggiornamenti. Dopo 30 giorni senza un nuovo aggiornamento, il sistema chiede all'utente di installare tutti gli aggiornamenti in attesa. In seguito, quando un nuovo aggiornamento di sistema disponibile, il periodo di 30 giorni ricomincia.

Come impostare un criterio

Puoi impostare i criteri di aggiornamento in Android 8.0 (livello API 26) o versioni successive. Per specificare quando il dispositivo deve installare aggiornamenti di sistema, crea un'istanza SystemUpdatePolicy utilizzando uno dei tre tipi descritti in alto. Per impostare un criterio, il proprietario del dispositivo chiama il metodo DevicePolicyManager setSystemUpdatePolicy() Il seguente codice esempio mostra come eseguire questa operazione. Per vedere un esempio di criterio con finestra, consulta la documentazione di 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);

Le istanze dei criteri non possono essere modificate dopo la loro creazione. Per modificare quando un dispositivo aggiornamenti delle installazioni, puoi creare e impostare un nuovo criterio. Per rimuovere un criterio da un dispositivo, chiama setSystemUpdatePolicy() passando null come argomento policy. Dopo che il DPC ha rimosso un criterio, l'utente del dispositivo vede le notifiche relative agli aggiornamenti di sistema disponibili.

Le app possono chiamare getSystemUpdatePolicy() per recuperare il criterio corrente del dispositivo. Se questo metodo restituisce null, significa che al momento non è impostato.

Periodi di blocco

Per bloccare la versione del sistema operativo durante periodi critici, come le festività o altri periodi di picco, i proprietari di dispositivi possono sospendere gli aggiornamenti di sistema per un massimo di 90 giorni. Quando un dispositivo è in un periodo di blocco, si comporta nel seguente modo:

  • Il dispositivo non riceve notifiche sugli aggiornamenti di sistema in attesa.
  • Gli aggiornamenti di sistema al sistema operativo non sono installati.
  • Gli utenti del dispositivo non possono controllare manualmente la disponibilità di aggiornamenti di sistema nelle Impostazioni.

Il sistema applica un periodo di buffer obbligatorio di 60 giorni dopo eventuali periodi di blocco definiti per impedire il blocco del dispositivo a tempo indeterminato. Ricorda che il sistema si blocca gli aggiornamenti possono impedire ai dispositivi di ricevere aggiornamenti critici.

Figura 1. Due periodi di blocco impostati per un dispositivo
Calendario che mostra due periodi di blocco in un anno con buffer di 60 giorni.

Imposti periodi di blocco in un criterio di aggiornamento. Non puoi impostare periodi di blocco senza l'impostazione di un criterio. Quando il dispositivo è al di fuori di eventuali periodi di blocco impostati, si applica il comportamento normale della norma (automatico, con finestra o posticipato).

Come impostare un periodo di blocco

Puoi impostare periodi di blocco in Android 9 (livello API 28) o versioni successive. Il proprietario di un dispositivo imposta un periodo di blocco per un criterio di aggiornamento di sistema prima di impostare il criterio per il dispositivo. Ecco i passaggi:

  1. Crea un nuovo criterio di aggiornamento di sistema (o scarica quello attuale).
  2. Imposta i periodi di blocco nel criterio chiamando setFreezePeriods().
  3. Imposta i criteri e i periodi di blocco per il dispositivo chiamando setSystemUpdatePolicy().

Poiché il periodo di blocco si ripete ogni anno, le date di inizio e di fine del periodo sono rappresentate dai valori di mese e giorno. Il giorno di inizio deve iniziare alle ore almeno 60 giorni dopo la fine di qualsiasi periodo di blocco precedente. L'esempio seguente mostra come impostare due periodi di blocco per un criterio di aggiornamento di sistema esistente:

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

Sono inclusi sia il giorno di inizio che quello di fine. Se il giorno di inizio è successivo al giorno di fine (ad esempio winterSale nell'esempio precedente), il periodo di blocco si estende all'anno successivo.

Quando imposti il blocco periodi su un criterio di aggiornamento di sistema, Android verifica i seguenti requisiti:

  • Nessun periodo di blocco è superiore a 90 giorni.
  • L'intervallo tra i periodi di blocco è di almeno 60 giorni.
  • I periodi di blocco non si sovrappongono.
  • Non sono presenti periodi di blocco duplicati.

Quando si imposta il criterio di aggiornamento di sistema per un dispositivo, Android ripete questi test e include eventuali periodi di blocco attuali o passati per il dispositivo.

Android genera un SystemUpdatePolicy.ValidationFailedException quando uno di questi test non va a buon fine.

Per ottenere un elenco di periodi di blocco impostati in precedenza su un oggetto criterio di aggiornamento di sistema, tutte le app installate possono chiamare SystemUpdatePolicy.getFreezePeriods() L'esempio seguente chiama questo metodo per registrare i periodi di blocco di un dispositivo:

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

Anni bisestili

Android utilizza il calendario ISO 8601 (detto anche calendario gregoriano) per calcolano i periodi di blocco e ignora gli anni bisestili. Ciò significa che il 29 febbraio non è riconosciuto come data valida e viene trattato come se fosse il 28 febbraio. Pertanto, il 29 febbraio non viene conteggiato durante il calcolo della durata di un periodo di blocco.

Sviluppo e test

Durante lo sviluppo e il test della funzionalità di aggiornamento di sistema del tuo DPC, potresti dover creare molti periodi di blocco. Android esegue controlli su un intervallo di 60 giorni tra periodi di blocco precedenti, potresti non essere in grado di impostare un nuovo periodo senza prima cancellare il record dei cicli passati. Per eliminare il blocco del dispositivo periodo, esegui il comando seguente in Android Debug Bridge Shell (adb):

adb shell dpm clear-freeze-period-record

Puoi verificare che un dispositivo si trovi in un periodo controllando che l'utente per gli aggiornamenti di sistema è disabilitata.

Aggiornamenti di sistema Google Play (Mainline)

Gli aggiornamenti di sistema Google Play (chiamati anche aggiornamenti Mainline) vengono scaricati automaticamente, ma l'installazione richiede il riavvio del dispositivo. Questi aggiornamenti non attiveranno un riavvio automatico, ma saranno installati all'avvio del riavvio successivo dell'utente, dell'amministratore o del criterio. I riavvii attivati dal criterio di aggiornamento del sistema installeranno l'aggiornamento di sistema Google/OEM associato e gli eventuali aggiornamenti di sistema Google Play scaricati in precedenza.

Gli aggiornamenti di sistema Google Play possono essere installati anche manualmente visitando Impostazioni > Informazioni > Versione Android > Aggiornamento di sistema Google Play.

Esegui il rollback di un aggiornamento

In alcuni casi, lo strumento di rollback degli aggiornamenti di sistema Google Play (GPSUR) può essere utilizzato per recuperare lo stato del dispositivo a causa di un'installazione problematica dell'aggiornamento di sistema Google Play. Questo strumento deve essere utilizzato da utenti avanzati o se indicato dal personale di assistenza, in quanto potrebbe comportare la perdita di dati. Ecco come utilizzare GPSUR questo strumento:

  1. Se sulla tua macchina è in esecuzione Android Debug Bridge (adb), interrompi il servizio adb prima di procedere in modo che non interferisca con la procedura di rollback. Per interrompere ADB, esegui adb kill-server.
  2. Apri lo strumento GPSUR.
  3. Fai clic su Consenti accesso ADB per consentire allo strumento di comunicare con il test dispositivo tramite ADB.
  4. Fai clic su Aggiungi nuovo dispositivo.
  5. Seleziona il tuo dispositivo dall'elenco e fai clic su Connetti. Questo elenco potrebbe non devono contenere il nome completo del dispositivo.
  6. Sullo schermo del dispositivo, seleziona Consenti sempre da questo computer e fai clic su Ok per accettare la connessione di debug USB.
  7. Seleziona il dispositivo connesso nel browser.
  8. Il testo del pulsante nella pagina dovrebbe passare da Nessun rollback disponibile a Esegui il rollback degli aggiornamenti recenti se sono disponibili rollback sul tuo dispositivo. Fai clic su Esegui il rollback degli aggiornamenti recenti.
  9. Leggi gli avvisi nella finestra modale Conferma rollback e fai clic su Conferma.
  10. Attendi il completamento del rollback. Al termine, viene eseguito il Rollback riuscito apparirà la finestra modale e il dispositivo verrà riavviato. Ora puoi scollegare il dispositivo dispositivo.

Risorse aggiuntive

Per scoprire di più sugli aggiornamenti di sistema, leggi l'OTA di Android Open Source Project Aggiornamenti.