Windows 10蓝牙低能耗连接c#

Windows 10蓝牙低能耗连接c#,c#,windows,bluetooth,bluetooth-lowenergy,windows-10,C#,Windows,Bluetooth,Bluetooth Lowenergy,Windows 10,对于一个项目,我需要使用C#从windows 10上的蓝牙设备获取一些数据。我对Bluetooth API不太熟悉,无法理解为什么以下操作不起作用: 我使用BluetoothLEAdvertisementWatcher搜索广告,效果很好。我确实从设备(本地名称)以及它的ServiceUuids接收到广告。接下来,我尝试使用与广告一起接收的BluetoothAddress连接到设备: private async void OnAdvertisementReceived(BluetoothLEAdv

对于一个项目,我需要使用C#从windows 10上的蓝牙设备获取一些数据。我对Bluetooth API不太熟悉,无法理解为什么以下操作不起作用:

我使用BluetoothLEAdvertisementWatcher搜索广告,效果很好。我确实从设备(本地名称)以及它的
ServiceUuids
接收到广告。接下来,我尝试使用与广告一起接收的
BluetoothAddress
连接到设备:

private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, 
                    BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
    ulong blAdress = eventArgs.BluetoothAddress;
    BluetoothLEDevice blDevice = await 
         Windows.Devices.Bluetooth.BluetoothLEDevice.FromBluetoothAddressAsync(blAdress);
}
但是,这样做会导致例外情况:

未找到元素。(HRESULT的异常:0x80070490)

这是从设备读取数据的正确方法吗?是否有其他选项可用于从服务读取数据?在windows中手动配对设备实际上不是一个选项,而且似乎也失败了


/编辑1:我检查设备的本地名称,以确保我只尝试连接到正确的设备。所以我想连接到这个特定的设备是有问题的,但我仍然不知道如何解决这个问题。服务数据已在iOS上成功读取,因此这应该是可能的。

我在直接使用BluetoothLeadVertiseTwatcher时遇到了同样的问题

然后我测试了观察者列出的不同地址。我发现它与蓝牙设备有关

在如下添加过滤器后,我可以成功连接到GATT设备(TI传感器标签)

public sealed partial class MainPage : Page
{
    private BluetoothLEAdvertisementWatcher watcher;

    public MainPage()
    {
        this.InitializeComponent();

        // Create and initialize a new watcher instance.
        watcher = new BluetoothLEAdvertisementWatcher();

        // Part 1B: Configuring the signal strength filter for proximity scenarios

        // Configure the signal strength filter to only propagate events when in-range
        // Please adjust these values if you cannot receive any advertisement 
        // Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm 
        // will start to be considered "in-range".
        watcher.SignalStrengthFilter.InRangeThresholdInDBm = -70;

        // Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction with OutOfRangeTimeout
        // to determine when an advertisement is no longer considered "in-range"
        watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75;

        // Set the out-of-range timeout to be 2 seconds. Used in conjunction with OutOfRangeThresholdInDBm
        // to determine when an advertisement is no longer considered "in-range"
        watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);

        // By default, the sampling interval is set to zero, which means there is no sampling and all
        // the advertisement received is returned in the Received event

