Reputation: 3183
I am using the sample from Microsoft. When an advertisement is received I am calling
BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
and then
device.GattServices()
but that always returns an empty list. Why is this happening? I have found no answer whatsoever.
Upvotes: 0
Views: 635
Reputation: 1029
I wanted to put more explanation in my comment, but something went wrong and cannot edit my comment so I will add it as an answer. I had exactly the same problem. for some reason you have to initialize your BLEdevice as null.
private BluetoothLEDevice device = null;
Also to prevent that you advertisementWatcher is setting your device over and over, use an if statement to set it only when the divice is null,
if (device == null)
{
device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
}
or if you want to set multiple devices than add them to a collection and make sure each device is only added once.
This is my working code :
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher,
BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
BluetoothLEAdvertisementType advertisementType = eventArgs.AdvertisementType;
short rssi = eventArgs.RawSignalStrengthInDBm;
string localName = eventArgs.Advertisement.LocalName;
string manufacturerDataString = "";
var manufacturerSections = eventArgs.Advertisement.ManufacturerData;
if (manufacturerSections.Count > 0)
{
// Only print the first one of the list
var manufacturerData = manufacturerSections[0];
var data = new byte[manufacturerData.Data.Length];
using (var reader = DataReader.FromBuffer(manufacturerData.Data))
{
reader.ReadBytes(data);
}
manufacturerDataString = string.Format("0x{0}: {1}",
manufacturerData.CompanyId.ToString("X"),
BitConverter.ToString(data));
}
string res = string.Format("type={0}, rssi={1}, name={2}, manufacturerData=[{3}]",
advertisementType.ToString(),
rssi.ToString(),
localName,
manufacturerDataString);
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
textBoxWatcher.Text = res;
});
if (device == null)
{
device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
if (device != null)
{
var deviceInfo = device.DeviceInformation;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (device.Name != string.Empty)
{
//ResultCollection is a observable observable collection of blueutooth devices
// to bind to a listvieuw,it is not needed!
ResultCollection.Add(new BleDevice(device));
if (deviceInfo.Name == "HMSoft")
{
if (ResultCollection[0] is BleDevice bleDevice)
{
BleDeviceId = bleDevice.Id;
SelectedBleDeviceName = bleDevice.Name;
}
Connect();
}
}
});
}
}
Upvotes: 0
Reputation: 1029
If you want this to work by using advertisement watcher, you need to target the windows 10 creators update(10.0;Build 15063) and use the latest SDK, otherwise you will have to pair the device first. To get the GattServices, first check if the device is not null. Then use:
var serviceResult = await bluetoothLeDevice.GetGattServicesAsync();
if (serviceResult.Status == GattCommunicationStatus.Success)
{
//Do something with servivicResult list
}
But there is a catch; It can be that serviceResult.Status returns success, but not all or no services have been found yet. My solution is to put it in a loop with a short delay and try it a few times until serviceResult count stays the same.
Upvotes: 1