Administrador de alarmas – Programación de varios eventos no repetitivos

En Android Alarm Manager, ¿cómo podemos programar varias alarmas que no sean repetitivas y que no tengan intervalos fijos para repetir? No puedo usar la función 'setRepeating', ya que las alarmas no tienen ningún patrón de repetición.

Tengo las horas de la alarma almacenadas en la tabla de la base de datos de Sqlite y la actividad debe escoger la fecha y la hora de esta tabla y fijar las alarmas.

Si configuramos diferentes alarmas en un bucle, entonces sólo retiene la última. Leí de la publicación: ¿Cómo puedo crear más de una alarma?

Indica que debe adjuntar el Id único a la intención y luego configurar eventos de alarma individuales. Pero no funcionó para mí.

¿Hay algo que necesitamos agregar en el archivo Manifest para cuidar este identificador único?

El código de la actividad 'RegularSchedule' es y sólo crea un evento de alarma:

while (notifCursor.moveToNext()) { Intent intent = new Intent(RegularSchedule.this, RepeatingAlarm.class); // The cursor returns first column as unique ID intent.setData(Uri.parse("timer:" + notifCursor.getInt(0))); PendingIntent sender = PendingIntent.getBroadcast( RegularSchedule.this, 0, intent, 0); // Setting time in milliseconds taken from database table cal.setTimeInMillis(notifCursor.getLong(1)); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); } 

Por favor, hágamelo saber si se necesitan más detalles o fragmentos de código.

Archivo de manifiesto (aquí RepeatingAlarm extiende BroadcastReceiver):

  <receiver android:name=".user_alerts.RepeatingAlarm" android:process=":remote" /> <activity android:name=".user_alerts.RegularSchedule" android:label="@string/reg_schedule_title" android:theme="@android:style/Theme.Light"> </activity> 

RepeatingAlarm:

 public class RepeatingAlarm extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); ....... // The PendingIntent to launch our activity if the user selects this notification Intent notificationIntent = new Intent (context, DisplayReminder.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); notification.defaults |= Notification.DEFAULT_SOUND; notification.defaults |= Notification.DEFAULT_VIBRATE; notification.defaults |= Notification.DEFAULT_LIGHTS; mNotificationManager.notify(2425, notification); 

Esto es lo que funcionó para mí. Estoy compartiendo la solución para que otros puedan beneficiarse y encontrar una solución rápida a este problema.

Doy la bienvenida a cualquier otro aporte para arrojar más luz sobre el tecnicismo de la solución y por qué ciertas cosas funcionan y otras no 🙂

(1) En primer lugar, archivo de manifiesto: Asegúrese de que tiene receptor para su clase teniendo BroadcastReceiver.

  <receiver android:name=".RepeatingAlarm" android:process=":remote"> <intent-filter> <data android:scheme="timer:" /> </intent-filter> </receiver> 

Tenga en cuenta que la clase es parte del paquete principal. Si se encuentra en algún subpaquete, vaya al paquete principal. El paquete principal es lo que define en la etiqueta 'manifesto'.

'Intención-filtro' se utiliza para definir 'acción' y 'datos'. Puede poner aquí la clase de actividad que se va a llamar de su intención pendiente. Pero encontré que si define 'acción' en manifesto, no muestra valores dinámicos en la actividad. Simplemente muestra valores estáticos. Bastante extraño. Si usted consigue en la misma edición, no ponga la "acción" en el manifiesto, sino que lo puso en la clase BroadcastReceiver como parte de la intención pendiente.

'Data' es lo que vas a poner URI dinámico de intentos únicos mientras programa diferentes alarmas usando AlarmManager. Consulte los pasos siguientes para obtener más detalles.

