
I’ve seen people having trouble with scheduling notifications in Xamarin.Android using the Java.Util.Calendar so I made a sample project on Github. Basically the main problem was using ElapsedRealtime instead of Rtc.
This app will start the notifications at a specified time and will repeat them every minute, even if the devices is rebooted.
1 2 3 4 5 6 7 |
Intent alarmIntent = new Intent(this, typeof(AlarmReceiver)); PendingIntent pending = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); AlarmManager alarmManager = GetSystemService(AlarmService).JavaCast<AlarmManager>(); //AlarmType.RtcWakeup – it will fire up the pending intent at a specified time, waking up the device alarmManager.SetRepeating(AlarmType.RtcWakeup, BootReceiver.FirstReminder(), BootReceiver.reminderInterval, pending); PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, 0); |
In MainActivity we create an Intent with the type of AlarmReceiver(see bellow).
For the alarm type we chose RTC which fires up the pending intent at a specified time. Here are other types:
- ELAPSED_REALTIME—Fires the pending intent based on the amount of time since the device was booted, but doesn’t wake up the device. The elapsed time includes any time during which the device was asleep.
- ELAPSED_REALTIME_WAKEUP—Wakes up the device and fires the pending intent after the specified length of time has elapsed since device boot.
- RTC—Fires the pending intent at the specified time but does not wake up the device.
- RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time.
Source: https://developer.android.com/training/scheduling/alarms.html#set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[BroadcastReceiver] [IntentFilter(new[] { Intent.ActionBootCompleted })] public class BootReceiver : BroadcastReceiver { //the interval currently every one minute //to set it to dayly change the value to 24 * 60 * 60 * 1000 public static long reminderInterval = 60 * 1000; public static long FirstReminder() { Java.Util.Calendar calendar = Java.Util.Calendar.Instance; calendar.Set(Java.Util.CalendarField.HourOfDay, 20); calendar.Set(Java.Util.CalendarField.Minute, 06); calendar.Set(Java.Util.CalendarField.Second, 00); return calendar.TimeInMillis; } public override void OnReceive(Context context, Intent intent) { Console.WriteLine("BootReceiver: OnReceive"); var alarmIntent = new Intent(context, typeof(AlarmReceiver)); var pending = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); AlarmManager alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService); alarmManager.SetRepeating(AlarmType.RtcWakeup, FirstReminder(), reminderInterval, pending); PendingIntent pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, 0); } } |
The FirstReminder method returns our the trigger time in milliseconds.
If you don’t want want to use a schedule and want to trigger your notification after a certain amount of time, you need to use ElapsedRealtime. Here is a sample code on how to do it:
1 |
alarmManager.setRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 15 * 60 * 1000, 15 * 60 * 1000, pendingIntent); |