PhoneGap on WP7 Tip #8: Alarms and Reminders

One of the key design decisions the design team made when creating Windows Phone was a focus on providing maximum battery life for the end user. And it seems a major contributor to short battery life is having applications running in the background. So it’s important to realize that apps you create for Windows Phone (including PhoneGap) are paused when the user switches away from them. But frequently, you want to provide information to the user while your application is not in the foreground. There are many ways to do this, including various background tasks and notifications.

We’re going to look at a particular kind of background task today – the ability to set custom Alarms and Reminders. These alarms and reminders can show alerts to the user when your app is not running, and can be used to launch your app either to the starting page or to a deeper page in the app by using a URI to another page as I showed here.

Read up on Alarms and Reminders, and then follow along as we interact with them from a PhoneGap app.

Begin by creating the plugin class like I showed here. Here’s the code for the plugin class that I’m calling scheduler.cs. Notice I’m using the latest template for Cordova so some of the references are a little different from previous samples.

 using System;
using System.Net;
using System.Runtime.Serialization;
using Microsoft.Phone.Tasks;
using WP7CordovaClassLib.Cordova.Commands;
using Microsoft.Phone.Scheduler;

namespace WP7CordovaClassLib.Cordova.Commands
{
    public class scheduler : BaseCommand
    {

          public class alarmOptions
        {

            [DataMember]
            public string content;

            [DataMember]
            public DateTime beginTime;

            [DataMember]
            public DateTime expirationTime;

            [DataMember]
            public RecurrenceInterval recurrence;

            [DataMember]
            public Uri sound;

        }

        public void addAlarm(string options)
        {
            // Generate a unique name for the new notification. You can choose a
            // name that is meaningful for your app, or just use a GUID.
            String name = System.Guid.NewGuid().ToString();
                        
            Alarm alarm = new Alarm(name);

            alarmOptions opts = JSON.JsonHelper.Deserialize<alarmOptions>(options);
           
            alarm.Content = opts.content;
            alarm.BeginTime = opts.beginTime;
            if (opts.expirationTime > opts.beginTime)
                alarm.ExpirationTime = opts.expirationTime;
            
            if(opts.recurrence != null)
                alarm.RecurrenceType = opts.recurrence;
            
            if (opts.sound != null)
                alarm.Sound = opts.sound;

            ScheduledActionService.Add(alarm);

            PluginResult result = 
                new PluginResult(PluginResult.Status.OK, name);

            this.DispatchCommandResult(result);
        }   

   
    }
}

A couple of things to note. First, you’ll see there’s a RecurrenceInterval type that the Alarm (and Notification) class uses. It’s an enumeration with values like None, Weekly, Daily, etc. We’ll be passing a numerical value in here later. Also note the URL of a custom sound the alarm can play. That’s just an MP3 or WAV file you put in the project directory for your application. Finally, we’re creating a unique name for the alarm by using a GUID. That’s just a string that’s guaranteed to be unique. We’re returning the GUID so that the calling application can keep track of the alarms it creates if it wants to change or cancel them later. You could also alter this plugin to allow you to pass a unique name yourself instead.

For the JavaScript side of the plugin, create a file called scheduler.js and add this code.

 PhoneGap.addConstructor(function () {
    
    navigator.plugins.scheduler =
    {
         addAlarm: function (callback, content, beginTime, expirationTime, recurrence, sound) {
            var options = {
                "content": content,
                "beginTime": beginTime,
                "expirationTime": expirationTime,
                "recurrence": recurrence,
                "sound": sound
            };
            PhoneGap.exec(callback, null, "scheduler", "addAlarm", options);
        }
    }
});

With this in place, it’s very simple to set an alarm. Make sure you add a <script> reference to the HTML page, then add a function like this, which sets an alarm for 1 minute in the future to walk the dog.

 

 function addAlarm() {
    var alarmTime = new Date(); 
    alarmTime.setMinutes(alarmTime.getMinutes() + 1);
    var alarmMessage = "Walk the dog";
    navigator.plugins.scheduler.addAlarm(addAlarmCallback, alarmMessage, alarmTime, null, 0, null);
}
function addAlarmCallback(alarmName) {
    navigator.notification.alert("Alarm created named: " + alarmName);
}

Notice we have to pass a zero (for a RecurrenceType of None) for the recurrence interval. To make the code clearer, we can add this code to the very top of the scheduler.js function:

 

 var RecurrenceInterval =
    { 
     "None": 0,
     "Daily": 1,
     "Weekly": 2,
     "Monthly": 3,
     "EndOfMonth": 4,
     "Yearly":5 
     };

Then our call to addAlarm becomes easier to read.

 

 navigator.plugins.scheduler.addAlarm(addAlarmCallback, alarmMessage, alarmTime, null, RecurrenceInterval.None, null);

Following this pattern you could add an addReminder function to the scheduler.cs and scheduler.js files, with the slightly different parameters a Reminder expects. You could also query the system for a list of existing Alarms and Reminders so the user could manage them.

So don’t be alarmed (pun intended), go ahead and add these features to your PhoneGap apps!