Android: cómo utilizar AlarmManager

89

Necesito activar un bloque de código después de 20 minutos desde que AlarmManagerse configuró.

¿Alguien me puede mostrar un código de muestra sobre cómo usar un AlarmManagerin ِ Android?

He estado jugando con un código durante unos días y simplemente no funciona.

Tom
fuente

Respuestas:

109

"Un código de muestra" no es tan fácil cuando se trata de AlarmManager.

Aquí hay un fragmento que muestra la configuración de 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);

En este ejemplo, estoy usando setRepeating(). Si desea una alarma de un disparo, simplemente use set(). Asegúrese de dar la hora para que la alarma comience en la misma base de tiempo que usa en el parámetro inicial set(). En mi ejemplo anterior, estoy usando AlarmManager.ELAPSED_REALTIME_WAKEUP, por lo que mi base de tiempo es SystemClock.elapsedRealtime().

Aquí hay un proyecto de muestra más grande que muestra esta técnica.

CommonsWare
fuente
2
Hola de nuevo. Gracias por la respuesta. Si compro su libro, ¿me explica cómo implementar un administrador de alarmas con todo detalle?
Tom
7
El libro de Android avanzado (versión 0.9) tiene ~ 9 páginas que cubren AlarmManager, WakeLocks y el resto de ese ejemplo. Eso probablemente se expandirá ligeramente en la Versión 1.0 a medida que haga la corrección que mencioné en mi respuesta anterior. Y si tiene preguntas sobre el libro o su código de muestra, vaya a groups.google.com/group/cw-android y estaré encantado de responderlas.
CommonsWare
17
Cualquier desarrollador de Android debería tener una suscripción a los libros de Mark :) Al menos una vez
Bostone
1
@ MarioGalván: Debes configurarlo cuando tu aplicación se ejecuta por primera vez y en un reinicio.
CommonsWare
Creo que deberías usar AlarmManager.RTC_WAKEUP si quieres que se active de inmediato y luego cada PERIODO. En su código, se activará después de SystemClock.elapsedRealtime () y luego cada PERIODO.
Damon Yuan
66

Hay algunos buenos ejemplos en el código de muestra de Android

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

Los que debes revisar son:

  • AlarmController.java
  • OneShotAlarm.java

En primer lugar, necesita un receptor, algo que pueda escuchar su alarma cuando se activa. Agregue lo siguiente a su archivo AndroidManifest.xml

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

Luego, crea la siguiente clase

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

Luego, para activar una alarma, utilice lo siguiente (por ejemplo, en su actividad principal):

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, mejor aún, crea una clase que lo maneje todo y úsala así

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

de esta manera, lo tienes todo en un solo lugar (no olvides editar el 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();
     }
}
Defecto
fuente
2
¡Hola! Probé este código y funcionó bien (+1). pero probé esto para múltiples alarmas (como una por 10 segundos y otra por 15, y solo la segunda se dispara. ¿Estoy haciendo algo mal o es un problema importante? EDITAR: Ok, encontré el problema aquí : stackoverflow.com/questions/2844274/…
Nuno Gonçalves
FWIW, usaría un método estático en lugar de un constructor para esto.
Edward Falk
9

Lo que debe hacer primero es crear la intención que necesita programar. A continuación, obtenga la intención pendiente de esa intención. Puede programar actividades, servicios y retransmisiones. Para programar una actividad, por ejemplo, MyActivity:

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

Dé este pendienteIntent 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);

Ahora MyActivity se iniciará después de 5 segundos del inicio de la aplicación, no importa si detiene su aplicación o el dispositivo entró en estado de suspensión (debido a la opción RTC_WAKEUP). Puede leer el código de ejemplo completo Programación de actividades, servicios y transmisiones #Android

SohailAziz
fuente
+1 gran respuesta, exactamente lo que necesitaba, un ejemplo funcional de 'conjunto'.
A.Alqadomi
4

Quería comentar pero <50 repeticiones, así que aquí va. Recordatorio amistoso de que si está ejecutando en 5.1 o superior y usa un intervalo de menos de un minuto, esto sucede:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Vea aquí .

kurt
fuente
3

Algún código de muestra cuando desee llamar a un servicio desde 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);

No tiene que pedir permisos de usuario.

La empresa publicitaria digital
fuente
Una abreviatura muy común.
Phantômaxx
0

Un AlarmManager se utiliza para activar algún código en un momento específico.

Para iniciar un administrador de alarmas, primero debe obtener la instancia del sistema. Luego pase el PendingIntent que se ejecutará en un momento futuro que especifique

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);

Debe tener cuidado al usar el Administrador de alarmas. Normalmente, un administrador de alarmas no puede repetir antes de un minuto. También en modo de bajo consumo, la duración puede aumentar hasta 15 minutos.

Faxriddin Abdullayev
fuente