AlarmManager
classe) ti daranno la possibilità di eseguire
le operazioni basate sul tempo al di fuori
della durata della tua applicazione.
Ad esempio, potresti utilizzare un allarme per avviare un'operazione a lunga esecuzione, come
avviando un servizio una volta al giorno per scaricare una previsione meteo.
Gli allarmi hanno le seguenti caratteristiche:
Ti consentono di attivare gli intent in orari e/o intervalli prestabiliti.
Puoi usarli insieme ai broadcast receiver per programmare jobs o WorkRequests per eseguire altre operazioni.
Funzionano al di fuori dell'applicazione, quindi puoi utilizzarli per attivare eventi o azioni anche quando l'app non è in esecuzione e anche se il dispositivo è in sospensione.
Ti aiutano a ridurre al minimo i requisiti di risorse della tua app. Puoi pianificare le operazioni senza utilizzare timer o servizi in esecuzione continua.
Impostare una sveglia approssimativa
Quando un'app imposta una sveglia inesatta, il sistema a un certo punto invia la sveglia in futuro. Le sveglie imprecise forniscono alcune garanzie in merito alla tempistica di invio della sveglia, rispettando al contempo le limitazioni per il risparmio della batteria, come la modalità Sospensione.
Gli sviluppatori possono sfruttare le garanzie API riportate di seguito per personalizzare le tempistiche alla consegna inesatta della sveglia.
Inviare una sveglia dopo un orario specifico
Se la tua app chiama set()
,
setInexactRepeating()
o
setAndAllowWhileIdle()
,
la sveglia non suona mai prima dell'ora di attivazione specificata.
Su Android 12 (livello API 31) e versioni successive, il sistema attiva l'allarme entro uno ora del tempo di attivazione specificato, a meno che non siano previste restrizioni per il risparmio energetico come risparmio energetico o Sospensione.
Inviare una sveglia durante un intervallo di tempo
Se la tua app chiama setWindow()
, la sveglia non suona mai prima dell'ora di attivazione fornita. A meno che non siano in vigore limitazioni per il risparmio della batteria, l'avviso viene inviato nell'intervallo di tempo specificato, a partire dall'ora di attivazione indicata.
Se la tua app ha come target Android 12 o versioni successive, il sistema potrebbe ritardare
la chiamata di una sveglia inesatta con intervallo temporale di almeno 10 minuti. Per
per questo motivo, i valori parametro windowLengthMillis
in 600000
sono troncati a
600000
.
Invia una sveglia ripetuta a intervalli approssimativamente regolari
Se la tua app chiama setInexactRepeating()
,
il sistema richiama più allarmi:
- La prima sveglia suona nell'intervallo di tempo specificato, a partire dall'ora di attivazione specificata.
- Le sveglie successive solitamente suonano dopo l'intervallo di tempo specificato trascorrano. Il tempo tra due invocazioni consecutive dell'allarme può variare.
Impostare una sveglia esatta
Il sistema richiama un allarme esatto in un momento preciso in futuro.
La maggior parte delle app può programmare attività ed eventi utilizzando sveglie inesatte per completare diversi casi d'uso comuni. Se la funzionalità di base della tua app dipende da una sveglia con timer preciso, ad esempio per un'app sveglia o un'app di calendario, puoi utilizzare una sveglia esatta.
Casi d'uso che potrebbero non richiedere sveglie esatte
Il seguente elenco mostra flussi di lavoro comuni che potrebbero non richiedere un allarme esatto:
- Pianificare le operazioni di sincronizzazione per l'intero ciclo di vita dell'app
- La classe
Handler
include diversi metodi utili per gestire le operazioni di temporizzazione, ad esempio eseguire un'operazione ogni n secondi, mentre l'app è attiva:postAtTime()
epostDelayed()
. Tieni presente che queste API si basano sull'uptime del sistema e non in tempo reale. - Operazioni in background pianificate, ad esempio l'aggiornamento dell'app e il caricamento dei log
WorkManager
fornisce un modo per pianificare il lavoro periodico con tempistiche precise. Puoi fornire un intervallo di ripetizione eflexInterval
(minimo 15 minuti) per per definire il runtime granulare per il lavoro.- Azione specificata dall'utente che deve avvenire dopo un momento specifico (anche se il sistema è in stato inattivo)
- Usa una sveglia inesatta. In particolare, richiama
setAndAllowWhileIdle()
- Azione specificata dall'utente che deve avvenire dopo un intervallo di tempo specifico
- Utilizzare una sveglia non esatta. In particolare, richiama
set()
- Azione specificata dall'utente che può verificarsi entro un periodo di tempo specificato
- Usa una sveglia inesatta. Nello specifico, chiama
setWindow()
. Tieni presente che, se la tua app ha come target Android 12 o versioni successive, la durata minima della finestra consentita è di 10 minuti.
Come impostare una sveglia esatta
La tua app può impostare sveglie precise utilizzando uno dei seguenti metodi. Questi metodi sono ordinati in modo che quelli più vicini alla fine dell'elenco pubblichino critici in termini di tempo, ma richiedono più risorse di sistema.
setExact()
Attivare una sveglia a un orario futuro quasi preciso, a condizione che non siano attive altre misure di risparmio batteria.
Usa questo metodo per impostare sveglie esatte, a meno che il lavoro dell'app non sia cruciali per l'utente.
setExactAndAllowWhileIdle()
Attivare una sveglia in un momento futuro quasi preciso, anche se sono attive misure di risparmio energetico.
setAlarmClock()
Consente di attivare una sveglia a un'ora precisa nel futuro. Poiché questi allarmi sono molto visibili agli utenti, il sistema non ne modifica mai la data di invio. La il sistema identifica questi allarmi come i più critici e lascia a bassa potenza modalità d'allarme se necessario.
Consumo di risorse di sistema
Quando il sistema attiva allarmi esatti impostati dalla tua app, il dispositivo consuma molte risorse, ad esempio la durata della batteria, soprattutto se è in modalità di risparmio energetico. Inoltre, il sistema non può raggruppare facilmente queste richieste per utilizzare le risorse in modo più efficiente.
Ti consigliamo vivamente di creare un allarme impreciso ogni volta che è possibile. Per eseguire un'attività più lunga, programmala utilizzando
WorkManager
o
JobScheduler
dal menuBroadcastReceiver
della sveglia. Per eseguire operazioni mentre il dispositivo è in modalità Sospensione, crea una sveglia non esatta utilizzando setAndAllowWhileIdle()
e avvia un job dalla sveglia.
Dichiara l'autorizzazione Sveglia esatta appropriata
Se la tua app ha come target Android 12 o versioni successive, devi ottenere l'accesso speciale per le app "Sveglie e promemoria". A tale scopo, dichiara l'autorizzazione
SCHEDULE_EXACT_ALARM
nel file manifest dell'app, come mostrato nello snippet di codice seguente:
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Se la tua app ha come target Android 13 (livello API 33) o versioni successive, puoi scegliere di:
dichiarare la proprietà SCHEDULE_EXACT_ALARM
o USE_EXACT_ALARM
autorizzazione.
<manifest ...> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Sebbene entrambe le autorizzazioni SCHEDULE_EXACT_ALARM
e USE_EXACT_ALARM
annuncino le stesse funzionalità, vengono concesse in modo diverso e supportano diversi casi d'uso. L'app deve utilizzare sveglie esatte e dichiarare
Autorizzazione SCHEDULE_EXACT_ALARM
o USE_EXACT_ALARM
, solo se rivolta all'utente
nella tua app richiedono azioni temporizzate in modo preciso.
USE_EXACT_ALARM
- Concesso automaticamente
- Non possono essere revocati dall'utente
- Soggetto a una norma di Google Play in arrivo
- Casi d'uso con limitazioni
SCHEDULE_EXACT_ALARM
- Concessa dall'utente
- Un insieme più ampio di casi d'uso
- Le app devono confermare che l'autorizzazione non è stata revocata
L'autorizzazione SCHEDULE_EXACT_ALARM
non viene pre-concessa per le nuove installazioni di app che hanno come target Android 13 (livello API 33) e versioni successive. Se un utente trasferisce l'app
a un dispositivo con Android 14 tramite un'operazione di backup e ripristino,
L'autorizzazione SCHEDULE_EXACT_ALARM
verrà negata sul nuovo dispositivo. Tuttavia, se
un'app esistente dispone già di questa autorizzazione, verrà pre-concessa quando
upgrade dei dispositivi ad Android 14.
Nota: se la sveglia esatta è stata impostata utilizzando un
OnAlarmListener
:
come con
setExact
nell'API, non è richiesta l'autorizzazione SCHEDULE_EXACT_ALARM
.
Utilizzo dell'autorizzazione SCHEDULE_EXACT_ALARM
A differenza di USE_EXACT_ALARM
, l'autorizzazione SCHEDULE_EXACT_ALARM
deve essere
concessi dall'utente. Sia l'utente sia il sistema possono revocare l'autorizzazioneSCHEDULE_EXACT_ALARM
.
Per verificare se l'autorizzazione è stata concessa alla tua app, chiama
canScheduleExactAlarms()
prima di provare a impostare una sveglia esatta. Quando l'autorizzazione SCHEDULE_EXACT_ALARM
viene revocato per la tua app, l'app si interrompe e tutte le sveglie esatte future
vengono annullate. Ciò significa anche che il valore restituito
canScheduleExactAlarms()
rimane valido per l'intero ciclo di vita dell'app.
Quando l'autorizzazione SCHEDULE_EXACT_ALARMS
viene concessa alla tua app, il sistema le invia la trasmissione ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
. L'app deve implementare un ricevitore di trasmissione che svolga le seguenti operazioni:
- Verifica che la tua app abbia ancora accesso speciale per le app. A questo scopo, chiama
canScheduleExactAlarms()
Questo controllo protegge la tua app dal caso in cui l'utente conceda all'app autorizzazione, la revoca quasi immediatamente dopo. - Riprogramma le sveglie esatte di cui ha bisogno la tua app in base al suo stato attuale.
Questa logica dovrebbe essere simile a quella della tua app quando riceve la trasmissione
ACTION_BOOT_COMPLETED
.
Chiedi agli utenti di concedere l'autorizzazione SCHEDULE_EXACT_ALARM
Se necessario, puoi indirizzare gli utenti alla schermata Sveglie e promemoria nelle impostazioni di sistema, come mostrato nella Figura 1. Per farlo, segui questi passaggi:
- Nell'interfaccia utente dell'app, spiega all'utente perché quest'ultima deve programmare sveglie.
- Richiama un'intenzione che includa l'azione di intenzione
ACTION_REQUEST_SCHEDULE_EXACT_ALARM
.
Impostare una sveglia ricorrente
Le sveglie ripetute consentono al sistema di inviare notifiche alla tua app con una frequenza ricorrente.
Un allarme non corretto può causare un consumo eccessivo della batteria e un carico significativo server web. Per questo motivo, su Android 4.4 (livello API 19) e versioni successive, tutte le sveglie ripetute sono sveglie imprecise.
Una sveglia ricorrente ha le seguenti caratteristiche:
Un tipo di sveglia. Per ulteriori discussioni, vedi Scegliere un tipo di sveglia.
Un'ora di attivazione. Se l'ora di attivazione specificata è nel passato, la sveglia si attiva immediatamente.
L'intervallo della sveglia. Ad esempio, una volta al giorno, ogni ora o ogni 5 minuti.
Un intent in attesa che viene attivato quando viene attivata la sveglia. Quando imposti seconda sveglia che utilizza lo stesso intent in sospeso, sostituisce la sveglia originale.
Per annullare un PendingIntent()
, passa
FLAG_NO_CREATE
a PendingIntent.getService()
per ottenere un'istanza dell'intent (se esistente), quindi passa l'intent a
AlarmManager.cancel()
Kotlin
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE) if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent) }
Java
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent); }
Scegli un tipo di sveglia
Una delle prime considerazioni da fare quando si utilizza una sveglia ripetuta è il tipo di sveglia.
Esistono due tipi generali di orologio per le sveglie: "tempo reale trascorso" e "orologio in tempo reale" (RTC). Il tempo reale trascorso utilizza il "tempo dall'avvio del sistema" come riferimento e l'orologio in tempo reale utilizza l'ora UTC (orologio standard). Ciò significa che il tempo reale trascorso è adatto per impostare una sveglia in base al passare del tempo (ad esempio, una sveglia che si attiva ogni 30 secondi) poiché non è influenzato dal fuso orario o dalle impostazioni internazionali. Il tipo di orologio in tempo reale è più adatto alle sveglie che dipendono dalle impostazioni internazionali correnti.
Entrambi i tipi hanno la funzione "sveglia" che indica di riattivare la CPU del dispositivo che lo schermo è spento. In questo modo ti assicuri che l'allarme si attivi all'ora programmata. Questa opzione è utile se la tua app ha una dipendenza dal tempo. Ad esempio, se ha a una finestra limitata per eseguire una determinata operazione. Se non utilizzi la versione di sveglia del tipo di sveglia, tutte le sveglie ripetute verranno attivate al successivo risveglio del dispositivo.
Se vuoi semplicemente che la sveglia si attivi a un determinato intervallo (ad esempio, ogni mezz'ora), utilizza uno dei tipi in tempo reale trascorso. In generale, questo è la scelta migliore.
Se vuoi che la sveglia si attivi in una determinata ora del giorno, scegline una dei tipi di orologio in tempo reale basati sull'orologio. Tieni presente, tuttavia, che questo approccio può avere alcuni svantaggi. L'app potrebbe non essere tradotta bene in altre lingue e, se l'utente modifica l'impostazione dell'ora del dispositivo, potrebbe verificarsi un comportamento imprevisto nell'app. Anche l'utilizzo di un tipo di sveglia con orologio in tempo reale non è scalabile, come discusso sopra. Se puoi, ti consigliamo di utilizzare una sveglia "in tempo reale trascorso".
Ecco l'elenco dei tipi:
ELAPSED_REALTIME
: Attiva l'intent in sospeso in base alla quantità di tempo trascorso da quando il dispositivo è stato si è avviato, ma non riattiva il dispositivo. Il tempo trascorso include il tempo durante il quale il dispositivo era in modalità Sospensione.ELAPSED_REALTIME_WAKEUP
: Consente di riattivare il dispositivo e attivare l'intent in sospeso dopo la durata specificata sia trascorso del tempo dall'avvio del dispositivo.RTC
: attiva l'intent in attesa all'ora specificata, ma non riattiva il dispositivo.RTC_WAKEUP
: riattiva il dispositivo per attivare l'intent in attesa all'ora specificata.
Esempi di sveglie in tempo reale trascorse
Ecco alcuni esempi di utilizzo di ELAPSED_REALTIME_WAKEUP
Attiva il dispositivo per attivare l'allarme dopo 30 minuti, e ogni 30 minuti Dopodiché:
Kotlin
// Hopefully your alarm will have a lower frequency than this! alarmMgr?.setInexactRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent )
Java
// Hopefully your alarm will have a lower frequency than this! alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);
Riattiva il dispositivo per attivare una sveglia una tantum (non ripetuta) tra un minuto:
Kotlin
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } alarmMgr?.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent )
Java
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);
Esempi di sveglie dell'orologio in tempo reale
Ecco alcuni esempi di utilizzo
RTC_WAKEUP
Riattiva il dispositivo per attivare la sveglia alle 14:00 circa e ripeti l'operazione una volta al giorno alla stessa ora:
Kotlin
// Set the alarm to start at approximately 2:00 p.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 14) } // With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr?.setInexactRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent )
Java
// Set the alarm to start at approximately 2:00 p.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 14); // With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
Attiva il dispositivo per attivare l'allarme esattamente alle 8:30 e ogni 20 minuti in seguito:
Kotlin
private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) } // Set the alarm to start at 8:30 a.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 8) set(Calendar.MINUTE, 30) } // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr?.setRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, 1000 * 60 * 20, alarmIntent )
Java
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); // Set the alarm to start at 8:30 a.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 8); calendar.set(Calendar.MINUTE, 30); // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 20, alarmIntent);
Decidi quanto deve essere precisa la sveglia
Come descritto in precedenza, la scelta del tipo di allarme spesso è il primo passo
creare una sveglia. Un'ulteriore distinzione riguarda la precisione della sveglia. Per la maggior parte delle app,
setInexactRepeating()
è la scelta giusta. Se utilizzi questo metodo, Android sincronizza più sveglie e incendi ripetuti inesatti
contemporaneamente. In questo modo si riduce il consumo della batteria.
Se possibile, evita di utilizzare sveglie esatte. Tuttavia, per l'app rara che presenta
requisiti di tempo, puoi impostare una sveglia esatta chiamando
setRepeating()
Con setInexactRepeating()
,
non puoi specificare un intervallo personalizzato come puoi fare con
setRepeating()
.
Devi utilizzare una delle costanti di intervallo, ad esempio
INTERVAL_FIFTEEN_MINUTES
,
INTERVAL_DAY
,
e così via. Per l'elenco completo, visita la pagina AlarmManager
.
Annulla una sveglia
A seconda dell'app, ti consigliamo di includere la possibilità di annullare la sveglia.
Per annullare una sveglia, chiama cancel()
in Alarm Manager, passando il valore
PendingIntent
che non vuoi più attivare. Ad esempio:
Kotlin
// If the alarm has been set, cancel it. alarmMgr?.cancel(alarmIntent)
Java
// If the alarm has been set, cancel it. if (alarmMgr!= null) { alarmMgr.cancel(alarmIntent); }
Avvia una sveglia al riavvio del dispositivo
Per impostazione predefinita, tutte le sveglie vengono annullate quando un dispositivo si spegne.
Per evitare che ciò accada, puoi progettare la tua applicazione
per riavviare automaticamente una sveglia ricorrente se l'utente riavvia il dispositivo. Questo
garantisce che AlarmManager
Continuare a svolgere l’attività senza che l’utente debba riavviare manualmente il rilevatore.
Procedi nel seguente modo:
Imposta la
RECEIVE_BOOT_COMPLETED
nel file manifest dell'applicazione. In questo modo la tua app può ricevereACTION_BOOT_COMPLETED
trasmesso al termine dell'avvio del sistema (funziona solo se è già stata lanciata dall'utente almeno una volta):<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Implementare un modello
BroadcastReceiver
per ricevere la trasmissione:Kotlin
class SampleBootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == "android.intent.action.BOOT_COMPLETED") { // Set the alarm here. } } }
Java
public class SampleBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // Set the alarm here. } } }
Aggiungi il destinatario al file manifest della tua app con un filtro per intent che filtra in base all'azione
ACTION_BOOT_COMPLETED
:<receiver android:name=".SampleBootReceiver" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver>
Nota che nel manifest, il ricevitore di avvio è impostato su
android:enabled="false"
. Ciò significa che il destinatario non verranno chiamati a meno che l'applicazione non lo consenta esplicitamente. In questo modo, il ricevitore di avvio non viene chiamato inutilmente. Puoi attivare un ricevitore (ad esempio se l'utente imposta una sveglia) nel seguente modo:Kotlin
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP )
Java
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Una volta attivato in questo modo, il ricevitore rimarrà attivo anche se l'utente riavvia il dispositivo. In altre parole, abilitare in modo programmatico il ricevitore sostituisce l'impostazione del file manifest, anche tra i riavvii. Il ricevitore rimarrà attivo finché l'app non lo disattiva. Puoi disattivare un ricevitore (ad esempio, se l'utente annulla una sveglia) nel seguente modo:
Kotlin
val receiver = ComponentName(context, SampleBootReceiver::class.java) context.packageManager.setComponentEnabledSetting( receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP )
Java
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Attivare le sveglie quando il dispositivo è in modalità Sospensione
I dispositivi con Android 6.0 (livello API 23) supportano la modalità Sospensione, che consente di prolungare la durata della batteria del dispositivo. Le sveglie non si attivano quando il dispositivo è in carica Modalità Sospensione Tutte le sveglie programmate vengono differite finché il dispositivo non esce dalla modalità Sospensione. Se devi completare un lavoro anche quando il dispositivo è inattivo, hai a disposizione diverse opzioni:
Imposta una sveglia esatta.
Utilizza l'API WorkManager, progettata per eseguire attività in background. Puoi indicare che il sistema deve velocizzare il tuo lavoro in modo che venga completato il prima possibile. Per ulteriori informazioni, vedi Pianificare le attività con WorkManager
Best practice
Ogni scelta che fai nella progettazione di una sveglia ripetuta può avere conseguenze nel modo in cui la tua app usa (o viola) le risorse di sistema. Immagina ad esempio molto conosciuta che si sincronizza con un server. Se l'operazione di sincronizzazione è basata sull'orologio ora e ogni istanza dell'app si sincronizza alle 23.00, il carico potrebbe causare un'elevata latenza o persino "denial of service". Segui queste best practice per l'utilizzo delle sveglie:
Aggiungi casualità (jitter) a tutte le richieste di rete si attiva in seguito a una sveglia ripetuta:
Eseguire qualsiasi operazione locale quando si attiva l'allarme. Per "lavoro locale" si intende qualsiasi attività che non acceda a un server o che non richieda i dati del server.
Allo stesso tempo, pianifica l'attivazione della sveglia contenente le richieste di rete in un periodo di tempo casuale.
Riduci al minimo la frequenza delle sveglie.
Non riattivare il dispositivo inutilmente (questo comportamento è determinato dal tipo di sveglia, come descritto in Scegliere un tipo di sveglia).
Non impostare l'ora di attivazione della sveglia più precisa del necessario.
Utilizza
setInexactRepeating()
invece disetRepeating()
. Quando usisetInexactRepeating()
, Android sincronizza le sveglie ripetute di più app e le attiva contemporaneamente. In questo modo si riduce il numero totale di volte in cui il sistema deve riattivare il dispositivo, riducendo il consumo della batteria. A partire da Android 4.4 (Livello API 19), tutti i rilevatori ripetuti sono sveglia inesatta. Nota mentresetInexactRepeating()
è un miglioramento rispettosetRepeating()
, può comunque sovraccaricare un server se ogni istanza di un'app raggiunge il server all'incirca contemporaneamente. Di conseguenza, per le richieste di rete, aggiungi una certa casualità le sveglie, come spiegato in precedenza.Se possibile, evita di basare la sveglia sull'ora dell'orologio.
Le sveglie ripetute basate su un tempo di attivazione preciso non vengono ridimensionate correttamente. Utilizza le funzionalità di
ELAPSED_REALTIME
se è possibile. Un'altra sveglia descritti più dettagliatamente nella sezione seguente.