gpt4 book ai didi

c# - Windows UWP 在发现后连接到 BLE 设备

转载 作者:IT王子 更新时间:2023-10-29 04:43:29 24 4
gpt4 key购买 nike

我正在使用 BluetoothLEAdvertisementWatcher 查找附近的 BLE 设备,它运行良好。找到它们后,我想通过 GATT 连接和读/写数据。但是在获取 BluetoothLEAdvertisement ( https://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.bluetooth.genericattributeprofile ) 之后,我不知道如何使用 API。

public class Adapter
{
private readonly BluetoothLEAdvertisementWatcher _bleWatcher = new BluetoothLEAdvertisementWatcher();

public Adapter()
{
_bleWatcher.Received += BleWatcherOnReceived;
}

private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
// how to connect?
// I know, it's the wrong place to to this, but this is just an example
}

public void StartScanningForDevices(Guid[] serviceUuids)
{
_blewatcher.advertisementfilter.advertisement.serviceuuids.clear();
foreach (var uuid in serviceuuids)
{
_blewatcher.advertisementfilter.advertisement.serviceuuids.add(uuid);
}
_blewatcher.start();
}
}

我找到了使用 DeviceInformation.FindAllAsync 而不是 BluetoothLEAdvertisementWatcher 的示例,但这些示例无法正常工作/无法找到任何设备。

更新

经过一段时间的挖掘,我发现了以下方法。但不幸的是,配对失败了。该设备只是一个带有 BLE 扩展板的 Arduino。我绝对可以连接 Android 和 iOS。因此,UWP 一定有可能以某种方式实现。 :/

private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
// dev.DeviceInformation.Pairing.CanPair is true
// dpr.Status is Failed
DevicePairingResult dpr = await dev.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
var service = await GattDeviceService.FromIdAsync(dev.DeviceInformation.Id);
}

更新#2

我现在能够发现并配对(不稳定,但现在还可以),但是

var service = await GattDeviceService.FromIdAsync(args.Id);

抛出以下异常

System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)

我不知道为什么。

最佳答案

更新 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 连接。

虽然它有它的怪癖,但它确实有效!

旧答案

根据 Jason 关于设备需要配对才能发现其服务的正确答案,下面是一些解决此问题的示例代码:

    private void SetupBluetooth()
{
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 void StopScanning()
{
Watcher.Stop();
DeviceWatcher.Stop();
}

private async void DeviceFound(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs btAdv)
{
if (_devices.Contains(btAdv.Advertisement.LocalName))
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
{
Debug.WriteLine($"---------------------- {btAdv.Advertisement.LocalName} ----------------------");
Debug.WriteLine($"Advertisement Data: {btAdv.Advertisement.ServiceUuids.Count}");
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress);
var result = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
Debug.WriteLine($"Pairing Result: {result.Status}");
Debug.WriteLine($"Connected Data: {device.GattServices.Count}");
});
}
}

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

private void DeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate update)
{
Debug.WriteLine($"Device updated: {update.Id}");
}

这里要注意的关键是:

  • DeviceWatcher 需要同时设置 Added 和 Updated 属性才能工作。
  • 您需要捕获在尝试询问未配对或尚未准备好的服务时发生的异常 FileNotFound。

关于c# - Windows UWP 在发现后连接到 BLE 设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35420940/

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