本日は HoloLens の技術調査枠です。
前回とは逆に、HoloLensの3DアプリでBlueToothAdvertisementを送信する方法を記事にします。
以下の記事の続きです。
bluebirdofoz.hatenablog.com
プロジェクトとシーンの準備
以下の記事を元にHoloLens(WindowsMR)プロジェクトを作成します。
bluebirdofoz.hatenablog.com
2019/5/3現在、MRTK 2017 の最新バージョンは 2017.4.3.0 です。
BluetoothAdvertisementを参考に作成したサンプルコード
BluetoothAdvertisement のパブリッシャクラスのコードを参考に、Advertisement を送信するクラスを作成しました。
・BluetoothAdvertisePublisher.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; #if WINDOWS_UWP using System; using Windows.Storage.Streams; using Windows.Devices.Bluetooth; using Windows.Devices.Bluetooth.Advertisement; #endif public class BluetoothAdvertisePublisher : MonoBehaviour { /// <summary> /// テキストオブジェクトの参照 /// </summary> public UnityEngine.UI.Text MessageText; string showmessage; /// <summary> /// 起動時処理 /// </summary> void Start() { App_Message("Start"); #if WINDOWS_UWP // 初期化 Awake_BluetoothLEAdvertisementPublisher(); // ハンドラ登録 OnEnable_BluetoothLEAdvertisementPublisher(); // パブリッシャ起動 Run_BluetoothLEAdvertisementPublisher(); #endif } /// <summary> /// 定期実行 /// </summary> private void Update() { if (showmessage.Length != 0) { MessageText.text = showmessage; showmessage = ""; } } /// <summary> /// テキスト更新 /// </summary> /// <param name="message">メッセージ</param> void App_Message(string message) { showmessage = message; } /// <summary> /// 終了時処理 /// </summary> void OnApplicationQuit() { #if WINDOWS_UWP // 終了 OnDisable_BluetoothLEAdvertisementPublisher(); #endif } #if WINDOWS_UWP /// <summary> /// Bluetooth LE advertisement の制御とカスタマイズに使用するBluetoothLEAdvertisementPublisher /// </summary> private BluetoothLEAdvertisementPublisher publisher; /// <summary> /// BluetoothLEAdvertisementPublisher初期化(Awake) /// </summary> public void Awake_BluetoothLEAdvertisementPublisher() { // 新しいパブリッシャインスタンスを作成して初期化します。 publisher = new BluetoothLEAdvertisementPublisher(); // advertisement にペイロードを追加する必要があります。 // ペイロードがない、または無効なパブリッシャーは起動できません。 // ペイロードを設定する必要があるのは、どのパブリッシャに対しても1回だけです。 // manufacturer-specific セクションを追加します。 // まず、製造元データセクションを作成します。 var manufacturerData = new BluetoothLEManufacturerData(); // 製造元データのIDを設定します。ここでは 0xFFFE の値を指定します。 manufacturerData.CompanyId = 0xFFFE; // manufacturer-specific セクション内にデータペイロードを設定します // ここでは以下の16ビットのUUIDを使用します。 // 0x1234 - > { 0x34、0x12}(リトルエンディアン) var writer = new DataWriter(); UInt16 uuidData = 0x1234; writer.WriteUInt16(uuidData); // 書き込みデータのバッファ長はアドバタイズペイロードに収まる必要があります。 // 収まらない場合は例外が発生します。 manufacturerData.Data = writer.DetachBuffer(); // 製造元データを advertisement パブリッシャに追加します。 publisher.Advertisement.ManufacturerData.Add(manufacturerData); } /// <summary> /// BluetoothLEAdvertisementPublisher初期化(OnEnable) /// </summary> public void OnEnable_BluetoothLEAdvertisementPublisher() { // パブリッシャのステータスを監視するためのイベントハンドラを登録します。 // これにより、advertisement が提供されたかどうか、がわかります。 // また、Bluetooth がユーザーによってオフになっているなどの予期しないエラーについても通知します。 publisher.StatusChanged += OnStatusChanged_AdvertisementPublisher; } /// <summary> /// BluetoothLEAdvertisementPublisher終了(OnDisable) /// </summary> public void OnDisable_BluetoothLEAdvertisementPublisher() { // コンテキストを離れるときは、パブリッシャを停止します。 // パブリッシャが停止されていなくても、パブリッシャが破棄されるとスキャンは自動的に停止します。 publisher.Stop(); // リークを防ぐためにリソースを解放する場合、ハンドラの登録を解除します。 publisher.StatusChanged -= OnStatusChanged_AdvertisementPublisher; } /// <summary> /// BluetoothLEAdvertisementPublisherサスペンド時処理 /// </summary> public void Suspending_BluetoothLEAdvertisementPublisher() { // 中断時にはパブリッシャを停止します。 publisher.Stop(); // リークを防ぐためにリソースを解放する場合、ハンドラの登録を解除します。 publisher.StatusChanged -= OnStatusChanged_AdvertisementPublisher; } /// <summary> /// BluetoothLEAdvertisementPublisher再開時処理 /// </summary> public void Resuming_BluetoothLEAdvertisementPublisher() { // ハンドラを登録してパブリッシャを再開します。 publisher.StatusChanged += OnStatusChanged_AdvertisementPublisher; // 再開時にパブリッシャを開始します。 publisher.Start(); } /// <summary> /// BluetoothLEAdvertisementPublisher実行処理(Run) /// </summary> public void Run_BluetoothLEAdvertisementPublisher() { // パブリッシャの Start() を呼び出すと advertisement が開始されます。 publisher.Start(); } /// <summary> /// BluetoothLEAdvertisementPublisher停止処理(Stop) /// </summary> public void Stop_BluetoothLEAdvertisementPublisher() { // パブリッシャの Stop() を呼び出すと advertisement が停止します。 publisher.Stop(); } /// <summary> /// パブリッシャのステータスが変更されたときにイベントハンドラとして呼び出されます。 /// </summary> /// <param name="publisher">イベントをトリガーした発行者のインスタンス</param> /// <param name="eventArgs">発行者ステータス変更イベントに関する情報を含むイベントデータ</param> private async void OnStatusChanged_AdvertisementPublisher( BluetoothLEAdvertisementPublisher publisher, BluetoothLEAdvertisementPublisherStatusChangedEventArgs eventArgs) { // このイベントハンドラを使用して、発行者のステータスを監視できます。 // パブリッシャーがシステムによって中止された場合、エラーを検出できます。 BluetoothLEAdvertisementPublisherStatus status = eventArgs.Status; BluetoothError error = eventArgs.Error; // 変更イベント処理を行う // 変更イベントメッセージをテキストオブジェクトに表示する App_Message("StatusChange Event"); } #endif }
Empty オブジェクトを作成し、本スクリプトをアタッチしました。
スクリプトの MessageText にテキストオブジェクトの参照を追加します。
Capabilityの追加
UWPアプリで Bluetooth を利用する場合、Capability の設定が必要です。
メニューから Edit -> Project Settings - Player を開きます。
Inspector ビューから Publishing Setttings を開きます。
[Capabilities]欄の[Bluetooth]にチェックを入れます。
後は HoloLens 向けにプロジェクトをビルドしてインストールします。
UnityプロジェクトのビルドとHoloLensへのインストール手順については以下を参照してください。
bluebirdofoz.hatenablog.com
HoloLensでの動作確認
この状態で HoloLens 上で動作確認を行います。
HoloLens 上でアプリを起動すると、Bluetooth のアドバタイズが送信されます。
受信側アプリの実行
PC側で前回ビルドした BluetoothAdvertisement アプリを起動します。
[Foreground watcher]のタブを開き、[Run]を実行して BlueTooth のアドバタイズを受信します。
HoloLens で送信されたアドバタイズを受信すると、IDとデータ値が表示されます。