Notificación de repetición diaria de Android en el momento específico de un día mediante AlarmManager

Necesito que la aplicación de Android envíe una notificación para recordar a los usuarios a las 8am, 3pm y 8pm todos los días. Así que utilizo las tres líneas siguientes en onCreate () de MainActivity, cuando se inicia la aplicación. Sin embargo, cuando ejecuto la aplicación, las tres notificaciones están llegando de una vez en vez de en el momento deseado.

setRepeatedNotification(1,8,0,0); setRepeatedNotification(2,15,0,0); setRepeatedNotification(3,20,0,0); 

¿Porqué es eso? También adjunto la función setRepeatedNotification aquí. ¡Gracias!

 private void setRepeatedNotification(int ID, int hh, int mm, int ss) { AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ID, alarmIntent, 0); Calendar calendar = Calendar.getInstance(); // calendar.set(); calendar.set(Calendar.HOUR_OF_DAY, hh); calendar.set(Calendar.MINUTE, mm); calendar.set(Calendar.SECOND, ss); // Clear previous everyday pending intent if exists. if (null != mEverydayPendingIntent) { alarmManager.cancel(mEverydayPendingIntent); } mEverydayPendingIntent = pendingIntent; alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent); } 

Veo dos posibles problemas con su configuración con AlarmManager. La primera surge cuando el dispositivo se va a dormir.

De la documentación de AlarmManager:

Si una alarma se retrasa (por ejemplo, para los tipos de alarma no _WAKEUP), se realizará una repetición omitida tan pronto como sea posible. Después de eso, las alarmas futuras serán entregadas según el horario original; No se deriva con el tiempo. Por ejemplo, si ha configurado una alarma recurrente para la parte superior de cada hora, pero el teléfono estaba dormido entre las 7:45 y las 8:45, se enviará una alarma tan pronto como se despierte el teléfono y la siguiente alarma se enviará al 9:00.

Como puede ver, si ha configurado una alarma y el dispositivo se ha AlarmManager.RTC_WAKEUP , sin utilizar AlarmManager.RTC_WAKEUP , podría haber un retardo largo dependiendo de cuánto tiempo haya estado el dispositivo en suspensión. Si nunca ha tocado su dispositivo y ninguna otra alarma ha provocado una activación, podría provocar que todas las alarmas se acumulen en la siguiente hora para la que el dispositivo está despierto.


Otro problema potencial que veo es que está recuperando una instancia de Calendar que representa el momento en este momento, pero luego establecer la hora, minuto y segundo por sí mismo. El día actual y el año actual se han completado automáticamente desde la hora actual.

Una vez más, de la documentación (énfasis mío):

Si el tiempo de activación indicado es anterior, la alarma se disparará inmediatamente , con un recuento de alarmas dependiendo de cuánto tiempo en el pasado el tiempo de activación es relativo al intervalo de repetición.

En este caso, si su método se invocó después de las 8 pm del día dado, calendar.getTimeInMillis() devolverá una marca de tiempo en el pasado para las tres alarmas, provocando que se activen de inmediato desde las 8 am, 3 pm y 8 pm. ya pasado en ese día. En este caso, primero debe evaluar si la hora actual supera el intervalo de alarma que está intentando establecer y agregar 1 día más al tiempo que está configurando para asegurarse de que la alarma se ha configurado en el futuro.

Aquí está el código actualizado:

 private void setRepeatedNotification(int ID, int hh, int mm, int ss) { AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); Intent alarmIntent = new Intent(StartActivity.this, AlarmReceiver.class); alarmIntent.putExtra("ID",ID); Log.d("setRepeatedNotification", "ID:" + ID); PendingIntent pendingIntent = PendingIntent.getBroadcast(StartActivity.this, ID, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); Calendar calendar = Calendar.getInstance(); Calendar now = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, hh); calendar.set(Calendar.MINUTE, mm); calendar.set(Calendar.SECOND, ss); //check whether the time is earlier than current time. If so, set it to tomorrow. Otherwise, all alarms for earlier time will fire if(calendar.before(now)){ calendar.add(Calendar.DATE, 1); } mEverydayPendingIntent = pendingIntent; alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent); } 
  • Ejemplo del Administrador de alarmas
  • OnReceiver de BroadcastReceiver no llamado, AlarmManager
  • Android alarmManager setRepetición no desencadenar
  • Android alarmmanager no es muy confiable
  • ¿Cómo se inicia una Actividad con AlarmManager en Android?
  • Administrador de alarmas en android
  • ¿Android AlarmManager controla los cambios de horario de verano?
  • Java.lang.SecurityException:! @Too muchas alarmas (500) registradas de pid 10790 uid 10206
  • Cancelar un AlarmManager pendienteIntent en otro pendienteintent
  • ¿Utilizar el Administrador de alarmas incluso si la aplicación está cerrada?
  • ¿Cómo puedo configurar un administrador de alarmas para disparar cada día específico de la semana y el tiempo en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.