Wakeup eccessivi

I wakeup sono un meccanismo dell'API AlarmManager che consente agli sviluppatori di impostare una sveglia per riattivare un dispositivo all'ora specificata. L'app imposta una sveglia di riattivazione chiamando uno dei metodi set() in AlarmManager con il flag RTC_WAKEUP o ELAPSED_REALTIME_WAKEUP. Quando viene attivata una sveglia wakeup, il dispositivo esce dalla modalità a basso consumo e mantiene un Wakelock parziale durante l'esecuzione del metodo onReceive() o onAlarm() della sveglia. Se le sveglie di riattivazione vengono attivate eccessivamente, possono scaricare la batteria di un dispositivo.

Per aiutarti a migliorare la qualità delle app, Android monitora automaticamente le app per rilevare un numero eccessivo di sveglie wakeup e visualizza le informazioni in Android vitals. Per informazioni su come vengono raccolti i dati, consulta la documentazione relativa a Play Console.

Se la tua app riattiva il dispositivo troppo, puoi utilizzare le indicazioni in questa pagina per diagnosticare e risolvere il problema.

Risolvi problema

La AlarmManager è stata introdotta nelle prime versioni della piattaforma Android, ma nel tempo molti casi d'uso che in precedenza richiedevano AlarmManager sono ora migliorati da funzionalità più recenti come WorkManager. Questa sezione contiene suggerimenti per ridurre le sveglie a risveglio, ma, a lungo termine, valuta la possibilità di eseguire la migrazione della tua app in modo da seguire i consigli nella sezione delle best practice.

Identifica i punti nell'app in cui programmi le sveglie sveglie e riduci la frequenza di attivazione di queste sveglie. Ecco alcuni suggerimenti:

  • Cerca le chiamate ai vari metodi set() in AlarmManager che includono il flag RTC_WAKEUP o ELAPSED_REALTIME_WAKEUP.

  • Si consiglia di includere il nome del pacchetto, della classe o del metodo nel nome tag del rilevatore in modo da poter identificare facilmente la posizione nella sorgente in cui è stata impostata la sveglia. Ecco alcuni suggerimenti aggiuntivi:

    • Lascia nel nome eventuali informazioni che consentono l'identificazione personale (PII), ad esempio un indirizzo email. In caso contrario, il dispositivo registra _UNKNOWN anziché il nome dell'allarme.
    • Non ottenere il nome della classe o del metodo in modo programmatico, ad esempio chiamando getName(), perché potrebbe essere offuscato da Proguard. Utilizza invece una stringa hardcoded.
    • Non aggiungere un contatore o identificatori univoci ai tag di allarme. Il sistema non sarà in grado di aggregare gli allarmi impostati in questo modo perché hanno tutti identificatori univoci.

Dopo aver risolto il problema, verifica che le sveglie wakeup funzionino come previsto eseguendo il seguente comando ADB:

adb shell dumpsys alarm

Questo comando fornisce informazioni sullo stato del servizio del sistema di allarme sul dispositivo. Per ulteriori informazioni, consulta dumpsys.

Best practice

Utilizza le sveglie wakeup solo se la tua app deve eseguire un'operazione rivolta all'utente, ad esempio pubblicare una notifica o avvisare l'utente. Per un elenco delle best practice di AlarmManager, consulta Programmazione delle sveglie.

Non utilizzare AlarmManager per pianificare le attività in background, in particolare le attività ricorrenti o in background. Utilizza WorkManager per pianificare le attività in background perché offre i seguenti vantaggi:

  • batch: i job vengono combinati in modo da ridurre il consumo della batteria
  • persistenza: se il dispositivo viene riavviato, i job WorkManager pianificati vengono eseguiti al termine del riavvio
  • criteri: i lavori possono essere eseguiti in base alle condizioni, ad esempio se il dispositivo è in carica o se è disponibile una rete Wi-Fi

Per ulteriori informazioni, consulta la Guida all'elaborazione in background.

Non utilizzare AlarmManager per pianificare operazioni di temporizzazione valide solo mentre l'app è in esecuzione (in altre parole, l'operazione di temporizzazione dovrebbe essere annullata quando l'utente esce dall'app). In queste situazioni, utilizza la classe Handler perché è più facile da usare e molto più efficiente.