跳转到内容

Web Bluetooth API:连接蓝牙低功耗设备

一句话: Web Bluetooth API 让 Web 应用通过浏览器托管的设备选择器扫描并连接附近的 蓝牙低功耗(BLE)设备——心率监测仪、智能锁、传感器、游戏手柄——无需原生应用。它是 WICG 规范,目前在基于 Chromium 的浏览器中可用。

Web Bluetooth 由 WICG(Web 孵化器社区组)规范定义,而非最终确立的 W3C 标准。它 在 Chrome 和 Edge(桌面端和 Android)上可用,但 Firefox 和 Safari 不支持。请始终进行 特性检测,并为不支持的浏览器提供回退或清晰说明。

async function connectHeartRateMonitor() {
// 1. 请求设备——显示浏览器的设备选择器 UI
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['heart_rate'] }],
// optionalServices: ['battery_service'],
});
// 2. 连接到设备的 GATT 服务器
const server = await device.gatt.connect();
// 3. 获取主服务
const service = await server.getPrimaryService('heart_rate');
// 4. 获取特征值
const characteristic = await service.getCharacteristic('heart_rate_measurement');
// 5. 订阅通知
characteristic.addEventListener('characteristicvaluechanged', (event) => {
const value = event.target.value; // DataView
console.log('心率:', value.getUint8(1), 'bpm');
});
await characteristic.startNotifications();
}

navigator.bluetooth.requestDevice() 必须在用户激活(点击、轻触或类似瞬时事件) 时调用。以编程方式在没有手势的情况下调用会抛出 SecurityError。选择器不能被预先 回答或绕过。

Web Bluetooth API 仅在安全上下文——HTTPS 或 localhost——中可用。在普通 HTTP 下, navigator.bluetoothundefined

Web Bluetooth 不使用标准 Permissions API 权限名称。访问是设备级别的:用户从浏览器 选择器中选择特定设备,且只有该设备对该源(origin)可访问。没有“广泛授予蓝牙访问” 的提示——每次 requestDevice() 调用通过 filtersacceptAllDevices 针对特定服务。

  • 已授予的设备访问对同一源跨页面加载持久存在(用户不必在每次访问时重新选择),但 可在浏览器设置中撤销。
  • device.gatt.connect() 可以重新连接到之前选择的设备,无需再次显示选择器——若 设备尚未连接,请在用户手势中调用它。
  • filters:过滤器对象数组。每个可包含 services(GATT 服务 UUID)、namenamePrefixmanufacturerData。只有匹配过滤器的设备会出现在选择器中。
  • acceptAllDevices: true:显示所有附近的 BLE 设备。仅用于开发或设备类型无法 提前知晓时;需要在 optionalServices 中列出你打算使用的每个服务。

BLE 通信按层次结构组织:

  • 服务将相关功能分组(如 heart_ratebattery_service)。
  • 特征值是服务中的各个数据点(如 heart_rate_measurement)。
  • 描述符提供特征值的元数据。

可以使用标准的 16 位蓝牙 SIG UUID(短名称如 'heart_rate' 自动解析为完整 UUID), 或用于厂商专有服务的完整 128 位自定义 UUID。

当前各浏览器数据请参见 /compatibility/

决策问题 建议行为 理由
面向 Chrome/Edge 用户? Web Bluetooth 在 Chrome 桌面端、Chrome Android 和 Edge 上可用。 目前仅限 Chromium;Firefox 和 Safari 未实现。
也需要在 Firefox/Safari 上工作? 显示清晰的“此浏览器不支持”消息;考虑原生配套应用。 没有 polyfill 能复制 BLE 访问;尽早设定预期。
连接已知设备类型(如心率监测仪)? 使用特定的 filters: [{ services: ['heart_rate'] }] 将选择器缩小到兼容设备;避免显示不相关的 BLE 设备。
需要在不再次弹出选择器的情况下重连? 存储 device 并在点击处理器中调用 device.gatt.connect() 源保留了对之前选择设备的访问权。
  • 特性检测:在调用任何 Web Bluetooth 方法前检查 if (!navigator.bluetooth)
  • 通过 HTTPS 提供页面——普通 HTTP 下 API 不可用。
  • 仅在用户手势处理器中调用 requestDevice()
  • 在生产环境中使用特定的 filters 而非 acceptAllDevices
  • filtersoptionalServices 中列出你需要的所有服务——浏览器会阻止访问 未列出的服务。
  • 处理断开连接事件(device.addEventListener('gattserverdisconnected', ...))并 实现重连逻辑。
  • 清晰传达此功能需要基于 Chromium 的浏览器。