Some tasks need to be performed at a particular time in the future, some may even be required to recur.
We can schedule tasks for the future using the AlarmManager
instance:
[assembly: UsesPermission(Manifest.Permission.SetAlarm)]
[BroadcastReceiver] [IntentFilter(new[] { "xamarincookbook.Alarm" })] public class AlarmReceiver : BroadcastReceiver { public override void OnReceive( Context context, Intent intent) { // alarm has triggered } }
var ringTime = JavaSystem.CurrentTimeMillis() + (long)TimeSpan.FromSeconds(5).TotalMilliseconds; var intent = new Intent("xamarincookbook.Alarm"); var alarm = PendingIntent.GetBroadcast(this, 0, intent, 0); var manager = AlarmManager.FromContext(this); manager.Set(AlarmType.RtcWakeup, ringTime, alarm);
Sometimes, there is a need for a specific task to be performed after an interval, either once or repeatedly. This may be to check for data updates or to synchronize settings. To create a task that will execute later in the future, we use the AlarmManager
instance.
Before we can use the AlarmManager
instance, we need to request the SetAlarm
permission. Next, we create a broadcast receiver that will be used to receive an intent once the alarm is triggered. The intent action that we specify in the intent filter is the action that will be broadcast once the alarm is triggered.
In order to schedule an alarm, we have to first obtain an instance of the manager using the static FromContext()
method on the AlarmManager
type. To set an alarm, we invoke the Set()
method. This method takes three parameters, the type of alarm, the time, and the intent to broadcast when the alarm is triggered.
We specify that we want to use real time and we want to wake the device using the RtcWakeup
alarm type. As the alarm may be triggered when the device is asleep, the manager holds a wake lock until the OnReceive()
method is complete. This guarantees that the device will wake when the alarm is triggered and may go back to sleep as soon as it is finished executing.
Then, we specify the alarm time in the number of milliseconds since the Unix epoch. In order to calculate the alarm time, we first obtain the current time as the number of milliseconds since the Unix epoch by using the static CurrentTimeMillis()
method on JavaSystem
. We then add to that the number of milliseconds between the current time and the desired time.
The last parameter is the PendingIntent
instance that holds the Intent
instance that will be broadcast when the alarm expires.
There is also the option to repeat the operation after a certain interval. To do this, we can use the SetRepeating()
method instead of the Set()
method. This will allow us to specify an additional parameter, which is the number of milliseconds between alarm triggers.
There are two main types of alarms: real time and boot time. Each type has an option to wake the device when the alarm is triggered. The real time clock uses the current system time of the device and the boot time starts from the time the device is booted.
To specify real time, we use the Rtc
or RtcWakeup
instances, and to specify boot time, we use ElapsedRealtime
or ElapsedRealtimeWakeup
.
The wake-up variants specify that the device should wake up and execute the broadcast. If this is not necessary, the manager will wait until the device is woken before broadcasting. If the device is not woken, the broadcasts are not queued up, and when the device finally wakes, only one broadcast will be sent.