Ibernazione dell'app

Se la tua app ha come target Android 11 (livello API 30) o versioni successive e l'utente non interagisce con la tua app per alcuni mesi, il sistema la mette in stato di ibernazione. Il sistema ottimizza lo spazio di archiviazione anziché le prestazioni e protegge i dati degli utenti. Questo comportamento del sistema è simile a quello che si verifica quando l'utente arresta forzatamente la tua app dalle impostazioni di sistema.

Effetti dell'ibernazione

Come mostrato nella tabella 1, gli effetti della modalità di sospensione dipendono dalla versione dell'SDK target della tua app, nonché dal dispositivo su cui è in esecuzione:

Tabella 1. Effetti dell'ibernazione sulla tua app
Versione SDK target Caratteristiche del dispositivo Effetti della sospensione
Android 12 o versioni successive Eseguire Android 12 o versioni successive

Le autorizzazioni di runtime dell'app vengono reimpostate. Questa azione ha lo stesso effetto che se l'utente avesse visualizzato un'autorizzazione nelle impostazioni di sistema e avesse impostato il livello di accesso della tua app su Rifiuta.

L'app non può eseguire job o avvisi in background.

La tua app non può ricevere notifiche push, inclusi i messaggi con priorità elevata inviati tramite Firebase Cloud Messaging.

Tutti i file memorizzati nella cache dell'app vengono rimossi.

Android 11 Eseguire Android 11 Le autorizzazioni di runtime dell'app vengono reimpostate.
Android 11 Funziona su Android 6.0 (livello API 23) ad Android 10 (livello API 29), inclusive, nonché è basata su Google Play Services

Le autorizzazioni di runtime dell'app vengono reimpostate.

Questo comportamento entrerà in vigore a dicembre 2021. Scopri di più in questo post del blog su come rendere disponibile il ripristino automatico delle autorizzazioni per altri miliardi di dispositivi.

Comportamento del sistema quando un'app esce dalla modalità di sospensione

Quando l'utente interagisce di nuovo con l'app, questa esce dalla modalità di sospensione e può creare nuovamente job, avvisi e notifiche.

Tuttavia, il sistema non esegue le seguenti operazioni per la tua app:

  1. Concedi di nuovo le autorizzazioni di runtime dell'app.

    L'utente deve concedere nuovamente queste autorizzazioni per la tua app.

  2. Riprogramma eventuali job, avvisi e notifiche pianificati prima che la tua app andasse in ibernazione.

    Per supportare più facilmente questo flusso di lavoro, utilizza WorkManager. Puoi anche aggiungere la logica di riprogrammazione nel broadcast receiver ACTION_BOOT_COMPLETED, che viene richiamato quando l'app esce dalla modalità di sospensione e dopo l'avvio del dispositivo.

Utilizzo di app

Le seguenti sezioni forniscono esempi di utilizzo dell'app e di esempi di azioni che il sistema non considera come utilizzo dell'app.

Esempi di utilizzo delle app

Quando un'attività nella tua app viene ripresa, il sistema considera questo evento come un'interazione dell'utente. Di conseguenza, il sistema prolunga il tempo prima che l'app entri in modalità di sospensione.

Su Android 11 e versioni successive, anche i seguenti comportamenti sono considerati interazioni utente:

  • L'utente interagisce con un widget.
  • L'utente interagisce con una notifica, ad eccezione della chiusura della notifica.

Tieni presente che l'utilizzo dell'app per la modalità di sospensione non richiede esplicitamente l'interazione dell'utente. Finché viene invocato un componente del pacchetto, viene comunque considerato utilizzo dell'app. Ecco alcuni esempi:

  • App con un fornitore di servizi o contenuti vincolato da un'altra app sul dispositivo o nel sistema operativo. Ad esempio, Input Method Editor (IME) o gestori delle password.
  • I broadcast receiver nel pacchetto ricevono una trasmissione esplicita da un pacchetto esterno.

Non esempi

Se la tua app presenta soltanto i comportamenti descritti nel seguente elenco, l'app entra in ibernazione dopo alcuni mesi:

Esenzioni dal letargo del sistema

Android concede esenzioni a livello di sistema dal ibernazione delle app in determinati casi d'uso. Se la tua app rientra in una delle seguenti categorie, è esente degli standard di utilizzo delle app e non entrerà in modalità di sospensione.

App non visualizzate nel programma di avvio
Qualsiasi app che non abbia un riquadro di scorciatoia attivo in Avvio app.
App del profilo di lavoro
Qualsiasi app installata da un utente su un profilo di lavoro. Tieni presente che se la stessa app si trova anche in un profilo personale, solo l'app del profilo di lavoro è esente.
Controller dei criteri dei dispositivi
App che controllano criteri locali dei dispositivi e applicazioni di sistema sui dispositivi.
App con privilegi dell'operatore
Qualsiasi app precaricata dagli operatori di telefonia mobile sui dispositivi e ritenuta necessaria per adempiere alle obbligazioni contrattuali relative ai servizi, ad esempio app per la posta vocale o per l'assistenza clienti.
App di installazione di terze parti
Store di terze parti per gli aggiornamenti automatici delle app installate, se necessario.

