Android 提供支持经典蓝牙和蓝牙低功耗的默认蓝牙堆栈。借助蓝牙,Android 设备可以创建个人区域网络,以便通过附近的蓝牙设备发送和接收数据。
在 Android 4.3 及更高版本中,Android 蓝牙堆栈可提供实现蓝牙低功耗 (BLE) 的功能。要充分利用 BLE API,请遵循 Android 蓝牙 HCI 要求。
具有合格芯片组的 Android 设备可以实现经典蓝牙或同时实现经典蓝牙和 BLE。BLE 不能向后兼容较旧版本的蓝牙芯片组。
在 Android 8.0 中,原生蓝牙堆栈完全符合蓝牙 5 的要求。要使用可用的蓝牙 5 功能,该设备需要具有符合蓝牙 5 要求的芯片组。
注意:与之前的版本相比,Android 8.0 在原生蓝牙堆栈方面的最大变化是使用了 Treble。Android 8.0 中的供应商实现必须使用 HIDL 而不是 libbt-vendor
。
一.Android 8.0 架构
![](https://i-blog.csdnimg.cn/blog_migrate/e2eabf614a6ede19e8d6a769f629d812.png)
应用框架:处于应用框架级别的是应用代码,它使用 android.bluetooth(位于frameworks/base/core/java/android/bluetooth/) API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。
蓝牙系统服务:位于 packages/apps/Bluetooth 中,被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 调用原生蓝牙堆栈。
JNI:与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用蓝牙堆栈。
蓝牙堆栈:Android系统在 AOSP 中提供了默认蓝牙堆栈,它位于 system/bt 中。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。
供应商实现:供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互。
HIDL:HIDL 定义了蓝牙堆栈和供应商实现之间的接口。要生成蓝牙 HIDL 文件,请将蓝牙接口文件传递到 HIDL 生成工具中。接口文件位于 hardware/interfaces/bluetooth 中。
蓝牙堆栈开发:Android 8.0 蓝牙堆栈是一个完全限定的蓝牙堆栈。限定列表位于蓝牙 SIG 网站上的 QDID 97584 下。核心蓝牙堆栈位于 system/bt 中。
二.Android 7.x 及更早版本的架构
![](https://i-blog.csdnimg.cn/blog_migrate/63a219c74b2f2911ce8490cfbc4e6206.png)
应用框架:处于应用框架级别的是应用代码,它利用 android.bluetooth API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。
蓝牙系统服务:位于 packages/apps/Bluetooth 中,被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。该应用通过 JNI 调用 HAL 层。
JNI:与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用 HAL 层并从 HAL 接收回调。
HAL硬件抽象层:定义了 android.bluetooth API 和蓝牙进程会调用的标准接口,并且必须实现该接口才能使蓝牙硬件正常工作。 蓝牙 HAL 的头文件是 hardware/libhardware/include/hardware/bluetooth.h。
另外,请查看所有 hardware/libhardware/include/hardware/bt_*.h 文件。
蓝牙堆栈:Android系统提供了默认蓝牙堆栈(位于 system/bt 中)。该堆栈会实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。
供应商扩展:要添加自定义扩展程序和用于跟踪的 HCI 层,可以创建一个 libbt-vendor 模块并指定这些组件。
实现HAL:蓝牙 HAL 位于 /hardware/libhardware/include/hardware/bluetooth.h
中。 bluetooth.h
文件包含蓝牙堆栈的基本接口,而且您必须实现其功能。
三、Android源码分析
一、BluetoothAdapter类的初始化
frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null ) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); //1 if (b != null ) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); //2 sAdapter = new BluetoothAdapter(managerService); //3 } else { Log.e(TAG, "Bluetooth binder is null" ); } } return sAdapter; } 1 .获取蓝牙管理服务,SystemServer进程中创建:mSystemServiceManager.startService(BluetoothService. class ); 2 .使用Binder获取到BluetoothManagerService对象 3 .创建BluetoothAdapter对象,单例模式 BluetoothAdapter(IBluetoothManager managerService) { if (managerService == null ) { throw new IllegalArgumentException( "bluetooth manager service is null" ); } try { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); //1 } catch (RemoteException e) { Log.e(TAG, "" , e); } finally { mServiceLock.writeLock().unlock(); } mManagerService = managerService; mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(); } 1 .向BluetoothManagerService类注册回调函数 |
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public IBluetooth registerAdapter(IBluetoothManagerCallback callback) { if (callback == null ) { Slog.w(TAG, "Callback is null in registerAdapter" ); return null ; } Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER); //1 msg.obj = callback; mHandler.sendMessage(msg); return mBluetooth; } 1 .注册监听,将接口保存到RemoteCallbackList<IBluetoothManagerCallback> mCallbacks; |
二、Bluetooth Profiles的使用
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.getProfileProxy(mService, new A2dpServiceListener(),BluetoothProfile.A2DP);
frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, int profile) { if (context == null || listener == null ) { return false ; } if (profile == BluetoothProfile.HEADSET) { BluetoothHeadset headset = new BluetoothHeadset(context, listener); return true ; } else if (profile == BluetoothProfile.A2DP) { BluetoothA2dp a2dp = new BluetoothA2dp(context, listener); return true ; } else if (profile == BluetoothProfile.A2DP_SINK) { BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener); return true ; } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) { BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener); return true ; } else if (profile == BluetoothProfile.HID_HOST) { BluetoothHidHost iDev = new BluetoothHidHost(context, listener); return true ; } else if (profile == BluetoothProfile.PAN) { BluetoothPan pan = new BluetoothPan(context, listener); return true ; } else if (profile == BluetoothProfile.HEALTH) { BluetoothHealth health = new BluetoothHealth(context, listener); return true ; } else if (profile == BluetoothProfile.MAP) { BluetoothMap map = new BluetoothMap(context, listener); return true ; } else if (profile == BluetoothProfile.HEADSET_CLIENT) { BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener); return true ; } else if (profile == BluetoothProfile.SAP) { BluetoothSap sap = new BluetoothSap(context, listener); return true ; } else if (profile == BluetoothProfile.PBAP_CLIENT) { BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener); return true ; } else if (profile == BluetoothProfile.MAP_CLIENT) { BluetoothMapClient mapClient = new BluetoothMapClient(context, listener); return true ; } else if (profile == BluetoothProfile.HID_DEVICE) { BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener); return true ; } else if (profile == BluetoothProfile.HEARING_AID) { BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener); return true ; } else { return false ; } } |
frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java
/*package*/ BluetoothA2dp(Context context, ServiceListener l) { mContext = context; mServiceListener = l; mAdapter = BluetoothAdapter.getDefaultAdapter(); IBluetoothManager mgr = mAdapter.getBluetoothManager(); //1 if (mgr != null ) { try { mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); //2 } catch (RemoteException e) { Log.e(TAG, "" , e); } } doBind(); //3 } 1 .从BluetoothAdapter类中获取到蓝牙管理服务对象 2 .注册A2DP状态回调接口 3 .绑定蓝牙A2DP Service boolean doBind() { Intent intent = new Intent(IBluetoothA2dp. class .getName()); //1 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0 ); intent.setComponent(comp); if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0 , mContext.getUser())) { Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent); return false ; } return true ; } 1 .绑定A2dpService(位于packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/),实现与Bluetooth进程通信 |