如何释放蓝牙 GATT 连接

How to release a Bluetooth GATT Connection

我有一个与 GATT 心率监测器通信的应用程序。有时,传感器出现故障,我想重新初始化连接。我想将连接包装在 class 中,并在旧连接失败但不起作用时声明一个新对象(请参阅 How to delete object?)。然后我尝试实施 IDisposable,但我不确定如何实施。我也考虑过使用CancelationToken,但也不知道如何。这是代码:

public class MainPage : Page
{
    ConnectingObject conn;
    MainPage()
    {
        this.InitializeComponent();
        conn = new ConnectingObject();
    }
    public void cancelConnection()
    {
        conn.Dispose();
    }
}

public class ConnectingObject : IDisposable
{
    bool disposed = false;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            // Free any other managed objects here.
            //
        }

        // Free any unmanaged objects here.
        //
        disposed = true;
    }

    ~HRGATTConnect()
    {
        Dispose(false);
    }
    async void Initialize()
    {
        try
        {
            var heartrateServices = await Windows.Devices.Enumeration
                .DeviceInformation.FindAllAsync(GattDeviceService
                    .GetDeviceSelectorFromUuid(
                        GattServiceUuids.HeartRate),
                null);

            GattDeviceService firstHeartRateMonitorService = await
                GattDeviceService.FromIdAsync(heartrateServices[0].Id);

            //Debug.WriteLine("serviceName:  " +  heartrateServices[0].Name);

            GattCharacteristic hrMonitorCharacteristics =
                firstHeartRateMonitorService.GetCharacteristics(
                    GattCharacteristicUuids.HeartRateMeasurement)[0];

            hrMonitorCharacteristics.ValueChanged += hrMeasurementChanged;

            await hrMonitorCharacteristics
                    .WriteClientCharacteristicConfigurationDescriptorAsync(
                        GattClientCharacteristicConfigurationDescriptorValue.Notify);                
        }
        catch (Exception e)
        {

        }
    }
    void hrMeasurementChanged(GattCharacteristic sender, GattValueChangedEventArgs eventArgs)
    {
        try
        {
            byte[] hrData = new byte[eventArgs.CharacteristicValue.Length];
            Windows.Storage.Streams.DataReader.FromBuffer(
                eventArgs.CharacteristicValue).ReadBytes(hrData);
            data_processing(hrData);                
            }
        }
        catch (Exception e)
        {

        }
    }

谢谢。

How to release a Bluetooth GATT Connection

您需要在GattDeviceService 上调用Dispose(),确保所有GattDeviceService 和GattCharacteristic 对象都为空。您可以这样编辑您的代码:

public sealed partial class MainPage : Page
{
    ConnectingObject conn;
    public MainPage()
    {
        this.InitializeComponent();
        conn = new ConnectingObject();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Frame.Navigate(typeof(BluetoothConnect));
    }
    public void cancelConnection()
    {
        conn.Dispose();
    }

    private void DisconnectButton_Click(object sender, RoutedEventArgs e)
    {
        conn.Dispose();
    }

    private void ConnectButton_Click(object sender, RoutedEventArgs e)
    {
        conn.Initialize();
    }
}

public class ConnectingObject : IDisposable
{
    GattCharacteristic hrMonitorCharacteristics;
    GattDeviceService firstHeartRateMonitorService;

    bool disposed = false;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            // Free any other managed objects here.
            //
            if (firstHeartRateMonitorService != null)
            {
                firstHeartRateMonitorService.Dispose();
                firstHeartRateMonitorService = null;
            }
            if (hrMonitorCharacteristics != null)
            {
                hrMonitorCharacteristics.Service.Dispose();
                hrMonitorCharacteristics = null;
            }
        }

        // Free any unmanaged objects here.
        //
        disposed = true;
    }

    //~HRGATTConnect()
    //{
    //    Dispose(false);
    //}
    public async void Initialize()
    {
        try
        {
            var heartrateServices = await Windows.Devices.Enumeration
                .DeviceInformation.FindAllAsync(GattDeviceService
                    .GetDeviceSelectorFromUuid(
                        GattServiceUuids.HeartRate),
                null);

            firstHeartRateMonitorService = await
                GattDeviceService.FromIdAsync(heartrateServices[0].Id);

            Debug.WriteLine("serviceName:  " + heartrateServices[0].Name);

            hrMonitorCharacteristics =
                firstHeartRateMonitorService.GetCharacteristics(
                    GattCharacteristicUuids.HeartRateMeasurement)[0];

            hrMonitorCharacteristics.ValueChanged += hrMeasurementChanged;

            await hrMonitorCharacteristics
                    .WriteClientCharacteristicConfigurationDescriptorAsync(
                        GattClientCharacteristicConfigurationDescriptorValue.Notify);

            disposed = false;

        }
        catch (Exception e)
        {

        }
    }
    void hrMeasurementChanged(GattCharacteristic sender, GattValueChangedEventArgs eventArgs)
    {
        try
        {
            byte[] hrData = new byte[eventArgs.CharacteristicValue.Length];
            Windows.Storage.Streams.DataReader.FromBuffer(
                eventArgs.CharacteristicValue).ReadBytes(hrData);
            //data_processing(hrData);
        }
        catch (Exception e)
        {

        }
    }

}