Esenzioni dall'ibernazione per gli utenti

Se prevedi che un caso d'uso principale della tua app sia interessato dalla ibernazione, puoi richiedere all'utente un'esenzione. Questa esenzione è utile per le situazioni in cui l'utente si aspetta che la tua app funzioni principalmente in background, anche senza che l'utente interagisca con l'app, ad esempio quando la tua app esegue una delle seguenti operazioni:

  • Garantire la sicurezza della famiglia segnalando periodicamente la posizione dei familiari.
  • Sincronizza i dati tra un dispositivo e il server dell'app.
  • Comunicare con gli smart device, ad esempio una TV.
  • Accoppiamento con dispositivi complementari, ad esempio uno smartwatch.

Per richiedere un'esenzione, completa i passaggi descritti nelle sezioni seguenti.

Controlla se l'utente ha già disattivato la modalità di sospensione per la tua app

Per verificare se l'utente ha già disattivato la ibernazione per la tua app, utilizza l'API getUnusedAppRestrictionsStatus().

Per ulteriori dettagli su come utilizzare questa API nella tua app, vedi l'esempio di codice API in questa pagina.

Chiedi all'utente di disattivare la modalità di sospensione per la tua app

Se l'utente non ha già disattivato la modalità di sospensione per la tua app, puoi inviargli una richiesta. Per farlo, segui questi passaggi:

  1. Visualizza una UI che spiega all'utente perché deve disattivare la ibernazione per la tua app.
  2. Richiama l'API createManageUnusedAppRestrictionsIntent(), come mostrato nell'esempio di codice API. Questa API crea un'intent che carica la schermata Informazioni app nelle Impostazioni. Da qui, l'utente può disattivare la modalità di sospensione per la tua app.

    È importante chiamare startActivityForResult(), non startActivity(), quando invii questo intent.

    Come mostrato nella tabella 2, la posizione e il nome dell'opzione dipendono dalle caratteristiche del dispositivo su cui è installata l'app:

    Tabella 2. Opzione che disattiva l'ibernazione per la tua app
    Caratteristiche del dispositivo Pagina in cui viene visualizzata l'opzione Nome dell'opzione da disattivare
    Android 13 o versioni successive Informazioni delle app Sospendi attività app se inutilizzata
    Eseguire Android 12 Informazioni delle app Rimuovi autorizzazioni e libera spazio
    Con Android 11 Informazioni sull'app > Autorizzazioni Rimuovi le autorizzazioni se l'app non viene utilizzata
    Disponibile dalla versione 6.0 ad Android 10 inclusi ed è basata su Google Play Services App Play > Menu > Play Protect > Autorizzazioni per app non utilizzate Rimuovere le autorizzazioni se l'app non viene utilizzata

Esempio di codice API

Questo esempio di codice mostra come verificare se la modalità di sospensione è attivata per la tua app e il modo corretto per chiedere agli utenti di disattivarla.

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

API della piattaforma precedente

Il sistema operativo include anche un'API per interagire con la funzionalità di ibernazione. Tuttavia, l'API funziona solo su dispositivi con Android 11 o versioni successive; l'API non gestisce le funzionalità di ibernazione di cui viene eseguito il backporting alle versioni di Android precedenti. Pertanto, sconsigliamo di utilizzare l'API.

Se devi continuare a utilizzare temporaneamente l'API per motivi di compatibilità, l'elenco seguente mostra come utilizzarla:

Invocare manualmente il comportamento di ibernazione

Per testare il comportamento dell'app dopo che il sistema la inserisce in uno stato di ibernazione, completa i seguenti passaggi:

  1. (Solo Android 12 e versioni successive) Attiva il comportamento di ibernazione sul tuo dispositivo:

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. Imposta il periodo di tempo predefinito che il sistema attende per entrare in modalità di sospensione. In questo modo, potrai ripristinarlo dopo aver eseguito il test:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. Ridurre il tempo di attesa del sistema. Nell'esempio seguente, il sistema viene modificato in modo che l'app entri in modalità di sospensione solo un secondo dopo che hai smesso di interagire con l'app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. Attendi il completamento delle trasmissioni in fase di avvio sul dispositivo di test eseguendo questo comando:

    adb shell am wait-for-broadcast-idle
    

    Al termine della trasmissione, questo comando restituisce il messaggio: All broadcast queues are idle!

  5. Richiama manualmente la procedura di ibernazione dell'app:

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (Solo Android 12 e versioni successive) Verifica che l'app sia in modalità di sospensione utilizzando uno dei seguenti metodi:

    • Nota che ora il dispositivo di test mostra una notifica che indica che le app non utilizzate sono in modalità di sospensione.
    • Esegui questo comando:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. Ripristina la durata predefinita che il sistema attende prima di mettere in ibernazione la tua app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold