Getting Started with Microsoft Band SDK

Ariel Ben Horesh
Share

On October 2014, Microsoft released the “Microsoft Band” — a smartwatch/fitness band. The reception to it surprised even Microsoft who, after preparing a limited amount of devices, found that the demand far exceeded supply. Not long after, they released the Band SDK, allowing developers to target the Band and provide applications to accompany the Band or extend its experience. A year after its initial release, the Band 2 was released improving several aspects of the device and brandishing a new sleeker, curved design.

Microsoft Band 2

The Microsoft Band 2 (Image Credit: Microsoft)

The Band is filled with sensors that focus on usage in fitness and sporting activities — but it can also be used as a sleep tracker and a smartwatch that displays notifications from a paired phone and/or from social networks such as Facebook and Twitter.

Band SDK Features

Before we dive into the features of the SDK, it is vital to understand that any user/SDK code will not be running on the Band itself (it is similar to the model used by the Apple Watch) but on a device paired with the Band.

The device can run any platform supported by the Band SDK — iOS, Android and Windows (including both Windows 10 and Windows 8.1 applications).

However, when you harness the SDK it will provide you with rich functionality including accessing its sensor data, providing custom UI shown on the Band (known as “tiles” and “tiles content”), and sending notifications to the Band.

The features offered by the Microsoft Band SDK are as follows:

  • Multi-platform support
  • Sensor data subscriptions
  • Tile creation and management
  • Tile notifications
  • Custom layouts
  • Haptic notifications
  • Band theme personalization

Band Sensors

As we mentioned earlier, the Band is packed with sensors. Here is the complete sensor list provided by either the Band/Band 2:

  • Accelerometer — Measures accelerations on the X, Y, Z axes.
  • Gyroscope — Measures angular velocity.
  • Distance — Measures distance in centimetres, and also provide current speed.
  • Heart Rate — Measures the wearer’s beats per minute.
  • Pedometer — Measures steps since the Band last factory reset.
  • Skin Temperature — Measures the skin temperature of the wearer in degrees Celsius.
  • UV — Measures the current ultraviolet radiation exposure intensity.
  • Calories — Measures the total number of calories the wearer has burned.
  • Galvanic Skin Response* — Provides the wearer’s skin resistance.
  • RR Interval* — Provides the interval between the last two continuous heart beats.
  • Ambient Light* — Provides the current room light intensity.
  • Barometer* — Provides the current raw air pressure.
  • Altimeter* — Provides the current elevation.

* Microsoft Band 2 only.

More information can be found on the Microsoft Band Sensors page.

In this article, we will look at how we can read sensor data using all three major platforms — iOS, Android and Windows. First, we need to setup our applications to use the SDK.

Download the SDK relevant to the platform of choice at the Microsoft Band platform page. If you aim to create a UWP (Universal Windows Platform) application, you may use Nuget to download and install the SDK into our application via the Microsoft Band nuget package.

Let’s start with iOS.

iOS – Setting up the Band SDK Environment

Currently, the Band SDK is supported on iOS 7 and above. Support for the iOS Simulator is not available, so we will need to test out our application on a real device paired with the Band.

If we would like our application to keep communication with the Band while it is on in the background, we need to enable “Use Bluetooth LE accessories” in background mode. For the sake of this tutorial, it won’t be necessary.

  • Launch Xcode (version 6.0 and above) and create a new single page iPhone application. This article will be using Objective-C, but it is fairly simple to translate the example code into Swift.
  • First things first, we need to add the Band SDK into our project. In the project navigator, right click on our project name and select “Add Files…”.
  • Locate and select the MicrosoftBandKit framework file (from where you’ve downloaded and extracted the SDK file) and select the option to “Copy items if needed”.
  • Select “Build Phases” under the project target. And add CoreBluetooth.framework under “Linking Binary with Libraries”.

Now, we are ready to start coding.

iOS — Connecting to a Band Device

Navigate to the ViewController.m file. Add an import statement in order to have access to the Micorsoft Band SDK.

#import <MicrosoftBandKit_iOS/MicrosoftBandKit_iOS.h>

Let us add a delegate to the ViewController definition. Via this delegate, we will get callbacks when we manage to successfully connect or disconnect from the device.

Add the following callbacks inside the implementation section of the ViewController:

@interface ViewController () <MSBClientManagerDelegate>
....
@implementation ViewController

-(void)clientManager:(MSBClientManager *)cm
  clientDidConnect:(MSBClient *)client {
  // handle connected event
}
-(void)clientManager:(MSBClientManager *)cm
clientDidDisconnect:(MSBClient *)client {
  // handle disconnected event
}
-(void)clientManager:(MSBClientManager *)cm client:(MSBClient *)client
didFailToConnectWithError:(NSError *)error {
  // handle failure event
}  

Later on, we will try to connect with a Band device, we will store this instance in a property so we will be able to access it from various methods.

@interface ViewController () <MSBClientManagerDelegate>
@property (nonatomic, weak) MSBClient *client;
@end

This tutorial assumes that you, the reader, is fluent enough with iOS development and creating a simple UI with buttons and labels is well within your grasp. To keep this tutorial as simple as possible, we will not get into details on how to create the user interface and hook it up with instances and actions on the ViewController side. Now add a button and hook it to an action named init.

MSBClientManager is a singleton which will provide us access to the SDK functionality. Later on, we will use an instance of a device client to access sensors, tiles and the rest of the SDK features. In this method, we will try to gain that instance.

As promised, we are setting up our ViewController for notifications via the delegate when calling setDelegate.

Then we are accessing the attachedClients collection. This will provide us with a list of all Band devices paired with the device running this app. (Yes, there can be multiple Bands connected to a single device!). Your code can have heuristics/UI to decide which Band to connect to, in this tutorial we will just grab the first one.

Lastly, we are initiating a call to try and connect to this device by calling connectClient and passing the Band’s client instance.

- (IBAction)init:(id)sender {
  [[MSBClientManager sharedManager] setDelegate:self];
  NSArray *attachedClients = [[MSBClientManager sharedManager]
                              attachedClients];
  self.client = [attachedClients firstObject];
  if (self.client) {
      [[MSBClientManager sharedManager] connectClient:self.client];
  }
}

iOS – Accessing a Sensor

Assuming all went well, and we’ve managed to connect to a Band, we can now proceed to gain access to a sensor’s data feed. However, some sensors require explicit user consent. Currently, only the heart rate and RR Interval sensors require consent, but this could be changed without warning. It is best practice to check for consent whenever you require access to a sensor.

Once again, I assume you have another button in your View to be able to call the following method.

First, we are checking whether we have user consent for the sensor in question. As we have mentioned above, since that in this specific example, we are asking for access to the Heart Rate sensor, we will most likely receive MSBUserConsentNotSpecified. We will need to call requestHRUserConsentWithCompletion. A dialog will popup out on the device where the user will be able to approve our app’s access to their heart rate.

Heart rate consent on iOS

The consent dialog on iOS

Consecutive call to this method should now give us a MSBUserConsentGranted or MSBUserConsentDeclined. For the sake of this tutorial, let’s assume that the optimistic scenario has happened and the user has agreed. We can now call the method startHeartRateUpdates which we will describe soon.

- (IBAction)getSensor:(id)sender {
  MSBUserConsent consent = [self.client.sensorManager
                            heartRateUserConsent];
  switch (consent) {
    case MSBUserConsentGranted:
      // user has granted access
      [self startHeartRateUpdates];
      break;
    case MSBUserConsentNotSpecified:
      // request user consent
      [self.client.sensorManager
          requestHRUserConsentWithCompletion:
               ^(BOOL userConsent, NSError *error) {
          if (userConsent) {
              // user granted access
          }
          else {
              // user declined access
          }
      }];
      break;
    case MSBUserConsentDeclined:
      // user has declined access
      break;
    default:
      break;
  }
}

In order to receive sensor updates we will be calling startHeartRateUpdatesToQueue. Once successful, it will call the callback parameter (known as a “block” in Objective-C) on an interval preconfigured for each sensor (check the documentation for further information about each sensor update’s interval). Inside the block, you are free to do with the data as you please. For the purpose of this tutorial, we will be updating the UI with the information provided by the callback parameters. For each call, we will be getting a value representing the current sensor data, in this case, a heart rate and a quality indicator, which should help us understand how reliable this information is. Specifically, with heart rate you should doubt the validity of a sample if the quality parameter is not locked.

- (void)startHeartRateUpdates {
  NSError *subscriptionError;
  [self.client.sensorManager startHeartRateUpdatesToQueue:nil errorRef:&subscriptionError withHandler:^(MSBSensorHeartRateData *heartRateData, NSError *error) {
    if (error) {
      // handle error
    }
    _heartRateLabel.text =
    [NSString stringWithFormat:@"Heart Rate: %3u %@",
     (unsigned int)heartRateData.heartRate,
     heartRateData.quality == MSBSensorHeartRateQualityAcquiring ? @"Acquiring" : @"Locked"];
  }];
  if (subscriptionError) {
    // failed to subscribe
  }
}

Once we are finished accessing the sensor, it is considered good behavior to unsubscribe from the sensor. This part is simple enough, a single call to stopHeartRateUpdatesErrorRef should do the trick.

- (IBAction)stop:(id)sender {
  [self.client.sensorManager stopHeartRateUpdatesErrorRef:nil];
}

With a few simple lines of code, we have shown how to create an iOS app from scratch, connect the Band and receive heart rate data from it.

Since the Band SDK is multi-platform, the code for Android and Windows is similar in concept. Let’s check out Android.

Android – Setting up the Band SDK Environment

Currently, the Band SDK is supported on Android API 17 and above.

The Android SDK relies on capabilities provided by the Microsoft Health App. To use the SDK on Android, having the Microsoft Health App installed on the phone is required. Without the Microsoft Health App installed on the phone, any attempts to create a Microsoft Band client will fail with an error.

Any Android app should provide the following permissions in its AndroidManifest.xml:

<uses -permission android:name="android.permission.BLUETOOTH"></uses>

<uses -permission android:name="com.microsoft.band.service.access.BIND_BAND_SERVICE"></uses>

To get started, launch Android Studio (or your favorite Android IDE) and create a basic Android application.

We need to add the Band SDK into our project. Go to the Android project’s application directory and locate the libs folders (you can create it if it does not already exist), and copy the microsoft-band-@version@.jar file to this location.

Right click on the app module (in the project structure window) and select “Open Module Settings”. Select the “Dependencies” tab and click on the “+” button to add a “File Dependency”. You should see inside the libs folder the jar file we have copied earlier. Select it and click OK.

Add the permissions mentioned above to the AndroidManifest.xml.

Now, we are ready to start coding.

Android — Connecting to a Band Device

Navigate to the Activity file and add the following import statements in order to have access to the Microsoft Band SDK:

import com.microsoft.band.BandClient;
import com.microsoft.band.BandClientManager;
import com.microsoft.band.BandException;
import com.microsoft.band.BandInfo;
import com.microsoft.band.BandIOException;
import com.microsoft.band.ConnectionState;
import com.microsoft.band.sensors.BandHeartRateEvent;
import com.microsoft.band.sensors.BandHeartRateEventListener;
import com.microsoft.band.sensors.HeartRateConsentListener;

Connecting to the band must be done via a background thread. We will be using the Android AsyncTask mechanism. Add an import statement for it as well.

import android.os.AsyncTask;

Later on, we will try to connect with a Band device. We will store this instance in a private member so we will be able to access it from various methods in future.

private BandClient client = null;

Now, let’s add a class inheriting from AsyncTask.

private class BandConnectTask extends AsyncTask<Void, Void, Void> {
  @Override
  protected Void doInBackground(Void... params) {
    return null;
  }
}

Just as with the iOS section, we assume are fluent enough with Android development that creating a simple UI with buttons and labels is well within your grasp. Details on how to create the user interface and hook it up with instances and actions on the activity side is outside of the scope of this article. Now we need to add a button and hook it to a listener. Add it into your app.

Inside the listener we will execute our background task responsible of connecting to the band:

btnConnect.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    new BandConnectTask().execute();
  }

Let’s implement the connection logic. The device running this app needs to be paired with at least one Band (it could be multiple). This code connects to the first Band it finds but you can provide logic to allow the user to select a specific Band for the app if required. Once we get the instance, we connect to it.

protected Void doInBackground(Void... params) {
  BandInfo[] devices = BandClientManager.getInstance().getPairedBands();
  client = BandClientManager.getInstance().create(getBaseContext(), devices[0]);
  try {
    ConnectionState state = client.connect().await();
    if(state == ConnectionState.CONNECTED) {
        // do work on success
    } else {
        // do work on failure
    }
  } catch (InterruptedException e) {
    e.printStackTrace();
  } catch (BandException e) {
    e.printStackTrace();
  }
  return null;
}

Android — Accessing a Sensor

Assuming all went well and we’ve managed to connect to a Band, we can now proceed to gain access to a sensor’s data feed. However, just like with iOS, some sensors require explicit user consent. At the moment, only the heart rate and RR Interval sensors require a consent, but this could be changed without warning. It is best practice to check for consent whenever you require access to a sensor.

We assume you have another button in your view that can call the next method we discuss.

First, we check whether we have user consent to the sensor in question. Since we are asking for access to the heart rate sensor by calling requestHeartRateConsent, it will display a dialog to the user to approve its consent.

Consent on Android

Consent on Android

btnStart.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v)  {
    if(client.getSensorManager().getCurrentHeartRateConsent() !=
            UserConsent.GRANTED) {
      client.getSensorManager().requestHeartRateConsent(MainActivity.this, new HeartRateConsentListener() {
        @Override
        public void userAccepted(boolean consentGiven) {
        }
      });
    }
  }
});

Assuming the user has approved, we can now start receiving sensor data. You can call this method if the user has given consent via the userAccepted method or if the current state is that the user already gave consent. We call the method registerHeartRateEventListener and we pass it a specific listener that we will create momentarily.

private void startRecievingData() {
  try {
    client.getSensorManager().registerHeartRateEventListener(heartRateListener);
  } catch(BandException ex) {
  }
}

In this tutorial, we have created this listener on the MainActivity as following:

final BandHeartRateEventListener heartRateListener = new
  BandHeartRateEventListener() {
    @Override
    public void onBandHeartRateChanged(final BandHeartRateEvent event) {
    }
  };

This should be enough to compile, but we would like to go the extra mile and update the UI. Once again, we assume you have a TextView at your disposal (if not, please add one to your layout). Since we are working with a UI element, we must be processing updates on the UI thread, and so we will call the activity runOnUI method and update the UI with the data we are getting from the event.

final BandHeartRateEventListener heartRateListener = new
  BandHeartRateEventListener() {
    @Override
    public void onBandHeartRateChanged(final BandHeartRateEvent event) {
      MainActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          updateText.setText(String.format("Heart Rate = %d beats per minute\n"
            + "Quality = %s\n", event.getHeartRate(), event.getQuality()));
        }
      });
    }
  };

Once we are finished accessing the sensor, it is good practice to unsubscribe from the sensor. This part is simple enough — a single call to unregisterHeartRateEventListener should do the trick.

btnStop.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v)  {
    try {
      client.getSensorManager().unregisterHeartRateEventListener(heartRateListener);
    } catch(BandIOException ex) {
    }
  }
});

With a few simple lines of code, we have now created an Android app from scratch, connected it to a Band and received heart rate data from it.

Now, let’s launch Visual Studio and see how Windows handles the same scenario.

Windows – Setting up the Band SDK Environment

All versions of the Microsoft Band SDK for Windows platforms require Visual Studio 2013 or later.

If you want to use the SDK with the Windows Universal Platform, you’ll also need to install the Universal Platform feature via the Visual Studio installer.

If you want to use the SDK with Windows Phone (8.1 and above), you’ll also need to install the Windows Phone SDK add-on for Visual Studio.

In this tutorial, we are going to use the Windows 10 Universal platform app. The same code will be able to run on both Windows Mobile and Windows desktops devices.

The steps for creating a Windows Universal Platform app include:

  • Create a Windows Blank App (Universal).
  • Right click on the project name in the solution explorer, and choose “Manage Nuget packages…”.
  • Click on browse and search for “Microsoft Band”.
  • Install the “Microsoft.Band” package into our project.
  • Double click on the Package.appxmanifest, and check “Bluetooth” and “Proximity” at the capabilities tab. This can change for earlier versions of Windows platform, consult the Band documentation for further details.

Now, we are ready to start coding.

Windows- Connecting to a Band Device

Navigate to MainPage.xaml.cs file. Add the following using statement in order to have access to the Micorsoft Band SDK.

using Microsoft.Band;
using Microsoft.Band.Sensors;

Let us add a private field to store the Band’s client instance. We will be able to access it from various methods in our code.

private IBandClient _client;

In this tutorial, we assume you understand how to add buttons and TextBlocks to the UI, and how to make them accessible via code-behind. For simplicity’s sake, we will refrain from using the MVVM pattern, but the following code can be easily translated into Commands and Properties bound to the UI. The Band SDK relies heavily on the async-await pattern. Make sure you adorn methods that are calling and awaiting other methods with the keyword "async".

Using the BandClientManager singleton, we get access to all the Band devices paired with the device running this app. In this tutorial, we choose the first one, but in your code you may select the Band you want to work with. When the ConnectAsync method completes, we should have a connection with the Band. If something goes wrong we will get an exception.

private async void ConnectClick(object sender, RoutedEventArgs e)
{
  var pairedBands = await BandClientManager.Instance.GetBandsAsync();
  try
  {
    _client = await
      BandClientManager.Instance.ConnectAsync(pairedBands[0]);
  }
  catch (BandException ex)
  {
    // handle a Band connection exception
  }
}

Windows — Accessing a Sensor

Assuming all went well and we’ve managed to connect to a Band, we can now proceed to gain access to a sensor’s data feed. Just as above with iOS and Android, some sensors require an explicit user consent (the heart rate and RR Interval sensors), it is best practice to check for consent whenever you require access to a sensor as the sensors requiring permission could change at any time.

Once again, we assume you have another button in your View to be able to call the upcoming method we will discuss next.

First, we check whether we have user consent to the sensor in question. As we are asking for access to the heart rate sensor using RequestUserConsentAsync, it will display a dialog to the user to approve via their consent.

Heart rate consent on Windows

The consent dialog on Windows

private async void StartClick(object sender, RoutedEventArgs e)
{
  if (_client.SensorManager.HeartRate.GetCurrentUserConsent() !=
      UserConsent.Granted)
  {
    // user hasn’t consented, request consent
    var result = await
        _client.SensorManager.HeartRate.RequestUserConsentAsync();
    if (result && _client.SensorManager.HeartRate.GetCurrentUserConsent() ==
      UserConsent.Granted)
    {
      StartRecievingData();
    }
  }
  if (_client.SensorManager.HeartRate.GetCurrentUserConsent() ==
    UserConsent.Granted)
  {
    StartRecievingData();
  }
}

Assuming the user has approved access, we can now start receiving sensor data. You can call this method if the user has given consent via the result of RequestUserConsentAsync or if the current state is that the user has already given consent. We call the method StartReadingsAsync and we subscribe to an event that will be fired on an interval specified by the sensor:

private async void StartRecievingData()
{
  _client.SensorManager.HeartRate.ReadingChanged += async (sender, args) =>
  {
    // do work when the reading changes (i.e., update a UI element)
  };
  try
  {
    await _client.SensorManager.HeartRate.StartReadingsAsync();
  }
  catch (BandException ex)
  {
    // handle a Band connection exception
  }
}

Now, we would like to update the UI. However, we need to worry about another issue — in order for us to update the UI, this code needs to run on the UI thread. The mechanism to do this is calling the Dispatcher.RunAsync and passing it a lambda expression which in turn is assured to be running on the UI thread. We throw in one of the C# 6.0 new features, string interpolation, which formats a string in a clearer way than the old way of using String.Format method.

private async void StartRecievingData()
{
  _client.SensorManager.HeartRate.ReadingChanged += async (sender, args) =>
  {
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
      TextBlock.Text =
        $"Heart Rate = {args.SensorReading.HeartRate} Quality = {args.SensorReading.Quality}");
  };
  try
  {
    await _client.SensorManager.HeartRate.StartReadingsAsync();
  }
  catch (BandException ex)
  {
    // handle a Band connection exception
  }
}

Once we are finished accessing the sensor, it is good practice to unsubscribe from the sensor. A single call to StopReadingsAsync should do the trick.

private async void StopClick(object sender, RoutedEventArgs e)
{
  await _client.SensorManager.HeartRate.StopReadingsAsync();
}

Our Windows app now can connect to the Band and receive heart rate data from it.

Wrapping up

We have covered how to get started, connect and receive real data from the Microsoft Band device. The Microsoft Band is packed with sensors that can provide a whole range of data for your connected applications.

That’s not all you can do with the Band — from here you can add your own tiles and connect functionality to those tiles via buttons and a unique UI. You can even create Band skins/themes to further personalize the Band. The SDK is fully cross-platform and supports the major platforms today — iOS, Android and Windows.

Building apps for the Band is ripe with opportunity and we can’t wait to see what you can achieve with it!

Thank you for your time, I hope you enjoyed this tutorial and found it useful. If you’ve got thoughts or questions, please add them below.