だいぶ前にNAVITIMEでカーナビリモコンを先着で配ってました。
とりあえず貰っとけ!と応募したところあっさり当選して、だいぶ時間が経ったところで届いてきました。
元々は専用のアプリに反応するようですが、ペアリングが不要でBluetooth LE使うって書いてあったので、これは何かに使えるのでは!?と思い探ってみました。
UWPでBluetooth LEの通信を拾う
実装
Bluetooth LEの場合は、BluetoothLEAdvertisementWatcher クラスを使うようです。
// Using using Windows.Devices.Bluetooth.Advertisement; // 初期化 BluetoothLEAdvertisementWatcher ble = new BluetoothLEAdvertisementWatcher(); // イベント定義 ble.Received += Ble_Received; // 開始 ble.Start();
受信する度にイベント発動します。
private async void Ble_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { // この中にデータがある var datRecv = args.Advertisement.ManufacturerData.FirstOrDefault(); if (datRecv != null) { // ストリームの中を抽出します using (BinaryReader br = new BinaryReader(datRecv.Data.AsStream())) { // 何か数値がとれました var data = br.ReadInt32().ToString("0"); } } }
dataの変数に数値形式で値が入ってくるようです。
クリック回数、ホールドでそれぞれ値が変わって、下何桁かがカウントアップされていくようです。
手元のやつだと、
- 1クリック → 頭4桁が"1684"
- 2クリック → 頭4桁が"1690"
- ホールド → 頭4桁が"3362"
こんな感じでした。ホールドは押してる間周期的にカウントアップされた値が飛んできました。カウントアップしていく性質上、デバイスによって設定値が違う気がします。もう1台くらいあれば裏が取れるんですがねー。
また、フィルタリングしないと周りで発してる電波を軒並み拾ってしまいます。今回の場合、CompanyIdでフィルタリングしました。
var cd = new BluetoothLEManufacturerData(); cd.CompanyId = 0x0059; ble.AdvertisementFilter.Advertisement.ManufacturerData.Add(cd);
CompanyIdは受信したデータから取れるので探りをいれて取りました。
また、終了処理も入れておきましょう。OnNavigatedFromあたりに入れておけば大丈夫そうです。
ble.Stop();
レスポンスはそれほど速くないので、スピード感を要求する場合は別の方法を取ったほうが良いかもしれないです。それでもこんな簡単にBluetoothLE取れるとは思いませんでした。
通常のBluetooth(ペアリングする方)の場合は、また実装方法が違いそうですね。
実装したアプリ
Multi Function Display に実装をして現在審査中です。
とりあえず1クリックで、ミラーモードのOn/Offを切り替えるようにしてみました。画面にタッチせずアプリを操作できるってなんか気持ち良かったので、アプリ自体の機能を増やしたら色々連携してみたいと思います。
久々にコード入りの記事書いた(笑)