2015 年 10 月

第 30 卷,第 10 期

本文章是由機器翻譯。

Microsoft Band - 使用 Microsoft Band SDK 開發 Windows 10 應用程式

Kevin 艾

Microsoft Bing 預測 wearables 2015 就會在技術中最熱門的趨勢 (binged.it/1hCBv9A)、 個人數位助理、 家庭自動化、 3D 列印和虛擬實境遊戲之前。

一個這類裝置,Microsoft 頻外結合了大部分人需要追蹤它們的健康情況、 適用性、 睡眠品質和更多的感應器。它在市場上套件和許多更耗費資源的可用裝置的多個感應器。

身為行動裝置應用程式開發人員,我想要建立實用的應用程式與 Microsoft 頻外。我在我 Active 售的應用程式 (activefitness.co) 具有超過 2 百萬個使用者在 Windows、 iOS 及 Android 中使用這個程式碼中使用的範例部分。大部分的取用者應用程式需要在 Windows、 iOS 和 Android 到達最大的對象等的多個平台上運作。在本文中我將說明如何開發 Windows 10 應用程式群組列及瀏覽跨平台選項。它是參與頻外 SDK 的早期版本的榮耀。既然它已經公開提供,我可以共用透過樂團 SDK 和開發人員社群的最新發行版本增強的程式碼範例。

重力英雄: Windows 10 範例應用程式

我想要建置有趣的東西展示了頻外功能,並且在同一時間的運作方式幾乎類似遊戲。所以我建置通用 Windows 應用程式呼叫 「 重力英雄"中所示 [圖 1。我們的構想是非常簡單的: 您跳穿著寬和裝置會告訴您您是否讓您最佳的跳過。而且因為我建置通用 Windows 應用程式時,它就能在任何 Windows 10 裝置上。我也會加入為原生的 Android 應用程式來示範如何輕鬆地針對其他裝置的 GitHub 上的範例程式碼。此外,帶開發人員網站包含文件和 SDK 程式碼範例連結 (developer.microsoftband.com)。