(2) Clase de actividad en la que va a utilizar AlarmManager para programar las alarmas: Estoy utilizando la base de datos para almacenar los valores de mi hora de alarma y programar utilizando esos valores. Mi cursor recupera el _ID único de la tabla y la hora de la alarma (en segundos desde 1/1/1970). Vea que el URI puesto aquí es igual que lo que tiene en archivo de manifiesto.

  Calendar cal = Calendar.getInstance(); int notifIterator = 0; if (notifCursor.getCount() > 0) { while (notifCursor.moveToNext()) { Intent intent = new Intent(MySchedule.this, RepeatingAlarm.class); // As the same intent cancels the previously set alarm having // same intent // changing the intent for every alarm event so that every alarm // gets // scheduled properly. intent.setData(Uri.parse("timer:" + notifCursor.getInt(0))); PendingIntent sender = PendingIntent.getBroadcast( MySchedule.this, 0, intent, Intent.FLAG_GRANT_READ_URI_PERMISSION); cal.setTimeInMillis(notifCursor.getLong(1) * 1000); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); notifIterator++; Toast mToast = Toast.makeText( RegularSchedule.this, "Reminders added to the calendar successfully for " + android.text.format.DateFormat.format( "MM/dd/yy h:mmaa", cal.getTimeInMillis()), Toast.LENGTH_LONG); mToast.show(); } } 

Si no ve las alarmas incluso después de hacer esto, compruebe el huso horario que el emulador toma. A veces, programamos horarios locales, pero los horarios del emulador para el huso horario GMT. Si usted mira el mensaje de la tostada, que le ayudará a resolver este problema.

(3) El último es la clase BroadcastReceiver. Tenga en cuenta que para abrir la base de datos, tendrá que utilizar el contexto:

 public void onReceive(Context context, Intent intent) { // Update the status in the notification database table int notificationId = Integer.parseInt(intent.getData().getSchemeSpecificPart()); db = context.openOrCreateDatabase(DATABASE_NAME, SQLiteDatabase.CREATE_IF_NECESSARY, null); <<<< Do DB stuff like fetching or updating something>>>> // Raise the notification so that user can check the details NotificationManager mNotificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); int icon = R.drawable.icon; CharSequence tickerText = "your text"; long when = System.currentTimeMillis(); Notification notification = new Notification(icon, tickerText, when); // Count of number of notifications notification.number = notifCount; CharSequence contentTitle = "your title "; CharSequence contentText = "your notification text"; // The PendingIntent to launch our activity if the user selects this // notification Intent notificationIntent = new Intent(context, DisplayReminder.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); notification.defaults |= Notification.DEFAULT_SOUND; notification.defaults |= Notification.DEFAULT_VIBRATE; notification.defaults |= Notification.DEFAULT_LIGHTS; // Instead of 1234 or any other number, use below expression to have unique notifications // Integer.parseInt(intent.getData().getSchemeSpecificPart()) mNotificationManager.notify(1234, notification); } 

Tenga en cuenta que si desea crear una notificación por separado, el identificador de solicitud se puede pasar como único al llamar a notify ().

Por último, puede crear la clase DisplayReminder a la que desea llamar cuando el usuario haga clic en la notificación.

Como se sugiere @Jonathon Horsman, asegúrese de que las intenciones que está creando son únicas.

Si desea configurar 10 alarmas, por ejemplo:

 for(int i=; i<10; i++) { Intent intent = new Intent(YourActivity.this, YourAlarm.class); intent.setData(Uri.parse("timer:" + i); PendingIntent sender = PendingIntent.getBroadcast( YourActivity.this, 0, intent, Intent.FLAG_GRANT_READ_URI_PERMISSION); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, yourTimeInMillis, sender); } 

Funcionó bien para mí.

  • AlarmManager.RTC_WAKEUP no funciona para algunos dispositivos
  • La función "Optimización de aplicaciones" de Samsung mata aplicaciones de fondo después de 3 días
  • ¿Por qué Android está ignorando la creación de la Notificación?
  • Detectar alarmas predeterminadas de la aplicación del reloj despertador
  • Alarma de repetición para días específicos de la semana en Android
  • Actualizando la alarma de la intención pendiente en android
  • ¿Alarm Manager persiste incluso después del reinicio?
  • Problema con el Administrador de alarmas en Android 6.0 Doze mode
  • Cómo configurar Alarma para días laborables en android
  • ¿Cómo ejecutar un servicio de 9 AM a 4 PM todos los días?
  • ¿Utilizar un receptor de difusión para iniciar AlarmManager en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.