Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cater the list of scheduled time in an Alarm Manager to push notifications

I am trying to retrieve the list of time stored in Sqlite (it has both hours and minutes) into the alarm manager to perform a reminder via a notification. My approach was to loop all the scheduled time stored in Sqlite into the alarm manager to perform notifications basing on the list of time stored,but the notification doesn't beep.

But when i specify one time (hour and minute) it works . Below is the code sample which works, but i don't want this:

alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 45);
Intent myIntent = new Intent(ListRemainder.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(ListRemainder.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);

But when it comes to loop several time schedules it doesn't work,and it's the approach i want, below is the code sample,what am i missing?

//listOfTime is the one which contains the list of stored scheduled time in Sqlite.
for (int i = 0; i < listOfTime.size(); i++) {
    int hour = Integer.parseInt(listOfTime.get(i).toString().substring(0, 2));
    int minute = Integer.parseInt(listOfTime.get(i).toString().substring(3));
    System.out.print("Hour : " + hour + " Minute : " + minute);
    Log.d("MyActivity", "Alarm On");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    Intent myIntent = new Intent(ListRemainder.this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(ListRemainder.this, 0, myIntent, 0);
    alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
like image 279
Lutaaya Huzaifah Idris Avatar asked Nov 08 '22 07:11

Lutaaya Huzaifah Idris


1 Answers

The prototype for getBroadcast looks like:

getBroadcast(Context context, int requestCode, Intent intent, int flags)

Setting a unique 'requestCode' for each PendingIntent should allow for the scheduling of multiple alarms:

PendingIntent.getBroadcast(context, uniqueValue, intent, PendingIntent.FLAG_UPDATE_CURRENT);

For guaranteed wake-up for user critical alarms:

void setAlarmClock (AlarmManager.AlarmClockInfo info, 
            PendingIntent operation)

From the Docs: "Schedule an alarm that represents an alarm clock, which will be used to notify the user when it goes off. The expectation is that when this alarm triggers, the application will further wake up the device to tell the user about the alarm -- turning on the screen, playing a sound, vibrating, etc. As such, the system will typically also use the information supplied here to tell the user about this upcoming alarm if appropriate.

Due to the nature of this kind of alarm, similar to setExactAndAllowWhileIdle(int, long, PendingIntent), these alarms will be allowed to trigger even if the system is in a low-power idle (a.k.a. doze) mode."

To summarise:

  • Use setAlarmClock to wakeup the device to present info to the user.
  • Use setExactAndAllowWhileIdle to do work in the background that must be done during doze. However, the firing of these alarms may be subject to delays ranging from 1 minute to 15 minutes roughly.
  • Use FCM to wake up the device in real time from a remote application. In practise, many apps should use FCM instead of setExactAndAllowWhileIdle if possible.
  • Use setExact if exact syncing during doze is not important. Also, use setExact on pre-API 21 devices instead of setAlarmClock or setExactAndAllowWhileIdle...

Lutaaya's final solution:

AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(),pendingIntent), pendingIntent);
like image 97
Elletlar Avatar answered Nov 14 '22 21:11

Elletlar