Scheduling tasks

Some tasks need to be performed at a particular time in the future, some may even be required to recur.

How to do it...

We can schedule tasks for the future using the AlarmManager instance:

  1. As scheduling tasks involves running code when the app is closed by the user, we have to get permission to do this:
    [assembly: UsesPermission(Manifest.Permission.SetAlarm)]
  2. Then, we need a broadcast receiver that will receive a notification when the alarm is triggered:
    [BroadcastReceiver]
    [IntentFilter(new[] { "xamarincookbook.Alarm" })]
    public class AlarmReceiver : BroadcastReceiver {
      public override void OnReceive(
      Context context, Intent intent) {
        // alarm has triggered
      }
    }
  3. When we want to schedule a task, we set an alarm for a specific time and then provide an intent that should be broadcast when the time expires:
    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);

How it works...

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.

Note

If the AlarmType does not specify that it will wake the device, the intent will wait until the device is woken before broadcasting the intent. This may not be desired if the intent needs to be broadcast at a specific time.

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.

Note

Unix, or Java, time starts from January 1, 1970, but .NET or C# time starts from January 1, 2001.

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.

Tip

When using the repeating alarm, the interval must be greater than or equal to 60 seconds. If not, the interval will be adjusted. For shorter intervals, an exact alarm can be used, with a manual reschedule.

There's more...

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.83.150