Microsoft Band

In this post, I’m going to cover the basics of getting your Band connected using a Background Task in a Windows Phone application.

If you’ve not yet discovered the basics of working with the Band SDK, check out my previous posts in this ‘Developing for Microsoft Band with WinRT’ series. You’ll need some experience to understand what I’m covering and how you can extend it to fit your needs.

Setup the background task

To get yourselves started with background execution, you’ll need to add a new project to your solution which will be solely for your background task class. You’ll need to create a new Windows Runtime Component, not a portable class library.

You will then need to create a sealed class within this project which inherits from the IBackgroundTask interface in the Windows.ApplicationModel.Background namespace. You’ll then have to add the interfaces only method, Run, which as it says on the method name, runs when the background tasks is executing. It will provide you with a parameter that you can access a deferral from. You’ll need to do this if you’re going to be using your background task to access the data from the sensors.

The basic layout for this Run method will look like this:


        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            this._deferral = taskInstance.GetDeferral();

            // ToDo: Possibly check the cost of performing the BG task on the device. If high, then don't perform the task?

            try
            {
                // ToDo: Connect to the band and get the data
            }
            catch (Exception)
            {
                // ToDo: Complete the deferral and disconnect from the band
            }
        }

As you can see from this basic layout, we’re getting the deferral from the task instance and keeping hold of it so we can complete it later. This will keep out background task alive and not drop out before we’ve done what we need it to do.

Getting Microsoft Band Data

Microsoft Band Sensors

Microsoft Band Sensors

If you’ve followed on from any of my previous posts, you should know how to get yourselves connected with the Band and get sensor information in your app. Now I’ll show you how to get it in a Background Task.

NOTE: If you’re wanting to access the Heart Rate sensor of the Band, you’ll need to get the user’s consent before the background tasks is registered to the phone as this is a new requirement in the SDK. The best way to do this is when your first page loads up, connect to the Microsoft Band using the following method:


        private static async Task CheckBandStatus()
        {
            var bandInfo = (await BandClientManager.Instance.GetBandsAsync()).FirstOrDefault();

            IBandClient bandClient = null;

            bool isRunning = false;

            if (bandInfo != null)
            {
                using (new DisposableAction(() => isRunning = true, () => isRunning = false))
                {
                    try
                    {
                        bandClient = await BandClientManager.Instance.ConnectAsync(bandInfo);
                    }
                    catch (Exception ex)
                    {
                        // ToDo: Log error?
                    }

                    if (bandClient != null)
                    {
                        if (bandClient.SensorManager.HeartRate.GetCurrentUserConsent() != UserConsent.Granted)
                        {
                            await bandClient.SensorManager.HeartRate.RequestUserConsentAsync();
                        }
                    }
                }
            }

            if (bandClient != null)
            {
                bandClient.Dispose();
                bandClient = null;
            }
        }

If you’ve not implemented the DisposableAction class that I covered in a previous post, you can get a copy of it here to add to your solution: DisposableAction.cs. You’ll be using it in the background task, so it’s worth having.

The above code will bring a dialog up in your application that your user will need to accept. If they refuse to do so, you can keep this method calling the next time the user enters your application to remind them that they need to do so if they want to use the Band sensors to track information in your app.

Now let’s get the Band data in your background class. We’ll create a new asynchronous private method called GetBandData which will setup the Band connection and register to listen for events fired by the Band’s sensors. I’m going to provide you with the setup code but if you’d like to understand what you’re doing, please go back and read my previous posts.


        private async Task GetBandData()
        {
            var bandInfo = (await BandClientManager.Instance.GetBandsAsync()).FirstOrDefault();

            bool isRunning = false;

            if (bandInfo != null)
            {
                using (new DisposableAction(() => isRunning = true, () => isRunning = false))
                {
                    try
                    {
                        this._bandClient = await BandClientManager.Instance.ConnectAsync(bandInfo);
                    }
                    catch (Exception)
                    {
                        throw;
                    }

                    if (this._bandClient != null)
                    {
                        if (this._bandClient.SensorManager.HeartRate.GetCurrentUserConsent() != UserConsent.Granted)
                        {
                            // ToDo: Complete the deferral because we don't have consent to carry on
                            return;
                        }

                        // Check the user is wearing the Band.
                        var bandContactState = await this._bandClient.SensorManager.Contact.GetCurrentStateAsync();

                        if (bandContactState.State == BandContactState.NotWorn)
                        {
                            // ToDo: Complete the deferral because the user isn't wearing the band. No need to read sensors.
                            return;
                        }

                        this._heartRateRead = false;
                        this._distanceRead = false;
                        this._skinTempRead = false;
                        this._bandClient.SensorManager.HeartRate.ReadingChanged += this.OnHeartRateChanged;
                        await this._bandClient.SensorManager.HeartRate.StartReadingsAsync();

                        this._bandClient.SensorManager.Distance.ReadingChanged += this.OnDistanceChanged;
                        await this._bandClient.SensorManager.Distance.StartReadingsAsync();

                        this._bandClient.SensorManager.SkinTemperature.ReadingChanged += this.OnSkinTemperatureChanged;
                        await this._bandClient.SensorManager.SkinTemperature.StartReadingsAsync();
                    }
                }
            }
            else
            {
                // ToDo: Complete the deferral as we can't find the connected Band on the device.
            }
        }

