[Xamarin.Forms] Desarrollando para la Microsoft Band

Introducción

El año pasado Microsoft se aventuró en el terrero de wearables con el lanzamiento de Microsoft Band,
una pulsera cuantificadora compatible con Windows Phone, iOS y Android
con posibilidades de monitorización de pasos, ritmo cardiaco, sueño o
metros recorridos además de tener acceso a notificaciones del teléfono
como llamadas, mensajes, correos o notificaciones Twitter por ejemplo.

Xamarin Microsoft Band 01

Además, Microsoft lanzó Microsoft Health, una plataforma en la nube donde controlar todos los datos recogidos relacionados con la salud y la actividad física.

Microsoft Band

Es un wearable con 10 sensores (incluido GPS), pantalla táctil y
batería para hasta 2 días de uso continuo (de media) que se basa en tres
pilares fundamentales:

  1. Salud: Podemos tener información como el número de pasos, pulsaciones, calidad del sueño, ritmo cardiaco, etc.
  2. Productividad: Notificaciones de llamadas perdidas, mensajes, Twitter además de alertas de calendario e incluso Cortana.
  3. Conectividad: App en teléfono en la que obtener más información, históricos, etc.
App móvil

App móvil

Creando proyecto

Para probar todas las opciones de la Microsoft Band vamos a crear un nuevo proyecto desde cero:

Nueva App Xamarin.Forms

Nueva App Xamarin.Forms

Nuestro objetivo sera crear una App Xamarin.Forms destinada a iOS,
Android y Windows Phone que nos permita conectar con una Microsoft Band,
acceder a información de sus sensores, crear tiles, enviar notificaciones, vibraciones e incluso personalizarla.

Permisos

Debemos añadir los siguientes requisitos:

  • Android: Permiso para acceder a Bluetooth:

[assembly: UsesPermission(Android.Manifest.Permission.Bluetooth)]

  • Windows Phone: De igual forma, acceso a Bluetooth:
<DeviceCapability Name="bluetooth.rfcomm">
  <Device Id="any">
    <!-- Used by the Microsoft Band SDK -->
    <Function Type="serviceId:A502CA9A-2BA5-413C-A4E0-13804E47B38F" />
    <!-- Used by the Microsoft Band SDK -->
    <Function Type="serviceId:C742E1A2-6320-5ABC-9643-D206C677E580" />
  </Device>
</m2:DeviceCapability>

Xamarin Microsoft Band SDK

En Xamarin Components y en Nuget tenemos disponible Xamarin Microsoft Band SDK. Es un conjunto de librerías que nos permite extender nuestras Apps móviles integrándolas con la Band. Podremos:

  • Conectar a Band (o Bands)
  • Obtener información de la Band y de los sensores
  • Gestionar tiles y layouts
  • Notificaciones
  • Personalización

Antes de continuar y lanzarnos de lleno a programar, importante
resaltar que la Band ofrece un modelo de extensión, se requiere una App
móvil. Usaremos la Band para obtener información y como pantalla
auxiliar.

Conexión

Para poder interactuar con la Band, lo primero sera…conectar con la misma!. Utilizaremos el siguiente namespace:

using Microsoft.Band.Portable;

Utilizamos el método GetPairedBandsAsync para obtener el listado de Bands disponibles

private async Task LoadBands()        
{            
     Bands = new ObservableCollection<BandDeviceInfo>();            
      
     // Get paired Bands           
     IEnumerable<BandDeviceInfo> bands = await BandClientManager.Instance.GetPairedBandsAsync();
             
     foreach (var band in bands)            
     {               
          Bands.Add(band);    
     }        
}

Mostraremos al usuario el listado de Bands disponible, de modo que,
una vez seleccionada una de ella, utilizaremos la información disponible
en BandDeviceInfo para crear una instancia de BandClient que representará a la Band y nos permitirá trabajar con el resto de acciones (Tiles, notificaciones, etc).

Información de la Band

Una vez seleccionada una Band accedemos a una vista con información
de la misma. Pasamos la Band seleccionada como parámetro en la
navegación:

var bandInfo = navigationContext as BandDeviceInfo;

Podemos extraer información básica como el nombre de la Band de la clase BandDeviceInfo:

BandClient = await BandClientManager.Instance.ConnectAsync(BandInfo);

Podemos obtener más información relacionada con la Band gracias a la instancia de BandClient como la versión de Firmware o de Hardware:

IsConnected = BandClient.IsConnected;
FirmwareVersion = await BandClient.GetFirmwareVersionAsync();
HardwareVersion = await BandClient.GetHardwareVersionAsync();

BandClient representa la Band a la que hemos conectado.

Xamarin Microsoft Band 06Sensores

Entre las posibilidades que tenemos disponibles con la Band, una de
las más interesantes es sin duda obtener información de sensores.
Contamos con la siguiente lista de sensores en la Band:

Sensores

Sensores

Además de acelerómetro, pedómetro y algun sensor del que ya estamos
acostumbrados a encontrar en teléfonos u otros dispositivos, contamos
con sensores muy interesantes como la medición del ritmo cardiaco o UV.

Para trabajar con sensores utilizaremos el siguiente namespace:

using Microsoft.Band.Portable.Sensors;

Utilizando BandClient podemos acceder a SensorManager que nos permitirá acceder a todos los sensores:

var sensorManager = BandClient.SensorManager;

Para trabajar con sensores nos suscribiremos a eventos en los que recibiremos información tanto en valores decimales como Raw.

NOTA: En tiempos prolongados de conexión tiene un impacto negativo en la duración de la batería.

Veamos un ejemplo:

await _sensorManager.Distance.StartReadingsAsync(BandSensorSampleRate.Ms128);
sensorManager.Distance.ReadingChanged += (s, e) =>
{
     TotalDistance = e.SensorReading.TotalDistance;
     var speed = e.SensorReading.Speed;
     var pace = e.SensorReading.Pace;
     var currentmotion = e.SensorReading.CurrentMotion;
};

Nos suscribimos al evento StartReadingsAsync del sensor Distancia para acceder a información como ls velocidad o la distancia total recorrida.

NOTA: Para acceder a la información de alguno de
los sensores, se necesita el consentimiento por parte del usuario. Es
necesario para obtener información del ritmo cardiaco.

Tiles

Los Tiles (baldosas) son uno de los pilares fundamentales de la interfaz de usuario disponible en la plataforma Windows.

Para trabajar con los tiles utilizaremos el namespace:

using Microsoft.Band.Portable.Tiles;

Y la instancia de TileManager:

var tileManager = BandClient.TileManager;

Podemos tener hasta 13 Tiles diferentes e independientes en una
Microsoft Band, podemos obtener el número de “huecos” disponibles que
tenemos en la Band utilizando el método GetRemainingTileCapacityAsync:

// Load Remaining CApacity

RemainingCapacity = await tileManager.GetRemainingTileCapacityAsync();

También podemos obtener un listado de Tiles de nuestra Aplicación utilizados en la Band:

private async Task LoadTiles()
{
     var tiles = await tileManager.GetTilesAsync();
     Tiles = new ObservableCollection<BandTile>(tiles);
}

Utilizamos el método GetTilesAsync para obtener una colección de objetos BandTile.

Creando Tiles

Las Apps pueden crear uno o más tiles. Cada Tile cuenta con GUID e icono que lo identifica.

Tamaño del Icono

Tamaño del Icono

Para crear un nuevo Tile utilizaremos un objeto de tipo BandTile, definiremos un nuevo identificador (Guid) además de la información básica como título, icono, etc:

TileId = Guid.NewGuid();
TileName = "New Tile";
TileIcon = await ResourcesHelper.LoadBandImageFromResourceAsync("Resources/tile.png");
TileBadge = await ResourcesHelper.LoadBandImageFromResourceAsync("Resources/badge.png");

Utilizamos las propiedades anteriores para crear el tile:

var tile = new BandTile(TileId)
{
     Icon = TileIcon,
     Name = TileName,
     SmallIcon = TileBadge,
     IsScreenTimeoutDisabled = DisableScreenTimeout
};

Para añadirlo en la Band, utilizamos el método AddTileAsync disponible en TileManager pasando el objeto BandTile creado:

// Add Tile
await _tileManager.AddTileAsync(tile);

Cada Tile puede contar con hasta 8 páginas. El contenido de cada página es de 245 x 106 píxeles. Las páginas pueden mostrar un mensaje básico un utilizar un Custom Layout. Para crear custom layout utilizaremos un árbol de contenedores y elementos.

