Legislazione 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 mette la tua app in stato di ibernazione. Il sistema ottimizza lo spazio di archiviazione anziché le prestazioni e protegge i dati utente. Questo comportamento del sistema è simile a quello che si verifica quando l'utente forza manualmente l'interruzione della tua app dalle impostazioni di sistema.

Effetti dell'ibernazione

Come mostrato nella tabella 1, gli effetti dell'ibernazione dipendono dalla versione dell'SDK target dell'app, nonché dal dispositivo su cui viene eseguita l'app:

Tabella 1. Effetti dell'ibernazione nella tua app
Versione SDK target Caratteristiche del dispositivo Effetti di letargo
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 se l'utente visualizzasse un'autorizzazione nelle impostazioni di sistema e modificasse il livello di accesso dell'app in Nega.

La tua 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 presenti nella cache dell'app vengono rimossi.

Android 11 Con sistema operativo Android 11 Le autorizzazioni di runtime della tua app sono state reimpostate.
Android 11 Esegue Android 6.0 (livello API 23) ad Android 10 (livello API 29) inclusi ed è basato su Google Play Services

Le autorizzazioni di runtime della tua app sono state reimpostate.

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

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

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

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

  1. Concedi di nuovo le autorizzazioni di runtime della tua app.

    L'utente deve riautorizzare queste autorizzazioni per la tua app.

  2. Riprogramma tutti i job, gli avvisi e le notifiche che sono stati pianificati prima della sospensione dell'app.

    Per supportare più facilmente questo flusso di lavoro, utilizza WorkManager. Puoi anche aggiungere la logica di riprogrammazione nel ricevitore di trasmissione del ACTION_BOOT_COMPLETED, che viene richiamato quando l'app lascia il periodo di sospensione e dopo l'avvio del dispositivo.

Utilizzo di app

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

Esempi di utilizzo delle app

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

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

  • L'utente interagisce con un widget.
  • L'utente interagisce con una notifica, ma non la ignora.

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

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

Non esempi

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

Esenzioni di sistema dalla sospensione

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

App non visualizzate in Avvio app
Qualsiasi app che non ha 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 i criteri relativi ai dispositivi locali e le applicazioni di sistema sui dispositivi.
App con privilegi dell'operatore
Qualsiasi app che gli operatori di telefonia mobile precaricano sui dispositivi e che ritengono necessarie per gli obblighi contrattuali relativi ai servizi, ad esempio app di segreteria o di assistenza clienti.
App per installazione di terze parti
Store di terze parti per aggiornamenti automatici delle app installate quando necessario.

Esenzioni per gli utenti dalla sospensione

Se prevedi che un caso d'uso principale nella tua app sia interessato dalla sospensione, 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 abbia interagito con l'app, ad esempio quando l'app esegue una delle seguenti operazioni:

  • Proteggi la tua 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.
  • Accoppiare dispositivi associati, ad esempio uno smartwatch.

Per richiedere un'esenzione, completa la procedura descritta nelle sezioni seguenti.

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

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

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

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

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

  1. Mostra una UI che spiega all'utente perché deve disabilitare la sospensione dell'app per l'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 sospensione per la tua app.

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

    Come mostrati 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 la sospensione per la tua app
    Caratteristiche del dispositivo Pagina in cui viene visualizzata l'opzione Nome dell'opzione di disattivazione
    Avere Android 13 o versioni successive Informazioni app Metti in pausa l'attività nelle app se inutilizzata
    Con sistema operativo Android 12 Informazioni app Rimuovi le autorizzazioni e libera spazio
    Con sistema operativo Android 11 Informazioni sulle app > Autorizzazioni Rimuovi le autorizzazioni se l'app non viene utilizzata
    Ha un sistema operativo da Android 6.0 ad Android 10 inclusi ed è basato su Google Play Services App Play > Menu > Play Protect > Autorizzazioni per le 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 è abilitata per la tua app e il modo corretto per chiedere agli utenti di disabilitare questa sospensione 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 legacy

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 temporaneamente l'API per motivi di compatibilità, il seguente elenco mostra come usarla:

Richiama manualmente il comportamento di ibernazione

Per verificare il comportamento della tua app dopo che il sistema ha attivato lo stato di ibernazione, procedi nel seguente modo:

  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. Consente di impostare l'intervallo 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. Riduci 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 interrotto l'interazione con l'app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. Attendi il completamento della trasmissione 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 il processo 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 sospensione utilizzando uno dei seguenti metodi:

    • Tieni presente che il dispositivo di test ora mostra una notifica, che indica che le app inutilizzate sono state ibernate.
    • Esegui questo comando:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. Ripristina il tempo predefinito di attesa dal sistema prima di mettere in pausa la tua app:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold