gpt4 book ai didi

c# - 为什么 BluetoothLEDevice.GattServices 为空

转载 作者:太空狗 更新时间:2023-10-30 01:16:13 24 4
gpt4 key购买 nike

我正在尝试与外围设备通信而不将其与 Windows 配对,并且我正在使用 BluetoothLEAdvertisementWatcher 扫描范围内的设备。这是我的 WatcherOnReceived 方法:

 async private void WatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
BluetoothLEDevice device = null;
BluetoothDevice basicDevice = null;
GattDeviceService services = null;

if (args.Advertisement.LocalName != "Nexus 6")
return;

_watcher.Stop();

device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
device.GattServicesChanged += Device_GattServicesChanged;
//basicDevice = await BluetoothDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
//services = await GattDeviceService.FromIdAsync(device.DeviceId);

lock (m_syncObj)
{
Debug.WriteLine("");
Debug.WriteLine("----------- DEVICE --------------");

Debug.WriteLine(args.ToString());

Debug.WriteLine(args.Advertisement.DataSections.Count);

foreach (var item in args.Advertisement.DataSections)
{
var data = new byte[item.Data.Length];
using (var reader = DataReader.FromBuffer(item.Data))
{
reader.ReadBytes(data);
}

Debug.WriteLine("Manufacturer data: " + BitConverter.ToString(data));

//Debug.WriteLine("Data : " + item.Data.ToString());
//Debug.WriteLine("Data capacity: " + item.Data.Capacity);
Debug.WriteLine("Data Type: " + item.DataType);
}

foreach (var md in args.Advertisement.ManufacturerData)
{
var data = new byte[md.Data.Length];
using (var reader = DataReader.FromBuffer(md.Data))
{
reader.ReadBytes(data);
}
Debug.WriteLine("Manufacturer data: " + BitConverter.ToString(data));
}

foreach (Guid id in args.Advertisement.ServiceUuids)
{
Debug.WriteLine("UUIDs: " + id.ToString() + " Count: " + args.Advertisement.ServiceUuids.Count);
//services = device.GetGattService(id);
}

Debug.WriteLine("Receive event...");
Debug.WriteLine("BluetoothAddress: " + args.BluetoothAddress.ToString("X"));
Debug.WriteLine("Advertisement.LocalName: " + args.Advertisement.LocalName);
Debug.WriteLine("AdvertisementType: " + args.AdvertisementType);
Debug.WriteLine("RawSignalStrengthInDBm: " + args.RawSignalStrengthInDBm);

if (device != null)
{
Debug.WriteLine("Bluetooth Device: " + device.Name);
Debug.WriteLine("Bluetooth Device conn status: " + device.ConnectionStatus);
Debug.WriteLine("Bluetooth DeviceId: " + device.DeviceId);
Debug.WriteLine("Bluetooth GettServices Count: " + device.GattServices.Count);
}
}
}

收到设备后,我从 args.BlutoothAddress 成功创建了 BluetoothLEDevice,但 device.GattServices 始终为空,因此我无法使用它们与设备通信。是设备问题还是 Windows API 问题,我还能尝试什么?

最佳答案

更新 04/17 - 创作者更新Microsoft 刚刚更新了他们的蓝牙 API。我们现在有未配对的 BLE 设备通信!

目前他们的文档很少,但这里是简化得多的新结构:

BleWatcher = new BluetoothLEAdvertisementWatcher 
{
ScanningMode = BluetoothLEScanningMode.Active
};
BleWatcher.Start();

BleWatcher.Received += async (w, btAdv) => {
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress);
Debug.WriteLine($"BLEWATCHER Found: {device.name}");

// SERVICES!!
var gatt = await device.GetGattServicesAsync();
Debug.WriteLine($"{device.Name} Services: {gatt.Services.Count}, {gatt.Status}, {gatt.ProtocolError}");

// CHARACTERISTICS!!
var characs = await gatt.Services.Single(s => s.Uuid == SAMPLESERVICEUUID).GetCharacteristicsAsync();
var charac = characs.Single(c => c.Uuid == SAMPLECHARACUUID);
await charac.WriteValueAsync(SOMEDATA);
};