Contenedores y Elementos

Contenedores y Elementos

Podemos añadir Custom Layout al Tile añadiendo una colección de objetos PageLayout a la propiedad PageLayouts del tile.

// Tile Custom Layouts
var layouts = CreatePageLayouts();
tile.PageLayouts.AddRange(layouts);

Contamos con varios contenedores que nos permiten organizar los elementos de la página:

  • FlowPanel: Organiza los elementos apilando vertical u horizonalmente.
  • ScrollFlowPanel: Similar al anterior pero añadiendo Scroll.
  • FilledPanel: Rectángulo relleno con un color de fondo.

Además de elementos básicos que nos permiten incluir imágenes, texto, código de barras y botones.

  • TextBlock: Muestra texto.
  • WrappedTextBlock: Similar al anterior pero el texto puede hacer wrapping.
  • Icon: Imágenes.
  • Barcode: Código de barras en diferentes formatos.
  • TextButton: Botón con formato texto.
  • FilledButton: Botón.
new PageLayout {                 
   Root = new ScrollFlowPanel {                      
        Rect = new PageRect(0, 0, 245, 105),                  
        Orientation = FlowPanelOrientation.Vertical,    
        Elements = {
             new TextBlock
             {
                  ElementId = 11,                   
                  Rect = new PageRect(0, 0, 230, 30),                
                  Color = new BandColor(255, 0, 0),             
                  AutoWidth = false,                        
                  HorizontalAlignment = HorizontalAlignment.Center,               
                  VerticalAlignment = VerticalAlignment.Bottom             
             },        
             new Barcode {                   
                  ElementId = 12,          
                  Rect = new PageRect(0, 0, 230, 61),     
                  BarcodeType = BarcodeType.Code39,                     
             },
             new TextBlock
             {
                  ElementId = 13,          
                  Rect = new PageRect(0, 0, 230, 30),                           
                  Color = new BandColor(255, 0, 0),
                  AutoWidth = false,       
                  HorizontalAlignment = HorizontalAlignment.Center,              
                  VerticalAlignment = VerticalAlignment.Bottom                            
             },   
             new Barcode {                      
                  ElementId = 14,
                  Rect = new PageRect(0, 0, 230, 61),
                  BarcodeType = BarcodeType.Pdf417,      
             }          
        }              
   }           
}

Podemos por supuesto también indicar el contenido de textos, botones, códigos de barra etc utilizando el método SetTilePageDataAsync disponible en TileManager:

// Update with page data
var datas = CreatePageDatas();
await _tileManager.SetTilePageDataAsync(tile.Id, datas);

El contenido:

new PageData {       
     PageId = Guid.NewGuid(),      
     PageLayoutIndex = 0,           
     Data = {
          new TextBlockData {               
               ElementId = 11,              
               Text = "Code 39"                 
          },                       
          new BarcodeData {                           
               ElementId = 12,                          
               BarcodeType = BarcodeType.Code39,                
               BarcodeValue = "HELLO"            
          },
          new TextBlockData {                     
              ElementId = 13,                       
              Text = "Pdf 417"                   
          },                        
          new BarcodeData {              
              ElementId = 14,     
              BarcodeType = BarcodeType.Pdf417,           
              BarcodeValue = "0246810"                    
          }                   
     }              
}

La asociación de contenido y elemento la realizamos utilizando el identificador del elemento, ElementId.

Notificaciones

Seleccionado un Tile anclado en la Band, con su correspondiente
identificador, podremos trabajar con notificaciones. Para ello
utilizaremos el siguiente namespace:

using Microsoft.Band.Portable.Notifications;

El objeto NotificationManager será nuestro aliado en esta ocasión.

var notifiactionManager = BandClient.NotificationManager;

Recibimos como parámetro de navegación tanto el identificador del tile como BandClient:

public override void OnAppearing(object navigationContext)
{
     var notificationData = navigationContext as NotificationData;
     if (notificationData != null)
     {
          BandClient = notificationData.BandClient;
          _tile = notificationData.Tile;
     }
 
     _notifiactionManager = BandClient.NotificationManager;
 
     base.OnAppearing(navigationContext);
}

