LoginSignup
17
27

More than 3 years have passed since last update.

iBeaconをスキャンするWindowsデスクトップアプリ

Last updated at Posted at 2018-05-19

はじめに

iBeaconのアドバタイズパケットをスキャンするWindowsアプリを作ってみる。

環境

プログラムを作る

プロジェクト作成


2020/8/31追記
Microsoft.Windows.SDK.Contractsについて
UwpDesktopは現在開発が止まっており、代わりにMicrosoft.Windows.SDK.Contractsで同じことができます。

  • Windows 10 WinRT API PackがNuGetパッケージMicrosoft.Windows.SDK.Contractsとして公開されています。
  • 開発プロジェクトをPackageReference対応へ設定変更し、NuGetパッケージを追加するだけで利用可能。

詳細
- Microsoft、Windows 10の機能を簡単にWinForms/WPFアプリへ組み込めるライブラリを公開
- デスクトップアプリで UWP Api を呼び出す


プログラミング①

  • usingにWindows.Devices.Bluetooth.Advertisementの追加
  • クラスメンバにBluetoothLEAdvertisementWatcher advWatcherを追加
  • MainWindowのコンストラクタでBluetoothLEAdvertisementWatcherクラスを生成、アドバタイズパケット受信イベントを追加してStartする。
MainWindowコンストラクタ
public MainWindow()
{
    InitializeComponent();

    this.advWatcher = new BluetoothLEAdvertisementWatcher();
    this.advWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);
    this.advWatcher.Received += this.Watcher_Received;
    this.advWatcher.Start();
}
  • Watcher_Received()を追加。
  • 非同期でイベントが発生するのでasync/awaitにする。
  • アドバタイズパケットはargsに詰まっている。
Watcher_Received()
private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
    await this.Dispatcher.InvokeAsync(() => {
        // ここで処理
    });
}

ひとやすみ・・・

  • ここまでで、Bluetoothデバイスをスキャンするところまで完成。
  • 実行すると、Bluetoothデバイスが近くにあればWatcher_Received()がCallされて、アドバタイズパケットがargsに詰まっている。
  • iBeaconが発信するアドバタイズパケットもこの中に含まれているが、どれがiBeaconなのかチェックする必要がある。

プログラミング②

Watcher_Receivedの中身を実装する
private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
    await this.Dispatcher.InvokeAsync(() => {
        // 参考:Windows10デバイスでiBeaconの全データを取得する方法 http://sonic.blue/it/605
        iBeacon bcon = new iBeacon(args);
        if (bcon.UUID != null) {
            // iBeacon
            DateTimeOffset timestamp = args.Timestamp;
            string retBeaconData;
            retBeaconData = "{";
            retBeaconData += string.Format("uuid:'{0}',", bcon.UUID);//"00000000-0000-0000-0000-000000000000"
            retBeaconData += string.Format("major:{0},", bcon.Major.ToString("D"));
            retBeaconData += string.Format("minor:{0},", bcon.Minor.ToString("D"));
            retBeaconData += string.Format("measuredPower:{0},", bcon.MeasuredPower.ToString("D"));
            retBeaconData += string.Format("rssi:{0},", bcon.Rssi.ToString("D"));
            retBeaconData += string.Format("accuracy:{0},", bcon.Accuracy.ToString("F6"));
            retBeaconData += string.Format("proximity:'{0}'", bcon.Proximity);
            retBeaconData += "}";

            this.textBox.Text = this.textBox.Text + timestamp.ToString("HH\\:mm\\:ss\\.fff") + ":" + retBeaconData + "\r\n";
        }

    });
}

プログラミング完了

これで、Bluetoothデバイスが発信するアドバタイズパケットからiBeaconだけを抽出して画面のテキストボックスに表示するようなアプリができた。

ソース → GitHub

検証

MAMORIO

iPhone iBeacon Scanner

  • Virtual iBeacon機能でアドバタイズパケットを発信できる。
  • UUID = 95f428b1-4a3a-4e39-b086-21bff38deb6d
  • アプリを立ち上げている間はスキャンできるが、iphoneがロックされるとスキャンできない。これはiOSアプリの仕様だろう(バックグランド発信できない)。

Android Beacon Simulator

  • SIMULATOR機能でアドバタイズパケットを発信できる。
  • UUIDは自由に設定できる。
  • Androidをロックしていてもパケット発信するし、アプリが立ち上がっていなくてもパケット発信している。Androdアプリはそういうものなのか、驚。

その他

  • 検証していると、上記以外のパケットがたくさんとれる、iBeaconデバイスがそんなに周りにあるのか、それともノイズなのか、謎…

最後に

  • 今回はざっくり実装ですが、Microsoftのサイトをきちんと読めば正しく理解できるかもです。 → Bluetooth LE アドバタイズ
  • Bluetooth、BLE、Beacon、iBeacon。これらの仕様は複雑でネットの情報も少ないです。誤り、アドバイスなどいただければありがたいです。
17
27
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
27