As you can see in this method, we’re making a connection to the Band client and keeping a reference to it so we can remember to dispose of it when we’ve done. If you let it dispose in this method, you’ll lose the events that have been attached to the sensors and won’t ever receive the readings.

We’re creating 3 methods to attach to our sensors and these will look something as follows:


        private void OnSkinTemperatureChanged(object sender, BandSensorReadingEventArgs<IBandSkinTemperatureReading> e)
        {
            var skinTemperature = e.SensorReading.Temperature;

            this._skinTempRead = true;

            this._bandClient.SensorManager.SkinTemperature.StopReadingsAsync();
            this._bandClient.SensorManager.SkinTemperature.ReadingChanged -= this.OnSkinTemperatureChanged;

            // Do something with the skin temperature?

            this.CompleteReadings();
        }

        private void OnDistanceChanged(object sender, BandSensorReadingEventArgs<IBandDistanceReading> e)
        {
            var motionType = e.SensorReading.CurrentMotion;
            var pace = e.SensorReading.Pace;
            var speed = e.SensorReading.Speed;

            this._distanceRead = true;

            this._bandClient.SensorManager.Distance.StopReadingsAsync();
            this._bandClient.SensorManager.Distance.ReadingChanged -= this.OnDistanceChanged;

            // Do something with the distance readings?

            this.CompleteReadings();
        }

        private void OnHeartRateChanged(object sender, BandSensorReadingEventArgs<IBandHeartRateReading> e)
        {
            var healthRate = e.SensorReading.HeartRate;

            this._heartRateRead = true;

            this._bandClient.SensorManager.HeartRate.StopReadingsAsync();
            this._bandClient.SensorManager.HeartRate.ReadingChanged -= this.OnHeartRateChanged;

            // Do something with the heart rate readings?

            this.CompleteReadings();
        }

        private async void CompleteReadings()
        {
            if (this._heartRateRead && this._distanceRead && this._skinTempRead)
            {
                // Do something with the data we've received.

                // ToDo: Complete the deferral as we are now done in the background task
            }
        }

We’ve now connected to the Microsoft Band, got the sensor data and have got to the end of our background task but the last thing we need to do is disconnect from the Band if we’re connected and complete the deferral. As you’ve probably noticed throughout the code snippets, I’ve purposely left areas that have notes to complete the deferral. In place of all of these comments, we can create a method which does the disconnection and completion of the deferral. The reason we need to disconnect from the Band is that if we don’t, the background task will throw an exception when it runs again.

Here’s that method:


        private async void CompleteDeferral()
        {
            if (this._bandClient != null)
            {
                this._bandClient.Dispose();
                this._bandClient = null;
            }

            this._deferral.Complete();
        }

We’ve now come full circle and our background task is complete. The only thing left to do is now register it within the application to execute.

Registering the Microsoft Band background task

The first thing you’ll want to do to get set up with the registration process is to reference your background project from your Windows Phone or Windows project.

Once you’ve done that, you’ll need to make a change to your app’s manifest file so that it supports the background task. Depending on how you’re wanting to trigger this, you’ll need to choose the correct trigger from the app manifest. In this tutorial, I’ll show you a time based one that runs every 15 minutes.

This is how your app manifest should look:

Package Manifest for Band Background Task

Package Manifest for Band Background Task

Now, after your call in the first page of your app that asks for access to the Band’s sensors, you’ll want to register your background task and here is how you do that:


        private static async Task RegisterTimerTask()
        {
            BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();

            var builder = new BackgroundTaskBuilder { Name = TimerTaskId, TaskEntryPoint = typeof(BandUpdaterTask).FullName };

            var trigger = new TimeTrigger(15, false);

            builder.SetTrigger(trigger);
            builder.Register();
        }

This background task will register as a time based trigger task which will run every 15 minutes.

You can now sit back and let your background task do all the work for your application!

If you have any questions, please feel free to leave them below and I will do my best to answer them.

Join the discussion 2 Comments

Leave a comment