Cómo configurar AlarmManager recurrente para ejecutar código diario

Actualmente estoy tratando de escribir el administrador de alarmas que hará que una alarma se apague dentro de un período específico de tiempo, todos los días. Primero compruebo si el usuario ha configurado una alarma para ese día:

if ((User.getReminderTime(Home.this) > 0) && (dt.getDate() != today.getDate() || dt.getDay() != today .getDay())) { AppointmentManager.setFutureAppointmentCheck(this .getApplicationContext()); User.setLongSetting(this, "futureappts", today.getTime()); } 

Entonces voy y pongo la alarma real para ir apagado entre 12 y 12:10 del día siguiente:

  public static void setFutureAppointmentCheck(Context con) { AlarmManager am = (AlarmManager) con .getSystemService(Context.ALARM_SERVICE); Date futureDate = new Date(new Date().getTime() + 86400000); Random generator = new Random(); futureDate.setHours(0); futureDate.setMinutes(generator.nextInt(10)); futureDate.setSeconds(0); Intent intent = new Intent(con, FutureAppointmentReciever.class); PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, PendingIntent.FLAG_ONE_SHOT); am.set(AlarmManager.RTC_WAKEUP, futureDate.getTime(), sender); } 

Ahora configuro un entorno de prueba para que esto se dispare cada dos minutos y parece que funciona bien, sin embargo, cuando me despliego en un dispositivo real, el receptor no parece estar recibiendo las alarmas. Pensé que podría ser un problema con el dispositivo de estar dormido, por lo que agregó el administrador de energía. Pero todavía no funciona:

  PowerManager pm = (PowerManager) context .getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "keepAlive"); wl.acquire(); setFutureAppointments(context.getApplicationContext()); AppointmentManager.setFutureAppointmentCheck(context .getApplicationContext()); User.setLongSetting(context.getApplicationContext(), "futureappts", new Date().getTime()); wl.release(); 

¿Alguien ve algo que estoy haciendo descaradamente mal o estoy haciendo esto incorrectamente? Gracias por cualquier y toda la ayuda.

Normalmente hago algo más en las líneas de:

 Intent i = new Intent(this, MyService.class); PendingIntent pi = PendingIntent.getService(this, 0, i, 0); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); am.cancel(pi); // cancel any existing alarms am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY, pi); 

De esta manera, no tiene que preocuparse por volver a configurar AlarmManager en su Service .

Normalmente ejecuto este bit de código cuando se inicia mi aplicación ( onResume en mi actividad principal) y en un BroadcastReceiver configurado para recibir BOOT_COMPLETED .

He escrito una guía sobre la creación de Service y el uso de AlarmManager , que se basa en mi propia experiencia y algunos consejos y trucos que elegí de ver una charla de E / S de Google. Si está interesado, puede leerlo aquí .


Para responder a su pregunta a continuación, todo lo que puedo hacer es citar los documentos :

 public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation) 

Programe una alarma de repetición que tenga requisitos inexact del tiempo del disparador; Por ejemplo, una alarma que se repite cada hora, pero no necesariamente en la parte superior de cada hora. Estas alarmas son más eficientes en energía que las repeticiones estrictas suministradas por setRepeating (int, long, long, PendingIntent), ya que el sistema puede ajustar la fase de las alarmas para hacerlas disparar simultáneamente, evitando despertar el dispositivo del sueño más de lo necesario.

El primer disparo de su alarma no se realizará antes de la hora solicitada, pero puede no ocurrir durante casi un intervalo completo después de ese tiempo. Además, mientras que el periodo total de la alarma de repetición será como se solicitó, el tiempo entre dos disparos sucesivos de la alarma puede variar. Si su aplicación exige una fluctuación de fase muy baja, utilice setRepeating (int, long, long, PendingIntent).

En conclusión, no está muy claro. Los docs sólo dicen que la alarma "puede variar". Sin embargo, debe ser importante que sepa que el primer desencadenador puede no ocurrir durante casi un intervalo completo después de ese tiempo .

Esto está trabajando, esto disparará alarma cada 5 segundos

 private void setRecurringAlarm() { Logger.d(IConstants.DEBUGTAG, "Setting Recurring Alarm"); Calendar updateTime = Calendar.getInstance(); updateTime.set(Calendar.SECOND, 5); Intent alarmIntent = new Intent(this, AlarmReceiver.class); PendingIntent recurringDownload = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarms.cancel(recurringDownload); alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 1000 * 5, recurringDownload); //will run it after every 5 seconds. } 
  • Android: Vibrar de acuerdo con la selección seleccionada en Ajustes de sonido> General
  • ¿Cómo crear notificaciones que no desaparecen cuando se hace clic en Android?
  • Cómo agregar indicadores a una notificación (notificación de barra de estado)?
  • Creación de una notificación de insignia similar a la del iPhone en Android
  • Cómo parpadear icono de notificación en android?
  • Los botones de notificación no funcionan
  • ¿Cuáles son los tamaños de los iconos en los botones de acción de notificaciones de Android?
  • El LED de notificación de Android no utiliza mi color
  • Mostrar una alerta o una vista al recibir una notificación
  • Pérdida de memoria android en el servicio de notificación
  • Notificación llevar la aplicación al frente sin actividad de cambio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.