studio - best alarm app android 2018
Alarm Manager-Programación de múltiples eventos no repetitivos (2)
En el Administrador de alarmas de Android, ¿cómo podemos programar múltiples alarmas que no se repiten y no tienen 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 los tiempos de alarma almacenados en la tabla de la base de datos de Sqlite y la actividad debe seleccionar la fecha y la hora de esta tabla y configurar las alarmas.
Si configuramos diferentes alarmas en un bucle, entonces solo retiene la última. Leí el post: ¿Cómo puedo crear más de una alarma?
Le indica que adjunte la identificación única a la intención y luego configure los eventos de alarma individuales. Pero no funcionó para mí.
¿Hay algo que necesitamos agregar en el archivo Manifest para encargarnos de esta identificación única?
El código en la actividad ''RegularSchedule'' es y crea solo 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, avíseme si se requieren 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>
RepetirAlarma:
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);
Como se sugiere en @Jonathon Horsman, asegúrate de que los intentos que estás creando sean únicos.
Si quieres 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í.
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 otra información para aclarar la tecnicidad de la solución y por qué ciertas cosas funcionan y otras no :)
(1) En primer lugar, archivo Manifest: asegúrese de tener un receptor para su clase con 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 está en algún subpaquete, muévase al paquete principal. El paquete principal es lo que define en la etiqueta ''manifest''.
''intent-filter'' se utiliza para definir ''acción'' y ''datos''. Puede colocar la clase de actividad aquí, que se llamará desde su intento pendiente. Pero descubrí que si define "acción" en el manifiesto, no muestra valores dinámicos en la actividad. Solo muestra valores estáticos. Bastante extraño. Si tiene el mismo problema, no ponga "acción" en el manifiesto, sino póngalo en la clase BroadcastReceiver como parte de la intención pendiente.
La etiqueta ''datos'' es lo que colocará URI dinámico de intentos únicos al programar diferentes alarmas utilizando AlarmManager. Por favor, consulte los siguientes pasos para más detalles.
(2) Clase de actividad en la que va a utilizar AlarmManager para programar alarmas: estoy usando la base de datos para almacenar los valores de la hora de mi alarma y luego programar usando esos valores. Mi cursor recupera el _ID único de la tabla y la hora de la alarma (en segundos desde el 1/1/1970). Verifique que el URI que se pone aquí sea igual al que tiene en el 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, verifique la zona horaria que toma el emulador. A veces, programamos la zona horaria local, pero las programaciones del emulador para la zona horaria GMT. Si te fijas en el mensaje de brindis, eso te ayudará a resolver este problema.
(3) El último es la clase BroadcastReceiver. Tenga en cuenta que para abrir la base de datos, deberá usar 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, la ID de la solicitud se puede pasar como única al llamar a Notify ().
Finalmente, puede crear la clase DisplayReminder a la que desea llamar cuando el usuario haga clic en la notificación.