Utilizando NotificationManager podremos enviar notificaciones utilizando los métodos:

  • SendMessageAsync: Envía un mensaje a un Tile de la App con posibilidad de mostrar un diálogo.
  • ShowDialogAsync: Muestra un diálogo en la Band asociado a uno de los Tiles de la App.

Para enviar un mensaje a la Band utilizamos el método SendMessageAsync donde podemos pasar título y contenido:

await notifiactionManager.SendMessageAsync(_tile.Id, Title, Body, DateTime.Now);

Podemos indicar facilmente con otro parámetro que deseamos mostrar un diálogo:

await notifiactionManager.SendMessageAsync(_tile.Id, Title, Body, DateTime.Now, true);

Utilizando el método ShowDialogAsync podemos mostrar un diálogo directo en la Band:

await notifiactionManager.ShowDialogAsync(_tile.Id, Title, Body);

Sencillo, ¿verdad?

Vibración

Continuamos con otras opciones disponibles con las que podemos
interactuar con la Band. Una forma sencilla pero muy potente para
notificar al usuario es enviar notificaciones hápticas o vibraciones.
Tenemos una enumeración de tipo VibrationType con las siguientes opciones:

  • NotificationOneTone
  • NotificationTwoTone
  • NotificationAlarm
  • NotificationTimer
  • OneToneHigh
  • TwoToneHigh
  • ThreeToneHigh
  • RampUp
  • RampDown
public ObservableCollection<string> GetVibrationTypes()   
{          
     var names = Enum.GetNames(typeof(VibrationType));     
     var split = names.Select(n =>                
          string.Concat(n.ToCharArray().Select(c =>                 
          char.IsUpper(c) ? " " + c : c.ToString())));
            
     return new ObservableCollection<string>(split.ToList());
}

Utilizamos el método VibrateAync disponible en NotificationManager indicando el tipo de la vibración:

await notifiactionManager.VibrateAsync((VibrationType)_vibrationIndex);

Personalización

Para trabajar con notificaciones utilizaremos el siguiente namespace:

using Microsoft.Band.Portable.Personalization;

Y PersonalizationManager:

var personalizationManager = BandClient.PersonalizationManager;

Podremos:

  • Cambiar imagen “Me Tile”
  • Modificar colores del tema

La imagen “Me Tile”:

Me Tile

Me Tile

Es una imagen de 310 x 102 píxeles mostrada en la pantalla principal
de la Band. Podemos establecer la imagen utilizando el método SetMeTileImageAsync:

MeTileImage = await ResourcesHelper.LoadBandImageFromResourceAsync("Resources/metile.png");
await personalizationManager.SetMeTileImageAsync(MeTileImage);

También podemos editar el tema de la Band basado en un conjunto de colores:

Colores del tema

Colores del tema

Base = new BandColor(10, 110, 20);
HighContrast = new BandColor(20, 120, 30);
Highlight = new BandColor(30, 130, 40);
Lowlight = new BandColor(40, 140, 50);
Muted = new BandColor(50, 150, 60);
SecondaryText = new BandColor(60, 160, 70);

Estableciendo el tema utilizando el método SetThemeAsync pasándole un objeto de tipo BandTheme que contiene todo el conjunto de colores usados en diferentes estados:

await _personalizationManager.SetThemeAsync(new BandTheme
{
     Base = Base,
     HighContrast = HighContrast,
     Highlight = Highlight,
     Lowlight = Lowlight,
     Muted = Muted,
     SecondaryText = SecondaryText
});

Podéis descargar el ejemplo completo realizado a continuación:

También tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordar que podéis dejar en los comentarios cualquier tipo de sugerencia o pregunta.

One more thing

WebTiles

Recientemente el equipo de Microsoft Band liberaron los Web Tiles.
Los Web Tiles son una forma fácil y sencilla de poder crear nuevos
Tiles que muestren información desde una URL que devuelva información en
JSON, RSS o ATOM feed sin necesidad de grandes conocimientos ni
programación.

Para ello, accederemos al siguiente enlace y completaremos el asistente paso a paso.

Microsoft Health APIs

Es una plataforma abierta de APIs Rest que nos permite a los
desarrolladores acceder a información de sensores, históricos y otras
opciones para poder crear Apps de salud y deporte de alta calidad.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *