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 è ottimizzato per lo spazio di archiviazione anziché per le prestazioni e protegge i dati utente. Questo comportamento del sistema è simile a quello che si verifica quando l'utente arresta forzatamente la tua app manualmente dalle impostazioni di sistema.

Effetti dell'ibernazione

Come mostrato nella tabella 1, gli effetti dell'ibernazione dipendono dalla versione dell'SDK target della tua app e dal dispositivo su cui è in esecuzione:

Tabella 1. Effetti dell'ibernazione sull'app
Versione SDK target Caratteristiche del dispositivo Effetti dell'ibernazione
Android 12 o versioni successive Android 12 o versioni successive

Le autorizzazioni di runtime della tua app vengono reimpostate. Questa azione ha lo stesso effetto che si avrebbe se l'utente visualizzasse un'autorizzazione nelle impostazioni di sistema e modificasse il livello di accesso della tua app impostandolo su Nega.

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.

Vengono rimossi tutti i file nella cache dell'app.

Android 11 Android 11 Le autorizzazioni di runtime dell'app vengono reimpostate.
Android 11 Esegue Android 6.0 (livello API 23) fino ad Android 10 (livello API 29) incluso ed è basato 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 a miliardi di dispositivi in più.

Comportamento del sistema quando un'app esce dalla sospensione

La volta successiva che l'utente interagisce con la tua app, questa esce dalla modalità di ibernazione e può creare di nuovo job, avvisi e notifiche.

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

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

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

  2. Ripianifica eventuali job, avvisi e notifiche programmati prima che l'app entri in modalità di ibernazione.

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

Utilizzo di app

Le sezioni seguenti forniscono esempi di utilizzo delle app, nonché esempi di azioni che il sistema non considera come utilizzo delle app.

Esempi di utilizzo dell'app

Quando un'attività nella tua app viene ripresa, il sistema considera questo evento come un'interazione utente. Pertanto, il sistema estende il periodo di tempo prima che l'app entri in ibernazione.

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

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

È importante notare che l'utilizzo dell'app per la sospensione non richiede esplicitamente l'interazione dell'utente. Finché viene richiamato un componente del pacchetto, viene comunque considerato utilizzo dell'app. Alcuni esempi includono:

  • App che hanno un fornitore di servizi o contenuti vincolato a un'altra app sul dispositivo o al sistema operativo. Ad esempio, Input Method Editor (IME) o gestori delle password.
  • Ricevitori di broadcast nel pacchetto che ricevono un broadcast esplicito da un pacchetto esterno.

Controesempi

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

Esenzioni del sistema dall'ibernazione

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

App non visualizzate in Avvio app
Qualsiasi app che non abbia un riquadro di scorciatoia attivo nell'avvio app.
App del profilo di lavoro
Qualsiasi app installata da un utente in un profilo di lavoro. Tieni presente che se la stessa app si trova anche in un profilo personale, è esente solo l'app del profilo di lavoro.
Controller dei criteri dei dispositivi
App che controllano i criteri dei dispositivi locali e le applicazioni di sistema sui dispositivi.
App con privilegi dell'operatore
Qualsiasi app precaricata sugli smartphone dagli operatori di telefonia mobile e ritenuta necessaria per gli obblighi di servizio contrattuali, ad esempio le app di segreteria telefonica o di assistenza clienti.
App di installazione di terze parti
Store di terze parti per gli aggiornamenti automatici delle app installate quando necessario.

Esenzioni degli utenti dall'ibernazione

Se prevedi che un caso d'uso principale della tua app sia interessato dall'ibernazione, puoi richiedere all'utente un'esenzione dall'ibernazione dell'app. 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 membri della famiglia.
  • Sincronizza i dati tra un dispositivo e il server della tua app.
  • Comunicare con smart device, ad esempio una TV.
  • Accoppiamento a dispositivi complementari, come uno smartwatch.

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

Controlla se l'utente ha già disattivato l'ibernazione per la tua app

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

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

Chiedi all'utente di disattivare l'ibernazione per la tua app

Se l'utente non ha ancora disattivato l'ibernazione per la tua app, puoi inviargli una richiesta. Per farlo, segui questi passaggi:

  1. Mostra un'interfaccia utente che spieghi all'utente perché deve disattivare l'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 in Impostazioni. Da qui, l'utente può disattivare l'ibernazione per la tua app.

    È importante che chiami 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
    Android 12 Informazioni delle app Rimuovi autorizzazioni e libera spazio
    Android 11 Informazioni app > Autorizzazioni Rimuovi le autorizzazioni se l'app non viene utilizzata
    Supporta Android 6.0-10 inclusi ed è basato su Google Play Services App Play > Menu > Play Protect > Autorizzazioni per app inutilizzate Rimuovi le autorizzazioni se l'app non viene utilizzata

Esempio di codice API

Questo esempio di codice mostra come verificare se l'ibernazione è attivata per la tua app e il modo corretto per chiedere agli utenti di disattivarla per la tua app.

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 è stato eseguito il backporting alle versioni precedenti di Android. Pertanto, sconsigliamo di utilizzare l'API.

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

Richiamare manualmente il comportamento di ibernazione

Per testare il comportamento della tua app dopo che il sistema la mette in 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 prima di entrare in ibernazione. In questo modo, potrai ripristinarlo dopo 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 ibernazione 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 di tutte le trasmissioni all'avvio sul dispositivo di test eseguendo il seguente comando:

    adb shell am wait-for-broadcast-idle
    

    Al termine delle trasmissioni, 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 stato di ibernazione utilizzando uno dei seguenti metodi:

    • Nota che sul dispositivo di test ora viene visualizzata una notifica che indica che le app inutilizzate sono in ibernazione.
    • Esegui questo comando:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. Ripristina il periodo di tempo predefinito che il sistema attende prima di mettere l'app in sospensione:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold