Contact Us
Magenic
  • What We Do
  • How We Do It
  • Our Thinking
  • Join Us
  • Our Work
  • Industries
  • Cloud
  • Software Development
  • Quality Engineering
  • DevOps
  • Strategy
  • Experience Design
  • Data & Integration
  • Advisory Services
  • Careers
  • Culture
  • Events
  • Success Stories
  • Partnerships
  • Technologies
  • Professional Services
  • Financial Services
  • Retail
  • Health Care

Starting with Microsoft Band and Xamarin

May 3, 2015 // By Kevin Ford

Recently Xamarin released their API for Microsoft Band that works with Android, iOS and Windows Phone. It was a tough choice on what to play with before vacation; a new Xamarin Forms preview that works with Windows Store and Windows Phone 8.1 was released as well as Xamarin Everywhere that hits Android Wear and Apple Phone. A complete overload of super cool stuff.

But… last week I got a new Microsoft Band and you know, time to play. First off, the Band isn't really a Smart Watch. It's more a like a fitness device on steroids. You can pull all kinds of sensor information out of it, you can also send notifications to it and play with it's appearancce. What you can't really do is input information into the Band and have to do something on the phone. That is to say the band is about collecting sensor information and consuming information but not for inputting information like a "true" smart watch allows.

Xamarin has wrapped the Microsoft platform APIs, pretty much verbatim. One thing they have done which is nice is if the calls are asynchronous on Android, they have Task returning versions. However, like the Microsoft platform specific versions the APIs do not match from platform to platform so making cross platform code will still be challenging unless you wrap them in your own unified interface. Xamarin has a nice page on the component store that explains the basics of the APIs which are pretty easy to use. They can be found here:

https://components.xamarin.com/view/microsoft-band-sdk

With that in mind I set out to givec this a try. Since my Band is currently synchronized with an Android device I am working with the Android version of the API. First I figured I'd try to add and then remove an icon from my Band that could receive notifications and messages. I created a class to open and close the connection.

public class BandConnection : IDisposable
{
    private IBandClient bandClient;
    private Activity context;

    public BandConnection(Activity context)
    {
        this.context = context;
        var pairedBands = BandClientManager.Instance.GetPairedBands();

        if (pairedBands != null && pairedBands.Length >= 1)
        {
            bandClient = BandClientManager.Instance.Create(context, pairedBands[0]);
        }
    }

    public ascync Task ConnectAsync()
    {
        if (bandClient == null)
        {
            throw new InvalidOperationException("BandClient is not set");
        }
        await bandClient.ConnectTaskAsync();
    }

    public async void Dispose()
    {
        if (bandClient != null && bandClient.IsConnected)
        {
            await bandClient.DisconnectTaskAsync().ConfigureAwait(false);
        }
    }
}

The class just takes in the current activity and then gets the first band registered with the device. If you were making a "real" application it may be a good idea to make some sort of screen to choose what Band the user wanted to connect to if there were more than one. The ConnectAsync method opens the connection to the Band. As you can see I use the ConnectTaskAsync method of the BandClient instead of ConnectAsync. All the asynchronous Android APIs seem to be wrapped up with Task returning operations with that naming convention. When the class is disposed, cif the bandClient is connected, the connection is closed.

I added a simple method to create a new tile on my band if there is room for one.

public async Task AddTileAsync(string tileId, string tileName, BandIcon largeIcon, BandIcon smallIcon)
{
    if (bandClient == null)
    {
        throw new InvalidOperationException("BandClient is not set");
    } 
    var tiles = await bandClient.TileManager.GetTilesTaskAsync().ConfigureAwait(false);
    var id = UUID.FromString(tileId);

    var spacesRemaining = await bandClient.TileManager.GetRemainingTileCapacityTaskAsync().ConfigureAwait(false);
    if (spacesRemaining > 0 && !tiles.Any(t => t.TileId.ToString() == tileId))
    {
        var tileBuilder = new BandTile.Builder(id, tileName, largeIcon);
        if (smallIcon != null)
        {
            tileBuilder.SetTileSmallIcon(smallIcon);
        }
        var tile = tileBuilder.Build();
        await bandClient.TileManager.AddTileTaskAsync(context, tile);
    }
}

I have added two images to my Android project, as per the API specs. One image is 24x24 and the other 48x48. I create them and convert them into the BandIcon format. The following code is what I used to call the AddTileAsync method.

using (var bandConnection = new BandConnection(this))
{
    if (bandConnection.BandClient != null)
    {
        await bandConnection.ConnectAsync().ConfigureAwait(false);
        var smallIconBitmap = ((BitmapDrawable)Resources.GetDrawable(Resource.Drawable.PhoneFinderSmall)).Bitmap;
        var smallIcon = BandIcon.ToBandIcon(Bitmap.CreateScaledBitmap(smallIconBitmap, 24, 24, false));
        var largeIconBitmap = ((BitmapDrawable)Resources.GetDrawable(Resource.Drawable.PhoneFinderLarge)).Bitmap;
        var largeIcon = BandIcon.ToBandIcon(Bitmap.CreateScaledBitmap(largeIconBitmap, 48, 48, false));

        await bandConnection.AddTileAsync(BandConstants.TileId, "Band Test", largeIcon, smallIcon).ConfigureAwait(true);
    }
}

When using this code it automatically syncs up to the device. The tile is identified by a unique identifier that I added as a constant to my code. When running it will first ask the user if they want to add the new tile to the Band. You can see my "awesome" abilities as an icon designer:

Xamarin Tile Band Test

After choosing allow the band synchronizes the new tile onto the Band.

Syncing screenshot

By scrolling the tiles on the band the newly added tile appears.

Screenshot of added tiles

I then added a method to remove the tile I just added.

public async Task RemoveTileAsync(string tileId)
{
    if (bandClient == null)
    {
        throw new InvalidOperationException("BandClient is not set");
    } 
    var tiles = await bandClient.TileManager.GetTilesTaskAsync().ConfigureAwait(false);
    var id = UUID.FromString(tileId);
    if (tiles.Any(t => t.TileId.ToString() == tileId))
    {
        await bandClient.TileManager.RemoveTileTaskAsync(id).ConfigureAwait(false);
   c }
}

This worked without incident and the tile from my band went away.

Sending a message to the band was also simple. The API reference contains the following description on the difference between a message and a dialog:

App notifications come in two flavors:

  1. Dialogs – dialog notifications are popups meant to quickly display information to the user. Once the user dismisses the dialog, the information contained therein does not persist on the Band.
  2. Messages – message notifications are sent and stored in a specific tile, and a tile can keep up to 8 messages at a time. Messages may display a dialog as well.

I added this method to my class to create a message:

public async Task SchowMessageAsync(string tileId, string title, string body, DateTime date, bool showMessage)
{
    if (bandClient == null)
    {
        throw new InvalidOperationException("BandClient is not set");
    }
    var id = UUID.FromString(tileId);
    await bandClient.NotificationManager.SendMessageTaskAsync(id, title, body, date, showMessage);
}

This method calls into my ShowMessageAsync method and gets the device location, converts it to an address and displays it to the user.

using (var bandConnection = new BandConnection(this))
{
    if (bandConnection.BandClient != null)
    {
        await bandConnection.ConnectAsync().ConfigureAwait(false);

        var geocoder = new Geocoder(this);
        var addressList = await geocoder.GetFromLocationAscync(_currentLocation.Latitude, _currentLocation.Longitude, 10).ConfigureAwait(false);

        var address = addressList.FirstOrDefault();
        if (address != null)
        {
            var deviceAddress = new StringBuilder();
            for (int i = 0; i < address.MaxAddressLineIndex; i++)
            {
                deviceAddress.Append(address.GetAddressLine(i))
                .AppendLine(",");
            }

            await bandConnection.ShowMessageAsync(BandConstants.TileId, 
                "Test Message", 
                string.Format("Current address: {0}", deviceAddress), 
                DateTime.Now, 
                true).ConfigureAwait(true);
        }
    }       
}

The message comes across to the band as expected.

Xamarin test message

Additionally, as expected, a message indicator appears with our tile stating that one new message was received.

New message indicator screenshot

When selecting the tile the message appears fully (I blocked out my address).

Test message Xamarin

Sending a dialog is similarly easy.  But as this test indicates the amount of text that can be displayed in the dialog is limited and there is no down button (see more) as with the message.  Dialogs should only be used for very short notifications.

public async Task ShowDialogAsync(string tileId, string title, string body)
{
    if (bandClient == null)
    {
        throw new InvalidOperationException("BandClient is not set");
    }
    var id = UUID.FromStrcing(tileId);
    await bandClient.NotificationManager.ShowDialogTaskAsync(id, title, body);
}

When sending this over it shows up as a popup but does not add to the message counter or add to the message history. As the API documentation stated, the dialog is not retained.

Longer message test

That's it for my first go.  Vibrating the band was similarly easy. Next I'll poke around at getting data from the Band and perhaps customizing its appearance.  Generally I was pleased at how easy it was to work with but cross platform applications may want to create a unified interface.

Kevin Ford is the Practice Lead of Mobile at Magenic. This is republished from his blog and can be found here. If you’d like to speak to us directly, contact us or give us a call at 877-277-1044.

Categories // Software Development
Tags Android, Microsoft Band, Wearables, Xamarin
SHARE:
THE LATEST:
  • FEBRUARY 23, 2021 // blog
    Stronger Product Owner = Better Software, Faster
  • FEBRUARY 19, 2021 // blog
    Security In Five Bi-Weekly Roundup – 2/19/21
  • FEBRUARY 18, 2021 // blog
    Doesn’t Everybody Know This?
Featured Content:
  • JANUARY 25, 2021 // White Paper
    The Top 7 Technology Trends of 2021

Related Posts

Blog
Microsoft Buys Xamarin - Analysis
Learn More
Blog
Magenic Named a Xamarin Elite Consulting Partner
Learn More
Blog
A Comprehensive Guide to Creating a Xamarin.Forms App with MvvmCross (Part 5 of 5)
Learn More
Blog
A Comprehensive Guide to Creating a Xamarin.Forms App with MvvmCross (Part 4 of 5)
Learn More

Ready to speak with our experts?

Have a question?

This field is required
This field is required
This field is required
This field is required

Thanks for Contacting Magenic

One of our experts will be contacting you directly within the next business day.

Return To Home
Magenic

info@magenic.com+1.877.277.1044

  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • RSS Feed

© Magenic Inc.Privacy NoticeTerms & ConditionsSitemap