Android: come utilizzare AlarmManager


89

Devo attivare un blocco di codice dopo 20 minuti dall'impostazione AlarmManager.

Qualcuno può mostrarmi un codice di esempio su come utilizzare un AlarmManagerin ِ Android?

Sto giocando con un po 'di codice per alcuni giorni e semplicemente non funzionerà.

Risposte:


109

"Alcuni esempi di codice" non è così facile quando si tratta di AlarmManager.

Ecco uno snippet che mostra la configurazione di AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

In questo esempio, sto usando setRepeating(). Se vuoi un allarme one-shot, devi solo usare set(). Assicurati di dare l'ora di inizio dell'allarme nella stessa base di tempo che usi nel parametro iniziale a set(). Nel mio esempio sopra, sto usando AlarmManager.ELAPSED_REALTIME_WAKEUP, quindi la mia base dei tempi è SystemClock.elapsedRealtime().

Ecco un progetto di esempio più ampio che mostra questa tecnica.


2
Ciao di nuovo. Grazie per la risposta. Se acquisto il tuo libro mi spiega come implementare in dettaglio un gestore di allarmi?
Tom

7
Il libro Advanced Android (versione 0.9) ha ~ 9 pagine che trattano AlarmManager, WakeLocks e il resto di quell'esempio. Probabilmente si espanderà leggermente nella versione 1.0 mentre apporto la correzione che ho menzionato nella mia risposta sopra. E se hai domande sul libro o sul suo codice di esempio, passa a groups.google.com/group/cw-android e sarò felice di risponderti.
CommonsWare

17
Qualsiasi sviluppatore Android dovrebbe avere un abbonamento ai libri di Mark :) Almeno una volta
Bostone

1
@ MarioGalván: Devi impostarlo quando la tua app viene eseguita per la prima volta e al riavvio.
CommonsWare

Penso che dovresti usare AlarmManager.RTC_WAKEUP se vuoi che si attivi subito e poi ogni PERIODO. Nel codice, verrà attivato dopo SystemClock.elapsedRealtime () e quindi ogni PERIOD.
Damon Yuan

66

Ci sono alcuni buoni esempi nel codice di esempio Android

. \ android-sdk \ samples \ android-10 \ ApiDemos \ src \ com \ example \ android \ apis \ app

Quelli da controllare sono:

  • AlarmController.java
  • OneShotAlarm.java

Prima di tutto, hai bisogno di un ricevitore, qualcosa che possa ascoltare il tuo allarme quando viene attivato. Aggiungi quanto segue al tuo file AndroidManifest.xml

<receiver android:name=".MyAlarmReceiver" />

Quindi, crea la seguente classe

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Quindi, per attivare un allarme, utilizza quanto segue (ad esempio nella tua attività principale):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


O, meglio ancora, crea una classe che gestisca tutto e usala in questo modo

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

in questo modo, hai tutto in un unico posto (non dimenticare di modificare il AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

2
Ciao! Ho provato questo codice e peggiora bene (+1). ma l'ho provato per più allarmi (come uno per 10 secondi e un altro per 15, e viene attivato solo il secondo. Sto facendo qualcosa di sbagliato o è un re dei problemi? EDIT: Ok, ho trovato il problema qui : stackoverflow.com/questions/2844274/…
Nuno Gonçalves

FWIW, userei un metodo statico piuttosto che un costruttore per questo.
Edward Falk

9

Quello che devi fare è prima creare l'intento che devi pianificare. Quindi ottenere il pendingIntent di quell'intento. È possibile programmare attività, servizi e trasmissioni. Per programmare un'attività, ad esempio MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Dai questo pendingIntent a alarmManager:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Ora MyActivity verrà avviato dopo 5 secondi dall'avvio dell'applicazione, indipendentemente dall'arresto dell'applicazione o dal dispositivo in stato di sospensione (a causa dell'opzione RTC_WAKEUP). Puoi leggere il codice di esempio completo Pianificazione attività, servizi e trasmissioni #Android


+1 ottima risposta, esattamente quello di cui avevo bisogno, un esempio di "set" funzionante.
A. Alqadomi

4

Volevo commentare ma <50 rep, quindi ecco qui. Promemoria amichevole che se stai utilizzando 5.1 o versioni successive e utilizzi un intervallo inferiore a un minuto, questo accade:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Vedi qui .


3

Alcuni esempi di codice quando si desidera chiamare un servizio da Alarmmanager:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

Non è necessario chiedere l'autorizzazione all'utente.


Un'abbreviazione molto comune.
Phantômaxx

0

Un AlarmManager viene utilizzato per attivare un codice in un momento specifico.

Per avviare un Gestore allarmi è necessario prima ottenere l'istanza dal sistema. Quindi passare il PendingIntent che verrà eseguito in un momento futuro specificato

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

È necessario fare attenzione durante l'utilizzo di Alarm Manager. Normalmente, un gestore di allarmi non può ripetere prima di un minuto. Anche in modalità a basso consumo, la durata può aumentare fino a 15 minuti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.