我将win10 sdk的蓝牙服务移植到WPF,无法做到快速断开和连接(快速断开后再次连接的情况下)

祝辉 王 0 信誉分
2024-08-01T05:55:15.03+00:00

打开软件(我的测试程序)第一次连接Ble设备 很顺利

当我快速断开连接,并尝试重连,会出现无法找到特征等其他问题导致无法连接上Ble设备,如下图

2da191cf056a0da60d0a56b256102405

0a8741d719c4d77365b3e084aa814c49

接近20S才重新获得数据,我不清楚我的问题到底出在哪里,现附上我的demo,请大家帮忙解答下

public class MainWindowViewModel : BindableBase
{
    private string _title = "Prism Application";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }
    private DeviceWatcher deviceWatcher;
    private GattCharacteristic GattCharacteristic;
    private FooList<DeviceInformation> deviceInformations;
    private BluetoothLEDevice _bluetoothLEDevice;
    public FooList<DeviceInformation> DeviceInformations
    {
        get { return deviceInformations; }
        set { SetProperty(ref deviceInformations, value); }
    }
    public MainWindowViewModel()
    {
        DeviceInformations = new FooList<DeviceInformation>();
        // Query for extra properties you want returned
        string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
        deviceWatcher =
                    DeviceInformation.CreateWatcher(
                            BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
                            requestedProperties,
                            DeviceInformationKind.AssociationEndpoint);
        // Register event handlers before starting the watcher.
        // Added, Updated and Removed are required to get all nearby devices
        deviceWatcher.Added += DeviceWatcher_Added;
        deviceWatcher.Updated += DeviceWatcher_Updated;
        deviceWatcher.Removed += DeviceWatcher_Removed;
        // EnumerationCompleted and Stopped are optional to implement.
        deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
        deviceWatcher.Stopped += DeviceWatcher_Stopped;
        // Start the watcher.
        deviceWatcher.Start();
    }
    private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
    {
        Debug.WriteLine("设备监视器已停止");
    }
    private void DeviceWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
    {
        Debug.WriteLine("设备枚举完成");
    }
    private void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        Debug.WriteLine($"设备已移除: {args.Id}");
    }
    private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        Debug.WriteLine($"设备已更新: {args.Id}");
    }
    private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
    {
        if (!DeviceInformations.Contains(args) && !string.IsNullOrEmpty(args.Name))
            DeviceInformations.Add(args);
    }
    private async Task ConnectDevice(DeviceInformation deviceInfo)
    {
        try
        {
            _bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
            if (_bluetoothLEDevice == null)
            {
                Debug.WriteLine("无法获取蓝牙设备");
                return;
            }
            if (deviceWatcher.Status == DeviceWatcherStatus.Started)
            {
                deviceWatcher.Stop();
            }
            GattDeviceServicesResult result = await _bluetoothLEDevice.GetGattServicesAsync();
            if (result.Status != GattCommunicationStatus.Success)
            {
                Debug.WriteLine($"{DateTime.Now}获取GATT服务失败: {result.Status}尝试重连");
                await Task.Delay(20);
                await ConnectDevice(deviceInfo);
                return;
            }
            var services = result.Services;
            if (services.Count <= 2)
            {
                Debug.WriteLine($"{DateTime.Now}服务数量不足尝试重连");
                await Task.Delay(20);
                await ConnectDevice(deviceInfo);
                return;
            }
            GattCharacteristicsResult chresult = await services[2].GetCharacteristicsAsync();
            if (chresult.Status != GattCommunicationStatus.Success)
            {
                Debug.WriteLine($"{DateTime.Now}获取特征失败: {chresult.Status}尝试重连");
                await Task.Delay(20);
                await ConnectDevice(deviceInfo);
                return;
            }
            var characteristics = chresult.Characteristics;
            if (characteristics.Count <= 2)
            {
                Debug.WriteLine($"{DateTime.Now}特征数量不足尝试重连");
                await Task.Delay(20);
                await ConnectDevice(deviceInfo);
                return;
            }
            GattCommunicationStatus status = await characteristics[2].WriteClientCharacteristicConfigurationDescriptorAsync(
                GattClientCharacteristicConfigurationDescriptorValue.Notify);
            if (status != GattCommunicationStatus.Success)
            {
                Debug.WriteLine($"{DateTime.Now}设置通知失败: {status}尝试重连");
                await Task.Delay(20);
                await ConnectDevice(deviceInfo);
                return;
            }
            GattCharacteristic = characteristics[2];
            GattCharacteristic.ValueChanged += Characteristic_ValueChanged;
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"连接设备时发生异常: {ex.Message}");
        }
    }
    private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
    {
        var reader = DataReader.FromBuffer(args.CharacteristicValue);
        var data = new byte[reader.UnconsumedBufferLength];
        reader.ReadBytes(data);
        Debug.WriteLine(BitConverter.ToString(data).Replace("-", " "));
    }
    private DelegateCommand<DeviceInformation> connectBle;
    public DelegateCommand<DeviceInformation> ConnectBle =>
        connectBle ?? (connectBle = new DelegateCommand<DeviceInformation>(ExecuteCommandName));
    private async void ExecuteCommandName(DeviceInformation parameter)
    {
        await ConnectDevice(parameter);
    }
    private DelegateCommand disConnectBle;
    public DelegateCommand DisConnectBle =>
        disConnectBle ?? (disConnectBle = new DelegateCommand(ExecuteDisConnectBle));
    private void ExecuteDisConnectBle()
    {
        try
        {
            if (GattCharacteristic != null)
            {
                GattCharacteristic.ValueChanged -= Characteristic_ValueChanged;
                GattCharacteristic = null;
            }
            if (_bluetoothLEDevice != null)
            {
                _bluetoothLEDevice.Dispose();
                _bluetoothLEDevice = null;
            }
        }
        catch (Exception ex)
        {
            // 记录异常或进行其他处理
            Debug.WriteLine($"断开蓝牙连接时发生异常: {ex.Message}");
        }
    }
}
开发人员技术 通用 Windows 平台 (UWP)
开发人员技术 Windows Presentation Foundation
Windows 商业版 适用于 IT 专业人员的 Windows 客户端 用户体验 其他
{count} 票

1 个答案

排序依据: 非常有帮助
  1. 志雄 夏 0 信誉分
    2024-11-18T08:10:11.7866667+00:00

    我也遇到一样的问题,就是服务特征读取没有完整,但设备已经连接了,无法主动断开,猜测是win api底层bug,狗日的微软社区问题不解决

    0 个注释 无注释

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。