UWPのAPIを使ってできるかやってみます。
まず、WpfBleSampleAppという名前でWPFアプリケーションを作成してNuGetからUwpDesktopをインストールします。こいつは、UWPを使うために必要な設定をやってくれる便利な奴です。
次に、以下の記事を参考にアドバタイズパケットを拾うコードを書きます。
まず、画面のXAMLです。TextBlockを置いて、BLEの受信を開始・停止するためのLoadedとClosedイベントを紐づけてます。
<Window x:Class="WpfBleSampleApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfBleSampleApp" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Closed="Window_Closed"> <Grid> <TextBlock x:Name="TextBlockRSSI" /> </Grid> </Window>
コードビハインドは、ほぼほぼ上記Blog記事のコードのコピペになります。
using System; using System.Linq; using System.Windows; using Windows.Devices.Bluetooth.Advertisement; namespace WpfBleSampleApp { /// <summary>/// MainWindow.xaml の相互作用ロジック/// </summary>publicpartialclass MainWindow : Window { private BluetoothLEAdvertisementWatcher watcher; public MainWindow() { InitializeComponent(); this.watcher = new BluetoothLEAdvertisementWatcher(); // CompanyIDとかDataでフィルタリングしたいとき//var md = new BluetoothLEManufacturerData();//// company id 0xFFFF (多分これ https://www.bluetooth.com/specifications/assigned-numbers/company-Identifiers)//md.CompanyId = 0xFFFF; //// data 0x1234//var w = new DataWriter();//w.WriteUInt16(0x1234);//md.Data = w.DetachBuffer();//this.watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(md);// rssi >= -60のとき受信開始するっぽいthis.watcher.SignalStrengthFilter.InRangeThresholdInDBm = -60; // rssi <= -65が2秒続いたら受信終わるっぽいthis.watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -65; this.watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000); this.watcher.Received += this.Watcher_Received; } private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { await this.Dispatcher.InvokeAsync(() => { var md = args.Advertisement.ManufacturerData.FirstOrDefault(); if (md != null) { // ManufactureDataをもとにCompanyIDとったりできる } this.TextBlockRSSI.Text = $"{args.Timestamp:HH\\:mm\\:ss}, RSSI: {args.RawSignalStrengthInDBm}, Address: {args.BluetoothAddress.ToString("X")}, Type: {args.AdvertisementType}"; }); } privatevoid Window_Closed(object sender, EventArgs e) { this.watcher.Stop(); } privatevoid Window_Loaded(object sender, RoutedEventArgs e) { this.watcher.Start(); } } }
実行してみましょう。
ちゃんと取れてますね。
コード
コードはGitHubに上げています。