You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP类库DeviceWatcher异常:直接从Created跳至EnumerationComplete无法扫描BLE设备

解决UWP类库中DeviceWatcher直接跳转到EnumerationComplete的BLE扫描问题

我之前帮好几个开发者排查过类似的UWP BLE扫描故障,你的情况明显是DeviceWatcher还没真正开始扫描就直接结束了,咱们从几个核心点入手排查:

1. 权限配置一定要盯紧宿主应用的清单

UWP类库本身的权限是由调用它的宿主应用决定的!哪怕你给类库加了清单,宿主应用的Package.appxmanifest才是关键。你需要确保里面包含以下配置:

  • 蓝牙设备权限
  • Windows 10 1903及以上版本,BLE扫描可能需要位置权限(哪怕你不需要获取设备位置,系统也要求声明)

示例清单配置:

<Capabilities>
  <!-- 基础蓝牙权限 -->
  <DeviceCapability Name="bluetooth">
    <Device Id="any">
      <Function Type="serviceId:00001800-0000-1000-8000-00805f9b34fb" /> <!-- 通用访问服务 -->
      <Function Type="serviceId:00001801-0000-1000-8000-00805f9b34fb" /> <!-- 通用属性服务 -->
      <!-- 如果要扫描特定服务的设备,添加对应的UUID -->
    </Device>
  </DeviceCapability>
  <!-- 针对Win10 1903+的位置权限 -->
  <Capability Name="location" />
</Capabilities>

2. 确保DeviceWatcher没有被GC回收

从你给出的代码片段看,deviceWatcher是类的私有字段,这很好,但要注意:如果你的类实例被提前回收,Watcher也会跟着停止。另外,一定要手动调用Start()方法——很多人会漏掉这一步,导致Watcher一直停在Created状态,直接跳转到完成。

正确的初始化和启动代码示例:

private DeviceWatcher deviceWatcher;

public void InitializeBLEScanner()
{
    // 使用通用的BLE设备选择器,不要加过于严格的过滤(先确保能扫到设备再调整)
    string deviceSelector = BluetoothLEDevice.GetDeviceSelector();
    deviceWatcher = DeviceInformation.CreateWatcher(deviceSelector);

    // 必须注册事件,否则即使扫描到设备你也接收不到通知
    deviceWatcher.Added += OnDeviceAdded;
    deviceWatcher.StatusChanged += OnWatcherStatusChanged;
    deviceWatcher.EnumerationCompleted += OnEnumerationCompleted;

    // 关键:启动扫描
    deviceWatcher.Start();
}

private void OnDeviceAdded(DeviceWatcher sender, DeviceInformation args)
{
    // 处理发现的BLE设备
    Debug.WriteLine($"发现设备:{args.Name}");
}

private void OnWatcherStatusChanged(DeviceWatcher sender, DeviceWatcherStatusChangedEventArgs args)
{
    Debug.WriteLine($"Watcher状态变更:{args.Status}");
}

private void OnEnumerationCompleted(DeviceWatcher sender, object args)
{
    Debug.WriteLine("扫描完成");
}

3. 检查系统蓝牙状态

如果系统蓝牙没打开,DeviceWatcher会直接结束扫描。你可以在代码里提前判断并提示用户:

var bluetoothRadio = await BluetoothRadio.GetDefaultAsync();
if (bluetoothRadio == null || bluetoothRadio.State != RadioState.On)
{
    // 这里可以弹窗提示用户开启蓝牙
    return;
}

4. 排查过滤条件是否过于严格

如果你给DeviceWatcher设置了特定的服务UUID过滤,而周围没有匹配该服务的BLE设备,扫描也会直接完成。建议先使用无过滤的选择器(也就是上面示例中的BluetoothLEDevice.GetDeviceSelector()),确认能扫到设备后,再添加特定过滤条件。

最后验证步骤

  1. 重启宿主应用(权限变更需要重启生效)
  2. 确保系统蓝牙处于开启状态
  3. 运行代码时查看Debug输出的Watcher状态,确认是否会进入Started状态

内容的提问来源于stack exchange,提问作者slacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:52:22