# 02_A2DP连接与断开流程 ## A2DP 是什么 ```text A2DP = 蓝牙音乐声音通道 手机音乐 App 播放出来的声音 ↓ 通过 A2DP ↓ 传到车机 ``` 在这个项目中,车机是 `A2DP Sink`,也就是音频接收端。 ## A2DP 连接成功流程 ```text 1. 手机和车机建立 A2DP 连接 ↓ 2. Android 系统发送 BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED ↓ 3. BluetoothConnectListenerClient.ConnectStatusReceiver.onReceive() ↓ 4. 判断 action 是 A2DP Sink 连接变化 ↓ 5. setA2dpConnectState(linkedInfo, intent) ↓ 6. newState == BluetoothProfile.STATE_CONNECTED ↓ 7. onA2dpConnect(linkedInfo) ↓ 8. BtMusicManager 收到 onA2dpConnect ↓ 9. BtMusicViewModel.onA2dpConnect() ↓ 10. mLiveDataA2dpConnectStatus.postValue(true) ↓ 11. BluetoothMusicActivity 观察到 true ↓ 12. setIsBtConnect(true) ↓ 13. 页面显示蓝牙音乐播放界面 ``` ## A2DP 断开流程 ```text 1. 手机断开 A2DP 或蓝牙关闭 ↓ 2. Android 系统发送 A2DP 断开广播 ↓ 3. BluetoothConnectListenerClient.setA2dpConnectState() ↓ 4. newState == BluetoothProfile.STATE_DISCONNECTED ↓ 5. onA2dpDisconnect(linkedInfo) ↓ 6. BtMusicManager.clearBtMusic() ↓ 7. resetMusicInfo() ↓ 8. 通知页面播放状态 false ↓ 9. BtMusicViewModel.onA2dpDisconnect() ↓ 10. mLiveDataA2dpConnectStatus.postValue(false) ↓ 11. BluetoothMusicActivity 显示未连接界面 ↓ 12. BtInfoPushManager.cleanBtMusic() ↓ 13. Launcher 卡片恢复默认状态 ``` ## 页面进入时的补连逻辑 这个逻辑在 `BluetoothMusicActivity.btMusicInfo()`。 ```text 1. 进入蓝牙音乐页 ↓ 2. BluetoothMusicActivity.onResume() ↓ 3. btMusicInfo() ↓ 4. getConnectedPhoneDevice() ↓ 5. 如果当前有手机设备 ↓ 6. 判断 A2DP 是否未连接且未处于连接中 ↓ 7. connectA2dp(device.getAddress()) ``` 这个逻辑的意义: ```text 如果手机已经和车机有蓝牙关系,但 A2DP 声音通道没有起来, 进入蓝牙音乐页时尝试补连 A2DP。 ``` ## 关键文件 | 文件 | 重点看 | |---|---| | `BluetoothConnectListenerClient.java` | 系统蓝牙连接广播如何分发。 | | `BluetoothA2dpSinkClient.java` | A2DP 是否连接、连接中、断开中、连接/断开方法。 | | `BtMusicManager.java` | A2DP 连接/断开后如何清状态、通知页面。 | | `BtMusicViewModel.java` | 如何把 A2DP 状态转成 LiveData。 | | `BluetoothMusicActivity.java` | 如何根据 `isBtConnect` 切换界面。 | ## 页面状态 | A2DP 状态 | `isBtConnect` | 页面 | |---|---|---| | 已连接 | `true` | 显示蓝牙音乐播放界面 | | 未连接 | `false` | 显示连接蓝牙提示 |