重力英雄範例應用程式在 Windows 10 上執行
[圖 1 重力英雄範例應用程式在 Windows 10 上執行

Microsoft 頻外小組提供 Sdk for Windows、 iOS 和 Android。此外,是透過 Xamarin,技術,可讓重複使用很棒的程式碼的跨平台 SDK 解決方案。您應該選擇哪一種技術? Microsoft 和社群支援,您會有下列選項群組列裝置進行開發時:

  • 原生開發與 Windows、 iOS 和 Android 的 Microsoft 頻外 SDK (Microsoft) (bit.ly/1JfiFvW)
  • 快速傳遞資訊帶到幾個簡單的步驟中的任何 Web 來源 web 磚 SDK (Microsoft) (bit.ly/1h94CjZ)
  • 雲端應用程式開發介面 (Microsoft) 的 RESTful Api 存取完整的適用性和健全狀況資料以容易取用的 JSON 格式 (bit.ly/1MIBOL7)
  • 跨平台 SDK (Xamarin) 用於 Xamarin 跨平台應用程式,針對 iOS、 Android 和 Windows。透過 Xamarin 可用於單一程式碼基底所有平台 (bit.ly/1EfhqjK)

如果您已經有 Windows、 iOS 或 Android 應用程式,只要這些平台的每個使用原生的頻外 SDK。如果您從頭開始或想要以相同的程式碼的所有平台為目標,您可能想要看一下 Xamarin。任君挑選。平台方便的方法可讓您開始建置應用程式所需的所有選項。在本文中我將討論這兩個選項。

連接到 Windows 10 PC 的寬線

在開始開發之前,您必須連接到 Windows 10 PC 的寬線。這是很容易進行 Windows 10 會包括藍芽支援:

在您的樂團翻轉] 設定] 並排顯示] 及 [藍芽圖示切換到 Pairing。您的樂團現在為配對模式。Windows 10 在電腦上,移至設定或輸入 Cortana 藍芽並開啟藍芽設定] 頁面中所示 [圖 2。請注意您在清單中的樂團的藍芽裝置的狀態。範圍名稱通常以開始您的名稱和程式碼,除非您變更為其他項目 (在此情況下,我有"Kevin 的頻外 ec:5a")。如果這個狀態顯示為 「 已連接 」,就得了。否則,點選組並遵循提示。

連接 Microsoft 帶到 Windows 10 PC
[圖 2 Windows 10 pc 連接 Microsoft 頻外

在 Visual Studio 建立 Windows 10 應用程式

您可以使用我在 GitHub 建立的範例應用程式啟動 (bit.ly/1U2sLup)。請記住是否您決定要從頭開始建立您的應用程式,需要 Bluetooth 裝置功能納入您的資訊清單。Visual Studio 中預設不會在應用程式範本中包含這項功能:

<Capabilities>
  <DeviceCapability Name="bluetooth" />
</Capabilities>

如果您加入您自己的應用程式的寬線或從頭開始建立 Windows 10 應用程式也您需要取得 Microsoft 頻外 NuGet 封裝。有數個封裝就一些建立由 Microsoft 和一些加入由社群成員 (例如 Xamarin.Microsoft.Band 封裝)。Windows 通用應用程式中為了我加入了 Microsoft 套件中所示 [圖 3

Microsoft 頻外 NuGet 封裝
[圖 3 Microsoft 頻外 NuGet 封裝

Microsoft 頻外 SDK 可讓開發人員存取頻外,建立並更新磚和個人化裝置上的感應器。您的應用程式可以傳送通知,包括 haptics,以寬。寬本身有不錯、 清楚且簡單的外觀,示 [圖 4

Microsoft Band
[圖 4 Microsoft 頻外

寬富含感應器 (中可以看到的完整清單 [圖 5); 為了我重力主題榜的範例應用程式,把焦點放在加速計感應器。

[圖 5 Microsoft 帶狀上可用的感應器

感應器 詳細資料
加速計 提供以 g 單位的 X、 Y 和 Z 加速。1 g = 9.81 每秒公尺第二個平方 (m/s2)。
提供 X、 Y 和 Z angular 速度的度數表示每個第二個 (° / 秒) 單位。
距離 提供以公分為單位,以公分為單位每秒 (cm/s) 的目前速度的總距離以毫秒為單位每個計量器 (ms/m) 的目前進度和目前 pedometer 模式 (例如查核或執行)。
核心速率

提供數個分擊敗每分鐘。也會指出核心速率感應器已完整鎖定到兼核心速率。

傳回的資料應該只能用於上來模式。頻外 SDK 並不提供最佳化的任何其他活動之核心速率值存取權。

Pedometer 提供步驟已經兼的總數。
面板溫度 提供以攝氏兼目前面板溫度。
UV 提供目前 ultraviolet 輻射曝光濃度。
帶連絡人 提供做為正在 not 磨損磨損寬線的目前狀態。
卡路里 提供兼有的卡洛總數。

設計資料模型

如往常,我開始在 Visual Studio 中的資料模型中所示 [圖 6。良好的資料模型永遠可幫助,因為它將資料分隔到不同的層,可以輕鬆共用您的應用程式和甚至雲端後端如果您決定將顯示您資料的網站。我想要讓我靈活地從感應器收集資料並呈現它們重力英雄應用程式中的資料模型。我可以重複使用我的資料模型中其他應用程式,因此值得將其放在我的 Visual Studio 方案中的另一個資料夾中。

Visual Studio 方案與範例專案和資料模型
[圖 6 與範例專案和資料模型的 Visual Studio 方案

重力英雄應用程式的資料模型使用方便地呼叫 ViewModel helper 類別。我可以使用各種現有 Model View ViewModel (MVVM) helper 程式庫,但在本例中我只是實作一個讓程式碼盡量透明化。ViewModel 類別會實作 INotifyPropertyChanged 介面。這是相當標準的方法在.NET 應用程式時您想要在您在 UI 中的資料模型中反映變更。在我的範例應用程式實作中,我想要確定類別通知透過 PropertyChanged 機制 UI。

SensorReading 是攔截頻外感應器讀數並通知訂閱的資料模型變更 UI 中的任何項目類別。讓我們更仔細看看這個類別。此類別衍生自先前介紹 ViewModel 而且也包含要將資料序列化並透過網路傳送 (給您雲端儲存體,例如) 就相當實用的屬性。DataContract SensorReading 類別上的屬性就是並在個別資料成員的 DataMember 屬性可讓資料進行序列化,可能是 JSON 或 XML 序列化程式根據。SensorReading 類別的另一個好處是因為類別保留 3D 向量讀取或 Vector3 提供標準化的表單。中所示 [圖 7, ,我也會提供傳回正規化的向量 (非常有用的事情時應付 3D 計算) 的值成員。

[圖 7 SensorReading 類別感應器資料模型

[DataContract]
public class SensorReading : ViewModel
{
  DateTimeOffset _timestamp;
  [DataMember]
  public DateTimeOffset Timestamp
  {
    get { return _timestamp; }
    set
    {
      SetValue(ref _timestamp, value, "Timestamp");
    }
  }
  double _x;
  [DataMember]
  public double X
  {
    get { return _x; }
    set
    {
      SetValue(ref _x, value, "X", "Value");
    }
  }
  double _y;
  [DataMember]
  public double Y
  {
    get { return _y; }
    set
    {
      SetValue(ref _y, value, "Y", "Value");
    }
  }
  double _z;
  [DataMember]
  public double Z
  {
    get { return _z; }
    set
    {
      SetValue(ref _z, value, "Z", "Value");
    }
  }
  public double Value
  {
    get
    {
      return Math.Sqrt(X * X + Y * Y + Z * Z);
    }
  }
}

BandModel 用來管理範圍中所示 [圖 8。這是可幫助萬一我有多個群組列裝置連線到我的 PC; 管理員類別它也可以告訴我是否已連接任何帶。

[圖 8 BandModel 管理群組列

public class BandModel : ViewModel
{
  static IBandInfo _selectedBand;
  public static IBandInfo SelectedBand
  {
    get { return BandModel._selectedBand; }
    set { BandModel._selectedBand = value; }
  }
  private static IBandClient _bandClient;
  public static IBandClient BandClient
  {
    get { return _bandClient; }
    set
    {
      _bandClient = value;
    }
  }
  public static bool IsConnected
  {
    get {
      return BandClient != null;
    }
  }
  public static async Task FindDevicesAsync()
  {
    var bands = await BandClientManager.Instance.GetBandsAsync();
    if (bands != null && bands.Length > 0)
    {
      SelectedBand = bands[0]; // Take the first band
    }
  }
  public static async Task InitAsync()
  {
    try
    {
      if (IsConnected)
        return;
      await FindDevicesAsync();
      if (SelectedBand != null)
      {
        BandClient =
          await BandClientManager.Instance.ConnectAsync(SelectedBand);
        // Connected!
          BandModel.BandClient.NotificationManager.VibrateAsync(
            Microsoft.Band.Notifications.VibrationType.ExerciseRunLap);
      }
    }
    catch (Exception x)
    {
      Debug.WriteLine(x.Message);
    }
  }
}

AccelerometerModel 是特別設計供重力英雄遊戲。重力是有效的寬線中內建的加速計感應器來測量的力量。現在您會看到如何建立資料模型類別。您可以加入其他任何您想要使用應用程式中的寬線感應器的類別。我需要初始化加速計類別 Init 方法中的,我訂閱方便頻外 SDK 所提供的幾個事件:

if (BandModel.IsConnected)
  {
    BandModel.BandClient.SensorManager.
      Accelerometer.ReadingChanged +=
      Accelerometer_ReadingChanged;
    BandModel.BandClient.SensorManager.
      Accelerometer.ReportingInterval =
      TimeSpan.FromMilliseconds(16.0);
    BandModel.BandClient.SensorManager.
      Accelerometer.StartReadingsAsync(
      new CancellationToken());
    totalTime = 0.0;
  }

第一個事件是要在 ReadingChanged。這是可以讓我從加速計感應器根據 ReportingInterval 我定義的時間週期的資料事件。讀取加速計值,我使用 16 ms 臨界值。請務必保留報表間隔越小越有效位數,但在此同時請考慮電池耗用量會增加大量使用感應器。接下來,我呼叫 StartReadingsAsync,開始從感應器讀取值並將它傳回到應用程式的方法。此方法只會啟動感應器資料的讀數的接聽程式。資料會傳遞至要在 ReadingChanged 事件。

要在 ReadingChanged 事件中我會擷取讀取和我的資料模型中重新計算的值:

void Accelerometer_ReadingChanged(object sender,
  BandSensorReadingEventArgs<IBandAccelerometerReading> e)
{
  SensorReading reading = new SensorReading {
    X = e.SensorReading.AccelerationX, Y = e.SensorReading.AccelerationY,
    Z = e.SensorReading.AccelerationZ };
  _prev = _last;
  _last = reading;
  Recalculate();
}

重新計算模型方法是大部分的我邏輯的發生位置 (請參閱 [圖 9)。我想我超過達成稍早當我開始遊戲時的值時引發回應用程式已變更 」 事件。請記住,我實作重力英雄遊戲,因此我正在尋找最佳的結果。我想要確定我使用發送器類別因為可能會在非 UI 執行緒上觸發頻外感應器事件,所以我需要封送處理至 UI 執行緒我已變更 」 事件的程式碼。

[圖 9 重新計算模型方法

DateTimeOffset _startedTime = DateTimeOffset.MinValue;
double totalTime = 0.0;
double lastTime = 0.0;
SensorReading _prev;
SensorReading _last;
double MIN = 0.4;
void Recalculate()
{
  if (_last.Value <= MIN)
  {
    if (_startedTime > DateTimeOffset.MinValue)
      lastTime = (DateTimeOffset.Now - _startedTime).TotalSeconds;
    else
      _startedTime = DateTimeOffset.Now;
    }
    else
    {
      if (_startedTime > DateTimeOffset.MinValue)
      {
        lastTime = (DateTimeOffset.Now - _startedTime).TotalSeconds;
        totalTime += lastTime;
        lastTime = 0.0;
        _startedTime = DateTimeOffset.MinValue;       
          CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
          CoreDispatcherPriority.Normal,        () =>
        {
          if (Changed != null)
            Changed(_last.Value);
            });
        }
      }
    }
¡  } 
}

我 UI 需要更新時帶回來自事件 (請參閱 [圖 10)。這是我在 MainPage.xaml 中訂閱的已變更 」 事件。我顯示 G 力和計數的成就。我也叫用 VibrateAsync 方法透過樂團 haptic 意見反應。以頻外使用者了幾個月,我真的很喜歡傳送 haptic 通知的能力 (只要記得在不濫用它並通知使用者只有適當的時候)。

[圖 10 更新已變更的事件中的 UI

void _accelerometerModel_Changed(double force)
{
  bandCount++;
  UpdateCount();
  if (force > maxForce)
  {
    maxForce = force;
    heroText.Text = String.Format("Intensity {0:F2}G", maxForce);
  }
  if (!isAchievementUnlocked && bandCount >= maxCount*0.2)
  {
    Speak("Just a few more!");
    isAchievementUnlocked = true;
  }
  if (!isSecondAchievementUnlocked && isAchievementUnlocked &&
    bandCount >= maxCount * 0.8)
  {
    Speak("Almost there!");
    isAchievementUnlocked = true;
  }
    BandModel.BandClient.NotificationManager.VibrateAsync(
      Microsoft.Band.Notifications.VibrationType.ExerciseRunLap);
  // Speak(bandCount.ToString()+"!");
}

讓很有趣的事情開始

現在的一切就地讓有趣開始。建置並啟動應用程式: 請記住,在任何 Windows 10 裝置上執行的應用程式。因為我使用帶感應器,我不用管關於 PC 或電話支援加速計。我將使用 PC 寬執行所有繁重的工作時顯示從頻的資訊。

中所示 [圖 11, ,當您第一次啟動應用程式從 Visual Studio 或並排顯示從 Windows 10 會自動提示您確認您想要重力英雄應用程式權限授予寬; 只選取 [是]。

Windows 10] 對話方塊會自動要求存取群組列
[圖 11 Windows 10] 對話方塊會自動要求存取群組列

當重力英雄連接到寬時,您會覺得震動寬。這是為了刻意,讓您知道所有項目設定跳躍點。我還加入了可發出聲音的提示來通知您可以啟動動作:

BandModel.BandClient.NotificationManager.VibrateAsync(
  Microsoft.Band.Notifications.VibrationType.ExerciseRunLap);

現在,請跳過。應用程式將會計算您跳恭賀您在每一項成就。

這個發行項的所有範例程式碼都是從 github 即可取得: bit.ly/1MIKIIK。若要使用此來源您可以使用 Visual Studio 2015 和 Windows 10。專案會使用 Microsoft 頻外 SDK NuGet 封裝。

總結

Microsoft Band 提供強大的 SDK,以及 Windows、Android 和 iOS 等多個平台的社群支援。開發人員可以使用 Microsoft Sdk 以及從 Xamarin、 GitHub 和開發人員社群的社群元件來擴充應用程式以使用 Microsoft 頻外。您可以使用本文中的程式碼整合到您自己的應用程式的 Microsoft 頻外 Windows 10。


Kevin 艾是 microsoft 的資深的遊戲開發人員推廣者。他是 「 專業人員 Windows 8 程式設計 」 (Wrox 2012) 的共同作者和開發人員的最上層的應用程式和遊戲,最值得注意的是 Active 適用性,具有超過 2 百萬個使用者 (activefitness.co)。他經常提供在各種事件、 產業顯示和網路廣播的技術。在角色中,他負責啟動與夥伴,建議您在軟體設計、 商務和技術策略、 架構和開發。您可以在他的部落格上依照艾 kevinashley.com 和在 Twitter 上 @kashleytwit

感謝以下的微軟技術專家對本文的審閱: Jaime Rodriguez