现在好多了。正如我所说,目前几乎没有文档,我有一个奇怪的问题,我的 ValueChanged 回调在 30 秒左右后停止被调用,尽管这似乎是一个单独的范围问题。

更新 2 - 一些奇怪的地方

在尝试了新的创作者更新之后,在构建 BLE 应用程序时需要考虑更多事项。

  • 您不再需要在 UI 线程上运行蓝牙。如果没有配对,BLE 似乎没有任何权限窗口,因此不再需要在 UI 线程上运行。您可能会发现您的应用程序在一段时间后停止从设备接收更新。这是一个范围界定问题,其中不应该处理对象。在上面的代码中,如果您在 charac 上收听 ValueChanged,您可能会遇到此问题。这是因为 GattCharacteristic 在它应该被处理之前就被处理掉了,将特性设置为全局特性而不是依赖于它被复制进来。断开连接似乎有点坏了。退出应用程序不会终止连接。因此,请确保您使用 App.xml.cs OnSuspended 回调来终止您的连接。否则你会进入一种奇怪的状态,Windows 似乎在维护(并继续阅读!!)BLE 连接。好吧,它有它的怪癖,但它确实有效!

  • 这仍然是 Windows 通用应用程序的问题,最初的问题是设备必须配对(而非绑定(bind))才能发现 GattServices。但是,还需要使用 Windows 设备而不是 BLE API 来发现它们。 Microsoft 知道并正在开发不需要配对的新 BLE API,但坦率地说,在准备就绪之前,他们的 BLE 支持非常无用。

  • 尝试在控制面板中手动配对设备,然后再次列出服务。由于某些原因,在 Windows Universal Apps 中您只能列出配对设备的 Gatt 服务,尽管 BLE 的优势之一是您在使用其服务之前无需与设备配对。

您可以通过编程方式配对设备,但是根据运行应用程序的平台,这需要 UI 提示。因此在后台查询 BLE 服务是不可行的。这需要修复,因为它确实阻碍了 UWP 中的 BLE 支持。

这很奇怪但很管用!

旧答案

下面是一些具有工作 BLE 设备连接的示例代码:

    private void StartWatcher()
{
ConnectedDevices = new List<string>();

Watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
Watcher.Received += DeviceFound;

DeviceWatcher = DeviceInformation.CreateWatcher();
DeviceWatcher.Added += DeviceAdded;
DeviceWatcher.Updated += DeviceUpdated;

StartScanning();
}

private void StartScanning()
{
Watcher.Start();
DeviceWatcher.Start();
}

private async void DeviceFound(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs btAdv)
{
if (!ConnectedDevices.Contains(btAdv.Advertisement.LocalName) && _devices.Contains(btAdv.Advertisement.LocalName))
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
{
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress);
if (device.GattServices.Any())
{
ConnectedDevices.Add(device.Name);
device.ConnectionStatusChanged += (sender, args) =>
{
ConnectedDevices.Remove(sender.Name);
};
SetupWaxStream(device);
} else if (device.DeviceInformation.Pairing.CanPair && !device.DeviceInformation.Pairing.IsPaired)
{
await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
}
});
}
}

private async void DeviceAdded(DeviceWatcher watcher, DeviceInformation device)
{
if (_devices.Contains(device.Name))
{
try
{
var service = await GattDeviceService.FromIdAsync(device.Id);
var characteristics = service.GetAllCharacteristics();
}
catch
{
Debug.WriteLine("Failed to open service.");
}
}
}

private async void DeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate update)
{
var device = await DeviceInformation.CreateFromIdAsync(update.Id);
if (_devices.Contains(device.Name))
{
try
{
var service = await GattDeviceService.FromIdAsync(device.Id);
var characteristics = service.GetAllCharacteristics();
}
catch
{
Debug.WriteLine("Failed to open service.");
}
}
}

关于c# - 为什么 BluetoothLEDevice.GattServices 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35937580/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com