一、蓝牙在物联网中的应用全景
物联网这个词,大家听得太多了。但真正落地的时候,你会发现蓝牙才是那个最实在的连接方式。Wi-Fi 功耗高、Zigbee 生态乱、5G 模组贵——而蓝牙,尤其是 BLE,几乎成了 IoT 设备的标配。
我在做智能家居项目时,遇到过客户非要上 Wi-Fi 直连,结果一个灯泡待机功耗 0.5W,用户直接炸毛。后来换成 BLE Mesh,待机降到 0.01W,问题就解决了。说白了,选蓝牙不是因为它最强,而是因为它最「合适」。
1.1 智能家居:灯、锁、传感器
智能家居是蓝牙 IoT 最典型的战场。你想想看,家里几十个设备,如果每个都要配网、都要连路由器,那体验得多糟糕?蓝牙 Mesh 的出现,让设备之间可以互相转发消息,一个网关就能覆盖全屋。
- 智能灯:开关、调色、场景联动(如回家自动亮灯)
- 智能锁:手机开锁、指纹+蓝牙双通道、临时密码分享
- 传感器:温湿度、人体红外、门窗磁——这些设备通常用 BLE 广播包上报数据,功耗极低
我记得有个项目,客户要求门锁在低电量时还能用蓝牙开锁。我们当时在协议栈里加了个「紧急广播」模式——电池只剩 5% 时,锁会以最低功耗广播一个特殊包,手机收到后自动降低连接间隔,保证开锁成功。嗯,这种细节,不踩坑是想不到的。
1.2 健康设备:心率、血氧
健康穿戴是 BLE 的另一个大本营。心率、血氧、体温、睡眠——这些数据的特点是:量小、实时、需要低功耗。BLE 的 GATT 协议正好完美匹配。
Android 上做健康设备开发,核心是理解 Health Device Profile (HDP) 和 Bluetooth SIG 定义的标准 Service。比如心率 Service 的 UUID 是 0x180D,里面包含心率测量特征值 0x2A37。
// 心率数据解析示例
BluetoothGattCharacteristic heartRateChar = ...;
byte[] value = heartRateChar.getValue();
int flags = value[0] & 0xFF;
int heartRate;
if ((flags & 0x01) == 0) {
// 8 位心率值
heartRate = value[1] & 0xFF;
} else {
// 16 位心率值
heartRate = ((value[2] & 0xFF) << 8) | (value[1] & 0xFF);
}
1.3 工业数据采集
工业场景听起来跟蓝牙不搭边?其实不是。工厂里大量传感器(温度、振动、压力)需要无线采集,而 BLE 的广播模式可以做到「一发多收」,一个传感器数据可以被多个网关同时收到,实现冗余备份。
我参与过一个工厂项目,用 BLE 采集 200 多个振动传感器的数据。难点在于:传感器每秒发 10 个包,200 个设备就是 2000 包/秒。BLE 的广播信道只有 3 个,碰撞率会很高。我们当时的方案是:
- 每个传感器随机延迟 0-100ms 发送
- 网关侧用多通道扫描(同时扫描 37/38/39 三个广播信道)
- 数据包带序列号,网关去重
这样做下来,丢包率从 15% 降到了 2% 以内。说白了,工业场景下蓝牙不是不能用,而是需要针对性地做优化。
二、蓝牙 IoT 的核心技术栈
不管你是做灯、做锁、做手环还是做传感器,底层技术栈其实大同小异。我画了一张图,帮你理清整体架构:
这张图其实想表达一个意思:不管上层怎么变,底层蓝牙核心层和硬件层是相对稳定的。你只要把协议层吃透,换什么应用场景都能快速上手。
三、Android 端的开发要点
Android 做蓝牙 IoT 开发,有几个绕不开的坑。我一个个说。
3.1 扫描策略
BLE 扫描是功耗大头。很多开发者上来就全速扫描,结果手机发烫、电量狂掉。正确的做法是:
- 使用
ScanSettings.SCAN_MODE_LOW_POWER做后台扫描 - 需要快速发现设备时,临时切换到
SCAN_MODE_LOW_LATENCY - 扫描回调里做过滤,别把所有设备都往 UI 抛
BluetoothLeScanner 的 startScan 传 PendingIntent。
3.2 连接与重连
IoT 设备不像手机,它们可能随时断电、移动、休眠。连接管理是重中之重。
我个人的习惯是:
- 用
BluetoothGatt的connect()方法,不要用autoConnect=false(除非你确定设备一直在附近) - 连接超时设为 10 秒,超时后主动断开并重试
- 维护一个连接状态机:DISCONNECTED -> CONNECTING -> CONNECTED -> DISCONNECTED
// 连接状态机示例
enum ConnectionState {
DISCONNECTED,
CONNECTING,
CONNECTED,
DISCONNECTING
}
private ConnectionState state = ConnectionState.DISCONNECTED;
public void connect(BluetoothDevice device) {
if (state != ConnectionState.DISCONNECTED) return;
state = ConnectionState.CONNECTING;
gatt = device.connectGatt(context, false, callback);
// 启动超时定时器
handler.postDelayed(timeoutRunnable, 10000);
}
3.3 数据解析与兼容性
不同厂商的 IoT 设备,数据格式千奇百怪。有的把温度放在 Service Data 里,有的放在 Manufacturer Data 里,还有的用自定义 Service。
我曾经对接过一个智能灯,它的开关状态居然藏在广播包的 AdvData 的第 7 个字节的低 2 位。厂商文档写的是「参考 SDK 文档」,但 SDK 文档里根本没提。最后我是用抓包工具对比着看出来的。
四、总结
蓝牙在物联网中的应用,说白了就是三个字:低功耗、短距离、低成本。智能家居、健康设备、工业采集,这三个方向基本覆盖了 90% 的蓝牙 IoT 场景。
做 Android 端开发,核心能力是:
- 理解 BLE 协议栈(GATT、广播、扫描)
- 掌握连接管理和状态机
- 能解析各种私有数据格式
- 会做功耗和性能优化
这些能力不是看一遍文档就能掌握的。后面几章我会带你深入每个细节,包括 Mesh 组网、蓝牙网关架构、以及如何跟 iOS 做互操作。嗯,咱们一步步来。
公众号:蓝海资料掘金营,微信 deep3321