UWPでBLEデバイスとペアリングして値を取得する
(2017-05-13)
ManifestからBluetoothを許可しておく。
BLEデバイスを見つける
CreateWatcher
にBluetooth LEプロトコルのAEP(Association EndPoint)サービスクラスIDと
requestPropaertiesで必要なデバイス情報を渡している。
最後のAssociationEndpoint
はSystem.Devices.Aep.ProtocolId
のAepと対応している。
using Windows.Devices.Enumeration;
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
deviceWatcher = DeviceInformation.CreateWatcher(
"(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")",
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
deviceWatcher.Start();
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Removed += DeviceWatcher_Removed;
deviceWatcher.Updated += DeviceWatcher_Updated;
/*
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
*/
Dictionary<string, DeviceInformation> deviceInfos = new Dictionary<string, DeviceInformation>();
private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation deviceInfo)
{
if (sender == deviceWatcher)
{
if (deviceInfo.Name != string.Empty)
{
deviceInfos.Add(deviceInfo.Id, deviceInfo);
}
}
}
private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
if (sender == deviceWatcher)
{
deviceInfos[deviceInfoUpdate.id].Update(deviceInfoUpdate);
}
}
private void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
if (sender == deviceWatcher)
{
deviceInfos.Remove(deviceInfoUpdate.id);
}
}
ペアリング
DevicePairingResult result = await deviceInfo.Pairing.PairAsync();
if (result.Status == DevicePairingResultStatus.Paired || result.Status == DevicePairingResultStatus.AlreadyPaired){
// success
} else{
// fail
}
こんなウィンドウが出てくる。
OSの設定からペアリングすることもできる。
serviceのcharacteristicを取得する
ペアリングしたらこんな感じで値を取得できる。
GetGattServicesForUuidAsyc
などはCreaters Update(15063)から追加されたAPI。
Anniversary Edition(14393)まで対応する場合
はGetGattService
を使う。いずれにしても最小バージョンをそれ以上にしておく。
deviceの値が取得できない場合はBluetoothが許可されているか確認する。
あと、characteristicが一つも取れない場合、他のアプリケーションからアクセスしていないか注意。
ドキュメントにも書いてあるけど、一つのサービスには一つのアプリケーションしかアクセスできない。
そもそも接続できない場合、一旦お互いの接続設定を消して再ペアリングするとよくなることがある。
ペアリングもできないようだったらBluetoothをオフにしてみるとか。
var device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
var services = await device.GetGattServicesForUuidAsync(serviceUUID);
var characteristics = await services.Services[0].GetCharacteristicsForUuidAsync(characteristicUUID);
characteristics.Characteristics[0].ValueChanged += characteristicChanged;
await characteristics.Characteristics[0].WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify
);
void characteristicChanged(
GattCharacteristic sender,
GattValueChangedEventArgs eventArgs
){
byte[] data = new byte[eventArgs.CharacteristicValue.Length];
Streams.DataReader.FromBuffer(eventArgs.CharacteristicValue).ReadBytes(data);
var str = System.Text.Encoding.ASCII.GetString(data)
}