跟经典蓝牙(BR/EDR)对比,BLE可以实现功更低耗、但带宽更小;例如未建立连接时,BLE 会处于睡眠模式。蓝牙芯片分单模和双模,其中双模是指同时支持BR/EDR和BLE(一般是共享一个天线、芯片在运行时切换模式)。安卓设备上,蓝牙是作为标配功能(OS 4.3及以上是双模芯片),因此潜在用户市场很大。
蓝牙应用通过 Binder 与蓝牙进程进行通信。而蓝牙进程使用 JNI 与蓝牙堆栈通信,并向开发者提供对各种蓝牙配置文件的访问。下图显示了蓝牙堆栈的整体结构:

从上往下、从左往右,依次为:
1.Application Framework
应用代码位于应用框架级别,它使用 android.bluetooth API 与蓝牙硬件进行交互;而API代码内部是通过 Binder IPC 机制调用蓝牙进程。
2.Bluetooth System Service
蓝牙系统服务(位于 packages/apps/Bluetooth 中)是打包成 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 接口调用原生蓝牙堆栈。
3.JNI
与 android.bluetooth 相关的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当执行特定蓝牙操作时(例如调用发现设备),JNI 代码就会调用蓝牙堆栈。
4.Bluetooth Stack
AOSP 中提供了默认蓝牙堆栈(位于 system/bt )。该堆栈实现经典蓝牙 HAL,并通过扩展程序和更改配置实现了定制。
5.Vendor Implementation
供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互。
简而言之,安卓蓝牙开发是要使用系统bluetooth接口,运行时是跟”蓝牙进程”进行调用、并接收回调。而安卓Bluetooth Stack已通过SIG认证,因此安卓应用应该遵循相关规范。
要想使用蓝牙BLE功能,最低版本为4.3(android-4.3-BLE-unstable),但考虑到接口功能完整性(5.0及以上才能修改MTU,还引入了BluetoothLeScanner/ScanFilter)和蓝牙堆栈的稳定性(有些系统BUG到8.1才真正Fixed掉),建议最低版本使用安卓5.0,如果能用7.0及以上则更好。
在 Android 8.0 中,原生蓝牙堆栈完全符合蓝牙 5 的要求,但是要使用蓝牙 5 功能,设备需要具有符合蓝牙 5 要求的芯片组,而实际情况:不少8.1/9.0设备仍使用蓝牙4.1/4.2芯片组,因此此时还不能使用蓝牙5特性功能(高码率或远距离)。
已知限制
如果扫描不到设备,需先确定下列几项是否满足: 1)蓝牙是否打开 2)蓝牙相关权限是否授权(6.0以上位置权限) 3)7.0以上手机很多需要手动打开定位功能
连接设备限制(手机同时连接经典蓝牙和BLE设备的总数),对应常量是BTA_GATTC_CONN_MAX(代码在Bluetooth Stack ,Android: Limit of simultaneous BLE connections - Stack Overflow)。一般是7设备左右(手机厂商可修改),因为每个连接都会占用一定系统资源,低端机