一、蓝牙在物联网中的应用全景

物联网这个词,大家听得太多了。但真正落地的时候,你会发现蓝牙才是那个最实在的连接方式。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);
}
个人经验:血氧设备的数据格式更复杂。我曾经被一个厂商的私有协议坑过——他们把 SpO2 值放在 Manufacturer Specific Data 里,而不是标准 Service。所以对接健康设备时,一定要先看厂商的 Protocol Spec,别盲目相信标准。

1.3 工业数据采集

工业场景听起来跟蓝牙不搭边?其实不是。工厂里大量传感器(温度、振动、压力)需要无线采集,而 BLE 的广播模式可以做到「一发多收」,一个传感器数据可以被多个网关同时收到,实现冗余备份。

我参与过一个工厂项目,用 BLE 采集 200 多个振动传感器的数据。难点在于:传感器每秒发 10 个包,200 个设备就是 2000 包/秒。BLE 的广播信道只有 3 个,碰撞率会很高。我们当时的方案是:

  • 每个传感器随机延迟 0-100ms 发送
  • 网关侧用多通道扫描(同时扫描 37/38/39 三个广播信道)
  • 数据包带序列号,网关去重

这样做下来,丢包率从 15% 降到了 2% 以内。说白了,工业场景下蓝牙不是不能用,而是需要针对性地做优化。

二、蓝牙 IoT 的核心技术栈

不管你是做灯、做锁、做手环还是做传感器,底层技术栈其实大同小异。我画了一张图,帮你理清整体架构:

蓝牙 IoT 应用技术栈 应用层 智能家居App / 健康App / 工业采集平台 协议层 GATT / HDP / Mesh Profile / 私有协议 蓝牙核心层 BLE 5.x / Classic / 双模 硬件层 Nordic / TI / Dialog / 国产芯片 Android 蓝牙框架位于协议层与应用层之间,提供标准 API

这张图其实想表达一个意思:不管上层怎么变,底层蓝牙核心层和硬件层是相对稳定的。你只要把协议层吃透,换什么应用场景都能快速上手。

三、Android 端的开发要点

Android 做蓝牙 IoT 开发,有几个绕不开的坑。我一个个说。

3.1 扫描策略

BLE 扫描是功耗大头。很多开发者上来就全速扫描,结果手机发烫、电量狂掉。正确的做法是:

  • 使用 ScanSettings.SCAN_MODE_LOW_POWER 做后台扫描
  • 需要快速发现设备时,临时切换到 SCAN_MODE_LOW_LATENCY
  • 扫描回调里做过滤,别把所有设备都往 UI 抛
注意:Android 8.0 之后,后台扫描有严格限制。如果你的 App 在后台,扫描结果会被延迟或丢弃。解决方案是用前台服务 + 通知,或者用 BluetoothLeScannerstartScanPendingIntent

3.2 连接与重连

IoT 设备不像手机,它们可能随时断电、移动、休眠。连接管理是重中之重。

我个人的习惯是:

  • BluetoothGattconnect() 方法,不要用 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 文档里根本没提。最后我是用抓包工具对比着看出来的。

建议:开发阶段一定要用 nRF Connect 或 Wireshark 抓包确认数据格式。不要相信厂商的「标准实现」,实测才是王道。

四、总结

蓝牙在物联网中的应用,说白了就是三个字:低功耗、短距离、低成本。智能家居、健康设备、工业采集,这三个方向基本覆盖了 90% 的蓝牙 IoT 场景。

做 Android 端开发,核心能力是:

  1. 理解 BLE 协议栈(GATT、广播、扫描)
  2. 掌握连接管理和状态机
  3. 能解析各种私有数据格式
  4. 会做功耗和性能优化

这些能力不是看一遍文档就能掌握的。后面几章我会带你深入每个细节,包括 Mesh 组网、蓝牙网关架构、以及如何跟 iOS 做互操作。嗯,咱们一步步来。


公众号:蓝海资料掘金营,微信 deep3321