微信小程序蓝牙SDK集成指南:5步实现设备连接与数据收发
微信小程序蓝牙SDK,听上去像是一个冷冰冰的接口文档,但如果你把它想象成一场“设备间的对话”,事情就变得有趣多了。你写的小程序是“人类”,蓝牙设备是“外星人”,而SDK就是翻译官。今天,我们不讲那些官方案例里翻来覆去的老套路,咱们聊聊实际开发中,那些文档不会明说,但你必须知道的“潜规则”。
一、别急着扫描:先搞清楚你的设备“说话”方式
一上手就调用wx.startBluetoothDevicesDiscovery,结果扫描出一堆设备,却连不上。问题出在哪?你连对方是“广播员”还是“私聊党”都没分清。蓝牙设备分两种:一种是“低功耗蓝牙(BLE)”,数据量小,像智能手环;另一种是“经典蓝牙”,比如蓝牙音箱。微信小程序SDK只支持BLE,你拿它去连音箱,当然没反应。
举个例子:你拿手机连一个体脂秤,它广播数据时,你扫描到的设备名可能叫“BodyFat_123”,但如果你用wx.createBLEConnection去连,你会发现它根本没开放连接权限——因为它只是“单向广播”,你得找它的服务UUID。怎么找?先扫描,拿到advertisData,用ArrayBuffer转16进制的方法看看里面藏了啥。大多数设备会在广播包里塞一个“自定义服务UUID”,这才是连接的关键。
wx.createBLEConnection返回成功,不代表你能收发数据。这就像你敲了门,对方开了门缝,但还没让你进屋。真正的“进屋”是拿到serviceId和characteristicId。很多开发者卡在这一步:连接成功了,但wx.notifyBLECharacteristicValueChange就是没回调。
实战技巧:连接成功后,先调用wx.getBLEDeviceServices,拿到所有服务列表。你会发现,有些服务是“标准服务”(比如电池服务0x180F),有些是“自定义服务”。你要找的通常是自定义服务里的“写特征值”和“通知特征值”。怎么区分?看特征值的属性:0x10表示“通知”,0x08表示“写”。用这个规律,你就能从一堆UUID里精准定位。
微信小程序蓝牙SDK的数据交换,用的是ArrayBuffer。直接传字符串,结果设备完全不理你。为什么?因为设备只认“二进制协议”。比如一个智能灯,你发“1”去开灯,它可能只认0x01这个字节。
一个实际案例:我曾调试一个温湿度传感器,文档说发“0xAA 0x01 0xBB”就能获取数据。我直接用new Uint8Array([0xAA, 0x01, 0xBB]).buffer发送,结果没反应。后来发现,设备要求“写入响应”,而我用的特征值属性是“写无响应”。换成writeType: 'write'(有响应),数据才正常。所以,写数据前,务必确认特征值支持“写”还是“写无响应”。
蓝牙设备断开后,你再次调用wx.createBLEConnection,可能返回“连接失败”。这不是设备坏了,而是微信的蓝牙缓存没清。特别是Android手机,同一个设备的deviceId,微信会记住上次的连接状态。解决方案:每次断开后,调用wx.closeBLEConnection并等待500ms以上,再重新扫描。另外,部分设备需要“手动配对”,你需要在系统蓝牙设置里先忽略设备,否则微信无法建立新连接。
很多开发者在onBLECharacteristicValueChange回调里做大量运算,比如渲染图表、更新UI。结果手机发烫,连接断断续续。蓝牙BLE的传输速度本身很慢(通常20字节/包),你如果每收到一包数据就做一次setData,小程序会卡死。
优化策略:用一个队列缓存收到的数据,每200ms批量更新一次UI。比如收到100组温度数据,先存到数组里,定时器每200ms取最新一组渲染。这样既省电,又不会丢包。另外,notifyBLECharacteristicValueChange的间隔不要调得太短,设备端通常有“最小通知间隔”,你催得太紧,设备会主动断开。
真机调试蓝牙,每次都要扫码、连设备,烦不烦?我教你一个偏方:在微信开发者工具里,用wx.createBLEConnection连接一个“假的”设备。怎么实现?写一个Node.js脚本,用bleno库(注意是bleno,不是bluetooth)模拟一个BLE外设。你的小程序连上这个“假设备”,就可以在电脑上断点调试数据收发逻辑。这样,你连真机都不用,就能把协议调通。
- 多设备连接:微信小程序最多同时连接7个BLE设备,超过会报错。如果你要连接多个,务必在
onBLEConnectionStateChange里维护一个连接池。 - iOS和Android差异:iOS上,
notifyBLECharacteristicValueChange必须在主线程调用,否则没回调。Android上,部分机型需要先readBLECharacteristicValue一次,才能开启通知。 - 数据粘包:设备可能一次发超过20字节的数据,它会分包。你需要在收包时拼接
ArrayBuffer,根据协议头里的“总包数”判断是否收齐。 - 后台蓝牙:微信小程序切换到后台后,蓝牙连接会断开。这不是bug,是微信的机制。你可以在
onShow生命周期里重新连接。
如果你写过Web蓝牙(navigator.bluetooth),你会发现微信的SDK更像“阉割版”。Web蓝牙可以直接扫描、连接、读特征值,而微信的SDK需要你先getBLEDeviceServices再getBLEDeviceCharacteristics,多了一步。但微信的优势是:它天然支持“小程序生态”,不需要用户授权位置权限(Android 6.0以上需要位置权限,但微信帮你封装了)。如果你要做一个跨平台蓝牙应用,可以先用微信小程序验证协议,再用Web蓝牙做PC端。
最后的提醒:蓝牙开发的核心不是写代码,是“读协议”。你花1小时读设备的“蓝牙协议文档”,能省你5小时调试时间。如果厂家没给文档,用nRF Connect(手机App)扫描设备,手动发数据试探,比猜UUID靠谱一百倍。