        // End of watcher configuration. There is no need to comment out any code beyond this point.
    }


    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        watcher.Received += OnAdvertisementReceived;

        watcher.Stopped += OnAdvertisementWatcherStopped;

        App.Current.Suspending += App_Suspending;

        App.Current.Resuming += App_Resuming;
    }


    protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
    {
        App.Current.Suspending -= App_Suspending;
        App.Current.Resuming -= App_Resuming;

        watcher.Stop();

        watcher.Received -= OnAdvertisementReceived;
        watcher.Stopped -= OnAdvertisementWatcherStopped;

        base.OnNavigatingFrom(e);
    }


    private void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
    {
        // Make sure to stop the watcher on suspend.
        watcher.Stop();
        // Always unregister the handlers to release the resources to prevent leaks.
        watcher.Received -= OnAdvertisementReceived;
        watcher.Stopped -= OnAdvertisementWatcherStopped;

    }

    private void App_Resuming(object sender, object e)
    {
        watcher.Received += OnAdvertisementReceived;
        watcher.Stopped += OnAdvertisementWatcherStopped;
    }

    private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
    {
        var address = eventArgs.BluetoothAddress;

        BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(address);

        var cnt =device.GattServices.Count;

        watcher.Stop();
    }

    /// <summary>
    /// Invoked as an event handler when the watcher is stopped or aborted.
    /// </summary>
    /// <param name="watcher">Instance of watcher that triggered the event.</param>
    /// <param name="eventArgs">Event data containing information about why the watcher stopped or aborted.</param>
    private void OnAdvertisementWatcherStopped(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementWatcherStoppedEventArgs eventArgs)
    {

    }

    private void start_Click(object sender, RoutedEventArgs e)
    {
        watcher.Start();
    }
}
公共密封部分类主页面:第页
{
私人蓝牙头领,眩晕追踪者;
公共主页()
{
this.InitializeComponent();
//创建并初始化一个新的观察者实例。
watcher=新的BluetoothLEAdvertisementWatcher();
//第1B部分:为接近场景配置信号强度滤波器
//将信号强度过滤器配置为仅在范围内传播事件
//如果您无法收到任何广告,请调整这些值
//将范围内阈值设置为-70dBm。这意味着RSSI>=-70dBm的播发
//将开始被视为“范围内”。
watcher.SignalStrengthFilter.inRangeSholdindBm=-70;
//将超出范围阈值设置为-75dBm(提供一些缓冲)。与OutOfRangeTimeout结合使用
//确定广告何时不再被视为“范围内”
watcher.SignalStrengthFilter.outofrangesholdindbm=-75;
//将超出范围超时设置为2秒。与OutOfRangeSThresholdIndBM一起使用
//确定广告何时不再被视为“范围内”
watcher.SignalStrengthFilter.OutOfRangeTimeout=TimeSpan.From毫秒(2000);
//默认情况下,采样间隔设置为零,这意味着没有采样和全部采样
//收到的广告将在收到的事件中返回
//观察者配置结束。没有必要注释掉超出此点的任何代码。
}
受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
watcher.Received+=收到的广告;
watcher.Stopped+=广告上的Twatcherstopped;
App.Current.Suspending+=App_Suspending;
App.Current.Resuming+=App_Resuming;
}
受保护的覆盖无效OnNavigatingFrom(NavigatingCancelEventArgs e)
{
App.Current.Suspending-=App_Suspending;
App.Current.Resuming-=App\u Resuming;
watcher.Stop();
watcher.Received-=收到广告;
watcher.Stopped-=广告上的Twatcherstopped;
基于(e)的导航;
}
私有void应用程序_挂起(对象发送方,Windows.ApplicationModel.SuspendingEventArgs e)
{
//确保在挂起时停止观察程序。
watcher.Stop();
//始终注销处理程序以释放资源以防止泄漏。
watcher.Received-=收到广告;
watcher.Stopped-=广告上的Twatcherstopped;
}
私有无效应用程序\u正在恢复(对象发送方,对象e)
{
watcher.Received+=收到的广告;
watcher.Stopped+=广告上的Twatcherstopped;
}
接收到的广告上的私有异步无效(BluetoothLeadVertizenTwatcher监视程序、BluetoothLeadVertizenTraceivedEventArgs事件Args)
{
var address=eventArgs.BluetoothAddress;
BluetoothLEDevice设备=等待BluetoothLEDevice.FromBluetoothAddressAsync(地址);
var cnt=device.GattServices.Count;
watcher.Stop();
}
/// 
///当监视程序停止或中止时,作为事件处理程序调用。
/// 
///触发事件的监视程序的实例。
///包含有关观察程序停止或中止原因的信息的事件数据。
广告上的私人无效信息(Bluetooth Lead VertizenTwatcher watcher、Bluetooth Lead VertizenTwatcher ToppedEventArgs)
{
}
私有无效开始\单击(对象发送者,路由目标)
{
watcher.Start();
}
}

以下是MS()的参考资料。似乎要使用此BluetoothLEDevice.FromBluetoothAddressAsync,我们必须在设备处于广告状态且尚未配对时处理此异常。

在MS解决此问题之前,我发现连接到BLE设备的唯一可靠解决方案是向注册表索要配对的BLE设备列表并比较蓝牙广告中的地址,带有配对可编程设备的注册表列表。我的经验是,当在未配对的设备上调用FromBluetoothAddressAsync时,Windows会抛出一个异常并终止观察线程。我有一些C++代码,我很乐意分享,阅读注册表,并创建一个配对的BLE设备列表。p>
希望微软能像苹果一样花时间完全支持BLE。

只是一个猜测,但也许你需要这个:

watcher.ScanningMode = BluetoothLEScanningMode.Active;
在OnAdv中
if (e.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse)
{
  BluetoothLEDevice blDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(e.BluetoothAddress);
}
 var device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);