1. 蓝牙核心API演进史

Android 蓝牙 API 自 2009 年 Android 2.0(API 5)首次引入以来,经历了多次重大重构与废弃。理解各版本的关键变更节点与弃用标志,是实现向后兼容的根基。本章将从版本断代、关键 API 变更、以及官方标记体系三个维度,系统梳理演进脉络。

学习目标:掌握每个 Android 大版本中蓝牙 API 的增删改,能快速识别@Deprecated、REMOVED等标记,并建立“最低兼容版本 + 运行时检测”的思维模型。

1.1 Android 版本断代与 API 级别对应

下表列出所有引入蓝牙 API 重大变更的 Android 版本,以及对应的 API Level 和版本代号。后文所有讨论均以 API Level 为准。

Android 版本API Level代号核心蓝牙变更
2.05Eclair首次引入 BluetoothAdapter、BluetoothDevice、BluetoothSocket
4.014Ice Cream Sandwich增加 BluetoothHeadset 服务代理
4.217Jelly Bean MR1新增 BluetoothHealth 和 BluetoothGatt(BLE 预览)
5.021Lollipop正式发布 BluetoothLeScanner、ScanFilter,废弃 startLeScan()
6.023Marshmallow运行时权限 ACCESS_FINE_LOCATION 强制用于 BLE 扫描
1029Q新增 BluetoothLeAudio(LE Audio 基础),废弃 fetchUuidsWithSdp()
1231S新增 BluetoothLeScanner 的 startScan(ScanCallback) 强制需要 BLUETOOTH_SCAN 权限
1434UpsideDownCake废弃 BluetoothAdapter.getDefaultAdapter(),推荐 BluetoothManager.getAdapter()

1.2 关键 API 变更节点

以下按时间线列举对向后兼容影响最大的几个变更点。开发者必须为每个节点编写版本守卫代码。

  1. API 5 → API 17:仅经典蓝牙,无 BLE 支持。使用 BluetoothDevice.ACTION_FOUND 进行设备发现。
  2. API 17 → API 21:BLE 扫描使用 BluetoothAdapter.startLeScan(),该 API 在 API 21 被标记为 @Deprecated。
  3. API 21 → API 23:BLE 扫描迁移至 BluetoothLeScanner,但 API 23 起扫描需要位置权限。
  4. API 29 → API 31:新增 BLUETOOTH_SCAN、BLUETOOTH_CONNECT 运行时权限,旧权限 BLUETOOTH、BLUETOOTH_ADMIN 被逐步废弃。
  5. API 34:BluetoothAdapter.getDefaultAdapter() 被标记为 @Deprecated,需通过 BluetoothManager 获取。
常见错误:直接调用 startLeScan() 而不检查 API Level,会导致在 API 21+ 设备上编译通过但运行时触发废弃警告,并可能在未来的 Android 版本中被移除。同样,getDefaultAdapter() 在 API 34+ 设备上仍可工作,但后续版本可能返回 null 或抛出异常。

1.3 弃用与替代标记体系

Android 框架使用三种官方标记来标注 API 状态,理解其语义是兼容性编码的基础。

标记含义向后兼容处理
@Deprecated不推荐使用,未来可能移除运行时通过 Build.VERSION.SDK_INT 判断版本,分别调用新旧 API
@Removed(API 文档)在指定 API Level 后彻底移除必须在最低支持版本中删除引用,使用替代 API
@RequiresApi标注 API 最低需要的版本调用处需用 if (Build.VERSION.SDK_INT >= ...) 保护,或类/方法添加 @RequiresApi
// 示例:安全调用 BluetoothLeScanner(API 21+)同时兼容旧版 BLE 扫描
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
    scanner.startScan(filters, scanSettings, scanCallback);
} else {
    // 旧版 API 17-20
    bluetoothAdapter.startLeScan(leScanCallback);
}
实践要点:推荐所有涉及蓝牙的代码均使用 @TargetApi 标注当前方法所需的最低版本,并用 Build.VERSION.SDK_INT 运行时判断。不要在方法签名上统一使用 @RequiresApi 而忽略运行时保护,否则会引发 NoSuchMethodError。

1.4 API 演进时间线(SVG)

下图中展示了从 Android 2.0 到 Android 14 的关键 API 引入与废弃节点,深色节点表示重大引入,红色节点表示废弃或移除,连接线体现版本间的继承与覆盖关系。

Android 蓝牙 API 演进时间线(关键节点) Android 2.0 API 5 · 首次引入 Android 4.2 API 17 · BLE 预览 Android 5.0 API 21 · BLE 正式 Android 6.0 API 23 · 位置权限 Android 10 API 29 · LE Audio Android 12 API 31 · 新权限 Android 14 API 34 · 废弃旧API 标记说明 绿色:正式发布/替代 红色:废弃/移除

1.5 向后兼容核心策略

基于上述演进史,向后兼容实践应遵循以下标准流程:

  1. 确定最低支持版本(通常为 API 17 或 API 21)。
  2. 在代码中针对每个关键节点使用 Build.VERSION.SDK_INT 进行分支。
  3. 为每个废弃 API 准备对应版本的替代实现,并添加单元测试。
  4. 使用 @TargetApi 注解标记方法所依赖的最高版本,以避免 Lint 警告。
  5. 定期用 lint --check Deprecation 检查项目中已废弃的 API 调用。