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

Web Bluetooth API获取BLE广播厂商与服务数据的问题排查与解决

Web Bluetooth API无法获取BLE广播的厂商数据/服务数据问题排查与解决

问题描述

我尝试通过BLE广播传输数据,发送端用原生APP能正常发送,但接收端需基于Web应用实现。已知Web Bluetooth API在部分浏览器支持,扫描监听BLE广播需手动启用。目前已能监听广播,获取设备名称、信号强度等数据,但无法获取自定义的厂商数据(Manufacturer Data)与服务数据(Service Data)。

使用以下脚本尝试获取数据,但manufacturerData始终为空:

device.addEventListener('advertisementreceived', event => {
  event.manufacturerData.forEach((dataView, companyId) => {
    const bytes = new Uint8Array(dataView.buffer);
    const ascii = new TextDecoder('ascii').decode(bytes);
    log(`Company ID: 0x${companyId.toString(16)}`);
    log(`Message: ${ascii}`);
  });
});
await device.watchAdvertisements();

原生Android APP扫描广播时可正常获取这些属性,请问无法通过浏览器获取的原因是什么?能否提供基于Web应用的解决方案?


无法获取数据的核心原因

  • 浏览器隐私过滤机制:为保护用户隐私,Web Bluetooth API默认会过滤广播中的厂商数据和服务数据,除非在请求设备时明确声明需要访问对应的厂商ID或服务UUID。
  • 连接状态限制:watchAdvertisements()在设备未连接时,部分浏览器(如Chrome)仅允许读取基础广播信息,无法获取自定义的厂商/服务数据;只有设备处于连接状态,才能完整读取这类数据。
  • 厂商ID规范性问题:若发送端使用的是蓝牙SIG未分配的自定义厂商ID,浏览器可能直接忽略该部分数据。

解决方案

1. 请求设备时明确声明厂商ID或服务UUID

调用navigator.bluetooth.requestDevice()时,必须通过filters字段指定目标厂商ID或服务UUID,让浏览器允许访问对应广播数据。示例代码:

// 替换为你的实际厂商ID(如0x0001)或服务UUID
const device = await navigator.bluetooth.requestDevice({
  filters: [{
    manufacturerData: [{ companyId: 0x0001 }]
    // 若要获取服务数据,可替换为:serviceData: [{ uuid: '0000ffe0-0000-1000-8000-00805f9b34fb' }]
  }],
  acceptAllDevices: false,
  optionalServices: ['battery_service'] // 必须声明,可填需要的服务UUID或留空
});

device.addEventListener('advertisementreceived', event => {
  // 处理厂商数据
  event.manufacturerData.forEach((dataView, companyId) => {
    const bytes = new Uint8Array(dataView.buffer);
    const ascii = new TextDecoder('ascii').decode(bytes);
    console.log(`Company ID: 0x${companyId.toString(16)}`);
    console.log(`Message: ${ascii}`);
  });

  // 处理服务数据(若有)
  event.serviceData.forEach((dataView, serviceUuid) => {
    const bytes = new Uint8Array(dataView.buffer);
    const ascii = new TextDecoder('ascii').decode(bytes);
    console.log(`Service UUID: ${serviceUuid}`);
    console.log(`Service Data: ${ascii}`);
  });
});

await device.watchAdvertisements();

2. 先连接设备再监听广播

若上述方法无效,尝试先建立GATT连接,再监听广播数据:

const device = await navigator.bluetooth.requestDevice({
  filters: [{ manufacturerData: [{ companyId: 0x0001 }] }],
  optionalServices: ['0000ffe0-0000-1000-8000-00805f9b34fb'] // 替换为你的服务UUID
});

// 先建立GATT连接
const server = await device.gatt.connect();

// 再监听广播事件
device.addEventListener('advertisementreceived', event => {
  console.log('Manufacturer Data:', event.manufacturerData);
  console.log('Service Data:', event.serviceData);
});

await device.watchAdvertisements();

3. 验证厂商ID的合法性

确保发送端使用的厂商ID是蓝牙SIG分配的合法16位ID,若需使用自定义标识,建议将数据嵌入服务数据,并搭配标准服务UUID传输。

4. 确认浏览器兼容性

目前仅Chrome(桌面/Android)、Edge等主流浏览器支持Web Bluetooth API的广播数据读取功能,Safari(含iOS)暂未完全支持该特性。


内容的提问来源于stack exchange,提问作者LAZARO QUEIROZ DO NASCIMENTO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 02:52:37