Windows BLE UWP断开连接

6
如何让 Windows 断开与在 UWP 应用程序中使用的 BLE 设备的连接?我收到了一些特征的通知,但在某个时候我想停止接收它们,并确保我断开与 BLE 设备的连接以节省其电量。
7个回答

3
假设您的应用程序作为gatt客户端运行,并且您在代码中使用以下实例,请注意:

假定您的应用程序作为gatt客户端运行,并且您在代码中使用以下实例:

GattCharacteristic myGattchar; // The gatt characteristic you are reading or writing on your BLE peripheral 
GattDeviceService myGattServ; // The BLE peripheral' gatt service on which you are connecting from your application  
BluetoothLEDevice myBleDev;  // The BLE peripheral device your are connecting to from your application

当您已连接到BLE外设时,如果像这样调用Dispose()方法:

myBleDev.Dispose(); 和/或 myGattServ.Dispose(); 和/或 myGattchar.Service.Dispose()

您可以释放应用程序中的资源,但不会干净地关闭BLE连接:应用程序失去对连接控制资源的访问。尽管如此,在堆栈的较低级别上保持连接(在我的外围设备上,任何Dispose()方法调用后,蓝牙连接激活 LED仍然保持开启状态)。

通过首先通过调用WriteClientCharacteristicConfigurationDescriptorAsync方法将0(零)写入该特征的客户端特征配置描述符参数GattClientCharacteristicConfigurationDescriptorValue.None来禁用有关特定特征(即我的示例中的myGattchar)的通知和指示来强制断开连接:

GattCommunicationStatus status = 
await myGattchar.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.None);

这是微软的UWP BLE示例展示给你应该做的。但对我来说并不起作用。 - Matt D.
如果客户端特征不允许写入该怎么办? 假设我只从DeviceInformation服务--> ModelNumberString特征中读取,而无法将此设置写入。那么我就不能使用您的方法了吗? - hansmbakker

1
对于我的UWP应用程序,尽管我已使用Dispose()方法,但仍然收到通知。帮助我的是将我的设备和特征设置为null。例如:

device.Dispose();

设备 = null;

我不太确定这个编程是否“正确”,但目前它对我来说一直运行良好。


1

只需处理与设备相关的所有对象即可。这将断开设备的连接,除非有其他应用程序连接到它。


1
微软提供的 UWP 蓝牙 BLE 示例代码(释放 BLE 设备)对我无效。我不得不添加代码(释放服务)以断开设备连接。
private async Task<bool> ClearBluetoothLEDeviceAsync()
{
    if (subscribedForNotifications)
    {
        // Need to clear the CCCD from the remote device so we stop receiving notifications
        var result = await registeredCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.None);
        if (result != GattCommunicationStatus.Success)
        {
            return false;
        }
        else
        {
            selectedCharacteristic.ValueChanged -= Characteristic_ValueChanged;
            subscribedForNotifications = false;
        }
    }
    selectedService?.Dispose(); //added code
    selectedService = null; //added code
    bluetoothLeDevice?.Dispose();
    bluetoothLeDevice = null;
    return true;
}

1
太好了,我终于找到了!我已经苦苦挣扎了几个小时!我还发现,即使只创建了一个临时对象,释放服务也是必要的,以便正确关闭设备。 - Ashley Duncan

0

记住,对于你已经调用了+=的事件,你必须调用-=,否则Dispose()将永远无法正确地进行垃圾回收。我知道这需要写更多的代码,但这就是事实。

不仅仅是蓝牙相关的东西,我要提醒你——所有情况都是如此。如果你有硬引用的事件处理程序,并期望垃圾回收按预期工作,那是不可能的。


0

执行所有建议的处理和空引用并没有实现我想要的 Windows(Windows 设置)断开连接。

但是通过 DeviceIoControl 处理 IOCTL 完成了任务。


0

我发现在调用 GattDeviceService.GetCharacteristicsAsync() 后,BluetoothLeDevice.Dispose() 不起作用。因此我会处理掉我不需要的服务。

GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync();
if (characteristicsResult.Status == GattCommunicationStatus.Success)
{
    foreach (GattCharacteristic characteristic in characteristicsResult.Characteristics)
    {

        if (characteristic.Uuid.Equals(writeGuid))
        {
            write = characteristic;
        }
        if (characteristic.Uuid.Equals(notifyGuid))
        {
            notify = characteristic;
        }
    }

    if (write == null && notify == null)
    {
        service.Dispose();
        Log($"Dispose service: {service.Uuid}");
    }
    else
    {
        break;
    }
}

最后,当我想要断开蓝牙连接时

write.Service.Dispose();
device.Dispose();
device = null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接