实战指南:微信小程序蓝牙指令全流程解析(权限检测、指令发送与自动重连)

张开发
2026/4/20 5:08:59 15 分钟阅读

分享文章

实战指南:微信小程序蓝牙指令全流程解析(权限检测、指令发送与自动重连)
1. 微信小程序蓝牙开发基础认知第一次接触微信小程序蓝牙功能时我踩了不少坑。最典型的就是在安卓机上死活搜不到设备后来才发现是没开GPS权限。微信小程序的蓝牙API主要分为经典蓝牙和低功耗蓝牙BLE两类我们日常对接的智能手环、电子秤等设备基本都是BLE。蓝牙开发的核心流程就像谈恋爱先要获得权限征得同意→搜索附近设备邂逅→建立连接确定关系→收发数据日常交流。整个过程涉及十几个关键API我整理了一张速查表API名称作用调用时机wx.openBluetoothAdapter初始化蓝牙模块第一步必须调用wx.startBluetoothDevicesDiscovery开始搜索设备需要发现新设备时wx.createBLEConnection连接指定设备获取到deviceId后wx.getBLEDeviceServices获取设备服务列表连接成功后立即调用wx.writeBLECharacteristicValue发送指令需要控制设备时实际开发中最容易忽略的是设备UUID的补全问题。安卓8.0以下版本只认128位完整UUID而设备厂商提供的往往只是16位短UUID。这时候需要手动补位// 16位转128位UUID function completeUUID(shortUUID) { return 0000 shortUUID -0000-1000-8000-00805F9B34FB }2. 蓝牙权限检测的完整方案去年做一个医疗设备项目时用户投诉率最高的就是权限问题。很多用户根本不知道需要开启蓝牙和定位直接导致功能不可用。完善的权限检测应该包含三层防御2.1 基础权限检测wx.getSetting({ success(res) { if (!res.authSetting[scope.bluetooth]) { this.showAuthModal(蓝牙) } if (!res.authSetting[scope.userLocation]) { this.showAuthModal(定位) // 安卓必须 } } })2.2 硬件状态检测即使有权限手机蓝牙可能未开启。需要监听状态变化wx.onBluetoothAdapterStateChange((res) { console.log(蓝牙状态${res.available ? 开启 : 关闭}) if (!res.available) { this.showToast(请打开手机蓝牙) } })2.3 异常错误处理常见的错误码需要特殊处理10001蓝牙适配器不可用10002没有找到指定设备10006连接断开需要重连我封装了一个错误处理器function handleBLEError(err) { const map { 10001: { msg: 蓝牙未开启, action: openBluetooth }, 10006: { msg: 连接已断开, action: reconnect } } const strategy map[err.errCode] || { msg: err.errMsg } this[strategy.action]?.() }3. 设备搜索与连接实战技巧搜索设备时有个大坑iOS和安卓的搜索策略完全不同。iOS设备会缓存搜索结果而安卓每次都是全新扫描。这里分享几个实战技巧3.1 优化搜索性能wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: false, // 是否重复上报 interval: 2000, // 上报间隔 success: () { this._discoveryTimer setTimeout(() { wx.stopBluetoothDevicesDiscovery() // 5秒自动停止 }, 5000) } })3.2 设备过滤策略实际项目中设备列表可能有大量干扰项需要智能过滤wx.onBluetoothDeviceFound((res) { const validDevices res.devices.filter(device device.name?.includes(HDS) || device.localName?.includes(MY_DEVICE) ) this.updateDeviceList(validDevices) })3.3 连接保活机制我遇到过最棘手的问题是连接不稳定后来通过心跳检测自动重连解决// 心跳检测 setInterval(() { if (!this._connected) return this.writeBLEHeartbeat().catch(() { this.autoReconnect() }) }, 30000) // 自动重连 function autoReconnect() { let retry 0 const attempt () { this.createBLEConnection().catch(() { if (retry 3) attempt() }) } attempt() }4. 蓝牙指令收发全解析指令收发是整个流程最核心的部分这里有个关键认知BLE通信本质上是特征值Characteristic的读写操作。4.1 指令格式处理医疗设备常用的指令格式// 生成16字节指令缓冲区 function createCommand(cmd, data) { const buffer new ArrayBuffer(16) const view new DataView(buffer) view.setUint8(0, cmd) // 指令码 // 填充数据... view.setUint8(15, this.calcCRC(view)) // 校验位 return buffer }4.2 写入指令最佳实践wx.writeBLECharacteristicValue({ deviceId, serviceId: 0000FFF0-0000-1000-8000-00805F9B34FB, characteristicId: 0000FFF6-0000-1000-8000-00805F9B34FB, value: this.createCommand(0x01, 0x99), success: () { console.log(指令发送成功) }, fail: this.handleBLEError })4.3 数据接收处理设备返回的数据需要转换处理wx.onBLECharacteristicValueChange((res) { const hexString this.ab2hex(res.value) const dataType hexString.substr(0, 2) if (dataType 01) { // 电量数据 this.handleBatteryData(hexString) } else if (dataType 02) { // 设备信息 this.handleDeviceInfo(hexString) } })5. 自动重连的工程化实现在智能家居项目中稳定的自动重连能提升用户体验。我总结出三级重连策略5.1 即时重连错误触发wx.onBLEConnectionStateChange((res) { if (!res.connected this._shouldReconnect) { this.createBLEConnection(res.deviceId) } })5.2 定时巡检setInterval(() { this.checkConnection().catch(() { this.reconnect() }) }, 60 * 1000)5.3 页面唤醒检测onShow() { if (this._lastDeviceId) { this.checkConnection() } }完整重连逻辑包含退避算法async reconnect() { let delay 1000 for (let i 0; i 5; i) { try { await this.createBLEConnection() break } catch (err) { await new Promise(r setTimeout(r, delay)) delay * 2 } } }6. 典型问题排查指南问题1iOS能搜到设备但安卓搜不到检查是否开启了GPS定位权限确认设备不在已配对列表安卓会过滤已配对设备问题2写入指令后无响应检查特征值properties是否包含write确认指令格式和校验码正确使用蓝牙调试工具交叉验证问题3频繁断开连接避免同时持有多个连接实例检查设备电量是否充足增加信号强度检测RSSI我常用的调试技巧是封装一个蓝牙日志器function bleLog(action, params) { console.log([BLE][${action}], params) wx.setStorageSync(ble_log, [ ...(wx.getStorageSync(ble_log) || []), { time: Date.now(), action, params } ]) }7. 性能优化与安全实践在智能锁项目中我们遇到了功耗问题最终优化方案缩短扫描间隔发现设备后立即停止扫描按需连接非活跃状态主动断开连接数据压缩使用更高效的编码方式安全方面需要注意// 敏感操作二次确认 function confirmWrite() { return new Promise((resolve) { wx.showModal({ content: 确认发送控制指令, success: (res) resolve(res.confirm) }) }) }蓝牙开发就像与设备对话需要耐心和技巧。记得第一次成功控制设备时那种成就感至今难忘。现在每次看到用户顺利使用蓝牙功能都会想起那些调试到凌晨的日子。

更多文章