蓝牙低功耗 (BLE) 是一种无线通信标准,针对以最低功耗传输少量数据进行了优化。根据 Bluetooth SIG,2025 的数据,该技术在全球超过 50 亿台设备中使用。GATT(通用属性协议)将数据组织成服务 → 特征 → 描述符的层次结构,这是所有 iOS 和 Android BLE 应用的基础。
关键要点
蓝牙低功耗 (BLE) 采用客户端-服务器模型,具有两个角色:Central(移动设备)和 Peripheral(设备)。Central 扫描空中信号并发起连接,而 Peripheral 传输数据。与经典蓝牙不同,BLE 并非为音频流设计 — 其任务是以最低功耗传输小数据包。根据蓝牙 SIG 核心规范 5.4(2025),BLE 在活动模式下支持高达 2 Mbps 的速度,电流低于 15 mA。
GATT(通用属性协议)定义了蓝牙低功耗的数据结构。服务是特征的逻辑组(例如,心率服务 0x180D)。特征是具有特定值的数据点。描述符是特征的元数据,包括用于通知管理的 CCCD。每个元素都有一个 UUID — 标准蓝牙 SIG 配置文件为 16 位,自定义为 128 位。
移动应用中的蓝牙低功耗使用此层次结构来组织智能手机与外围设备之间的数据交换。正确理解 GATT 是在两个平台上开发 BLE 应用的基础。开发者必须知道设备的服务和特征的 UUID,以及每个特征的属性(读、写、通知、指示)。
BLE 设备传输广播数据包以便被发现。广播数据包含设备名称、服务 UUID、RSSI 和制造商特定数据。广播数据包大小限制为 31 字节。要传输额外数据,可使用扫描响应 — 中央设备在发现后请求的第二个数据包。
在 iOS 上,Core Bluetooth 框架负责蓝牙低功耗。CBCentralManager 管理扫描和连接,CBPeripheral 代表远程 BLE 设备。过程是标准的:初始化 CBCentralManager,检查 poweredOn 状态,启动 scanForPeripherals,连接和发现服务。Core Bluetooth 自动管理无线电模块的电源 — 如果不使用 BLE,它将关闭。
iOS 上的移动开发中的 BLE 需要考虑后台模式。Core Bluetooth 后台模式通过项目的 Capabilities(使用蓝牙 LE 配件)启用。在后台,应用可以接收来自特征的通知,但扫描受限 — 系统仅在设备移动时重新启动扫描。对于 iBeacon,后台扫描通过 CLLocationManager 更活跃地工作。
import CoreBluetooth
class DeviceScanner: NSObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
func start() {
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
guard central.state == .poweredOn else { return }
central.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber) {
print("找到: \(peripheral.name ?? "unknown")")
}
}
在此示例中,CBCentralManagerDelegate 处理所有 BLE 连接事件。centralManagerDidUpdateState 方法检查移动设备上的蓝牙是否已打开。成功初始化后,扫描开始。每次发现设备时都会调用 didDiscover 回调。
发现设备后,需要调用 connect 和 discoverServices。CBPeripheralDelegate 提供处理每个步骤的方法:didDiscoverServices、didDiscoverCharacteristics、didUpdateValueFor。每个方法都是异步的 — 数据通过委托回调到达。RSSI(接收信号强度指示器)显示信号强度:值越接近 0,信号越强。
在 Android 上,蓝牙低功耗通过 android.bluetooth 包实现。BluetoothAdapter 是所有 BLE 操作的入口点。BluetoothLeScanner 使用 ScanCallback 回调启动扫描。发现设备后,会创建 BluetoothGatt — 到外设的连接。BluetoothGattCallback 处理事件:连接、服务发现、特征读取、RSSI 变化。
Android 上移动应用中的蓝牙低功耗需要明确的 BLUETOOTH_SCAN、BLUETOOTH_CONNECT 和 ACCESS_FINE_LOCATION 权限。自 Android 12 起,权限已分离:BLUETOOTH_SCAN 用于扫描,BLUETOOTH_CONNECT 用于连接。ACCESS_FINE_LOCATION 仅用于扫描某些类型的设备。没有这些权限,应用无法使用 BLE。
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter) {
fun startScan() {
val scanner = bluetoothAdapter.bluetoothLeScanner
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
scanner.startScan(null, settings, scanCallback)
}
private val scanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
val device = result.device
val rssi = result.rssi
Log.d("BLE", "设备: ${device.name},RSSI: $rssi")
}
}
}
ScanSettings 允许配置扫描模式:LOW_POWER 用于省电,BALANCED 用于标准任务,LOW_LATENCY 用于最大发现速度。ScanFilter 按照服务 UUID、设备名称或 MAC 地址缩小搜索范围。过滤可降低功耗并加快所需设备的发现速度。
通过 connectGatt 创建 BluetoothGatt 后,应用调用 discoverServices。BluetoothGattCallback 包含 onServicesDiscovered、onCharacteristicRead、onCharacteristicChanged。要接收有关特征更改的通知,需要调用 setCharacteristicNotification。该过程需要仔细处理:每个 GATT 操作都是异步的,结果在单独的回调中返回。
iBeacon 是 Apple 用于传输 UUID、Major 和 Minor 的 BLE 信标技术。信标设备广播数据包,移动应用根据这些数据确定位置和距离。在 iOS 上,iBeacon 通过 CLLocationManager 原生支持。在 Android 上,需要第三方库(例如 AltBeacon 或 Android iBeacon Library)。
Bonding 是在 BLE 设备之间创建永久安全连接的过程。Bonding 后,加密密钥被保存,设备再次靠近时自动连接。在 iOS 上,系统自动管理 bonding。在 Android 上 — 通过 BluetoothDevice.createBond()。Bonding 对于需要快速重新连接的可穿戴设备和健身追踪器非常重要。
广播数据是蓝牙低功耗中的关键发现机制。设备制造商可以向广播数据包添加制造商特定数据以传输自定义数据。数据包格式包括公司标识符(2 字节)和任意数据。在 iOS 上,CBCentralManager 接受服务 UUID 数组进行过滤 — 这可以节省电池。在 Android 上,ScanFilter 遵循相同原理。
| 参数 | iOS(Core Bluetooth) | Android(BluetoothGatt) |
|---|---|---|
| 管理器 | CBCentralManager | BluetoothLeScanner |
| 连接 | connect(to:) | connectGatt() |
| 服务 | discoverServices() | discoverServices() |
| 读取 | readValue(for:) | readCharacteristic() |
| 通知 | setNotifyValue(_:for:) | setCharacteristicNotification() |
| 权限 | 自动 | BLUETOOTH_SCAN、BLUETOOTH_CONNECT |
| iBeacon | CLLocationManager(原生) | AltBeacon / 库 |
MTU(最大传输单元)是单个蓝牙低功耗数据包的最大大小。默认情况下,MTU 为 23 字节(3 字节标头 + 20 字节数据)。将 MTU 增加到 512 字节可显著加快配置或日志交换时的传输速度。在 iOS 上,maximumWriteValueLength 显示可用的 MTU。在 Android 上,使用 requestMtu() 增加 MTU。
连接间隔是中央设备轮询外设的频率。间隔越短,传输速度越快,但功耗也越高。典型值范围为 7.5 毫秒到 4 秒。对于健身追踪器,100 毫秒就足够了;对于音频 — 7.5 毫秒。移动开发中的 BLE 需要在传输速度和设备电池寿命之间取得平衡。
iOS 通过后台模式支持 BLE 在后台运行,但有限制。后台应用可以接收特征通知,但不能主动扫描。系统在设备位置改变时重新启动扫描。在 Android 上,后台扫描需要带有持久通知的前台服务。否则,移动系统将在应用最小化时终止进程。
为确保 BLE 在移动应用中可靠运行,请遵循以下规则。使用通知代替轮询 — 具有通知功能的特征在变化时发送数据,节省电池。在连接开始时设置最佳 MTU。扫描时按服务 UUID 过滤设备。检查不同型号上的 BLE 堆栈兼容性 — 制造商(小米、华为、三星)会进行影响蓝牙行为的更改。
常见问题
蓝牙低功耗 (BLE) 针对低功耗下的小数据包定期传输进行了优化。经典蓝牙设计用于音频流和大量数据的连续传输。
GATT(通用属性协议)是 BLE 中的数据交换协议,定义了服务 → 特征 → 描述符的层次结构。GATT 用于从 BLE 设备读取、写入和接收通知。
在 Android 12 之前,BLE 扫描可用于确定位置,因此 Google 合并了这些权限。自 Android 12 起,引入了单独的 BLUETOOTH_SCAN 权限,与位置无关。
通过 Android 上的 requestMtu() 和 iOS 上的 maximumWriteValueLength 增加 MTU。连接间隔也会影响速度 — 越小传输越快。最佳组合可提供高达 10 倍的改进。
Bonding 是在 BLE 设备之间创建永久安全连接的过程。Bonding 后,加密密钥被保存,设备无需重复搜索即可自动连接。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。