Files
Obsidian/项目文档/同力/蓝牙音乐/04_播放控制与音频焦点流程.md
T
2026-11-05 14:35:04 +08:00

3.7 KiB

04_播放控制与音频焦点流程

页面按钮控制流程

1. 用户点击蓝牙音乐页面按钮
   ↓
2. BluetoothMusicActivity.onClick()
   ↓
3. 根据按钮 ID 判断动作
   ↓
4. 调用 BtMusicViewModel
   ↓
5. BtMusicViewModel 调用 BtMusicControlManager
   ↓
6. BtMusicControlManager 调用 BtMusicManager
   ↓
7. BtMusicManager 调用 BluetoothAvrcpClient
   ↓
8. BluetoothAvrcpClient 调用 MediaController.TransportControls
   ↓
9. 手机音乐 App 响应

页面按钮映射

控件 ID 方法 最终 AVRCP 控制
iv_bt_music_pre preBtMusic() skipToPrevious()
iv_bt_music_state playBtMusic() / pauseBtMusic() play() / pause()
iv_bt_music_next nextBtMusic() skipToNext()

播放命令详细链路

BluetoothMusicActivity.onClick()
  ↓
mViewModel.playBtMusic()
  ↓
BtMusicViewModel.playBtMusic()
  ↓
BtMusicControlManager.playBtMusic()
  ↓
BtMusicManager.requestFocus()
  ↓
BtMusicAudioManager.requestAudioFocus()
  ↓
BtMusicManager.playBtMusic()
  ↓
BluetoothAvrcpClient.play()
  ↓
TransportControls.play()

暂停命令详细链路

BluetoothMusicActivity.onClick()
  ↓
mViewModel.pauseBtMusic()
  ↓
BtMusicViewModel.pauseBtMusic()
  ↓
BtMusicControlManager.pauseBtMusic()
  ↓
BtMusicManager.pauseBtMusic()
  ↓
BluetoothAvrcpClient.pause()
  ↓
TransportControls.pause()

切歌命令详细链路

上一曲:
BluetoothMusicActivity
  ↓
BtMusicViewModel.preBtMusic()
  ↓
BtMusicControlManager.preBtMusic()
  ↓
BtMusicManager.preBtMusic()
  ↓
BluetoothAvrcpClient.previous()
  ↓
TransportControls.skipToPrevious()

下一曲:
BluetoothMusicActivity
  ↓
BtMusicViewModel.nextBtMusic()
  ↓
BtMusicControlManager.nextBtMusic()
  ↓
BtMusicManager.nextBtMusic()
  ↓
BluetoothAvrcpClient.next()
  ↓
TransportControls.skipToNext()

音频焦点是什么

音频焦点 = 当前谁有资格出声

车机里可能同时有:
  蓝牙音乐
  收音机
  USB 音乐
  视频
  导航播报
  蓝牙电话

所以蓝牙音乐播放前必须申请焦点。

焦点申请流程

1. 用户点击播放
   ↓
2. BtMusicManager.requestFocus()
   ↓
3. BtMusicAudioManager.requestAudioFocus()
   ↓
4. AudioManager.requestAudioFocus()
   ↓
5. 如果返回 AUDIOFOCUS_REQUEST_GRANTED
   ↓
6. setA2dpUnMute()
   ↓
7. isFocus = true
   ↓
8. setMediaButtonEvent()
   ↓
9. 允许执行 AVRCP play()

焦点变化处理

焦点变化 处理
AUDIOFOCUS_GAIN 恢复 A2DP 出声,必要时恢复播放,通知语音当前是蓝牙音乐。
AUDIOFOCUS_LOSS 释放焦点,暂停蓝牙音乐,清空 Launcher 蓝牙音乐信息。
AUDIOFOCUS_LOSS_TRANSIENT 临时失焦,A2DP 静音,暂停蓝牙音乐。
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 降低蓝牙音乐音量。

失焦流程

1. 其他音源抢焦点
   ↓
2. BtMusicAudioManager.mAudioFocusListener.onAudioFocusChange()
   ↓
3. 收到 AUDIOFOCUS_LOSS 或 AUDIOFOCUS_LOSS_TRANSIENT
   ↓
4. 记录当前是否正在播放
   ↓
5. setA2dpMute()
   ↓
6. BtMusicManager.pauseBtMusic()
   ↓
7. 手机音乐暂停

恢复焦点流程

1. 蓝牙音乐重新获得焦点
   ↓
2. 收到 AUDIOFOCUS_GAIN
   ↓
3. isFocus = true
   ↓
4. setA2dpUnMute()
   ↓
5. 如果 isPlayingLossFocus == true
   ↓
6. BtMusicManager.playBtMusic()
   ↓
7. 手机音乐恢复播放

注意点

BluetoothA2dpSinkClient 中这两个方法底层调用目前被注释:

setFluorideAudioTrackGain()
setFluorideStreaming()

所以焦点切换时,A2DP 静音/恢复是否真正生效,需要真机验证。