# 03_AVRCP歌曲信息与播放状态流程 ## AVRCP 是什么 ```text AVRCP = 蓝牙媒体控制协议 它负责两类事情: 1. 车机控制手机:播放、暂停、上一曲、下一曲 2. 手机告诉车机:歌名、歌手、封面、播放状态、进度 ``` ## MediaBrowser 连接流程 ```text 1. BluetoothAvrcpClient.init(context) ↓ 2. initMediaBrowserHelper() ↓ 3. new MediaBrowserClient(context) ↓ 4. MediaBrowserClient 连接系统服务: com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService ↓ 5. 连接成功后创建 MediaControllerCompat ↓ 6. 注册 MediaControllerCompat.Callback ↓ 7. 可以接收 metadata 和 playbackState ``` ## 歌曲信息流程 ```text 1. 手机音乐 App 播放或切歌 ↓ 2. 手机通过 AVRCP 上报 metadata ↓ 3. Android 蓝牙服务接收 metadata ↓ 4. MediaBrowserClient.mediaControlCallback.onMetadataChanged() ↓ 5. BluetoothAvrcpClient.callback.onMetadataChanged() ↓ 6. BtMusicManager.onMetadataChanged() ↓ 7. 解析字段: artist title album albumUrl duration ↓ 8. 保存到 MusicInfo ↓ 9. 通知 BtMusicViewModel.onPlayMusicInfo() ↓ 10. mLiveDataMusicInfo.postValue(musicInfo) ↓ 11. BluetoothMusicActivity 更新 UI ``` ## 播放状态流程 ```text 1. 手机音乐播放状态变化 ↓ 2. MediaBrowserClient.onPlaybackStateChanged() ↓ 3. BluetoothAvrcpClient.onPlaybackStateChanged() ↓ 4. BtMusicManager.onPlaybackStateChanged() ↓ 5. 判断: state == PlaybackStateCompat.STATE_PLAYING ↓ 6. 更新 MusicInfo.isPlaying ↓ 7. 更新 MusicInfo.playPosition ↓ 8. 通知 BtMusicViewModel.onPlayMusicState(isPlaying) ↓ 9. BluetoothMusicActivity 更新播放按钮图标 ``` ## 同步给 Launcher 的流程 同样的 AVRCP 数据,还会推给桌面卡片。 ```text BluetoothAvrcpClient.onMetadataChanged() ↓ BtInfoPushManager.sendMusicInfoToLauncher() ↓ 转换为 BtMusicInfo ↓ DataManager.putObject(BT_MUSIC_INFO, btInfo) ↓ 发送 ACTION_UPDATE_MUSIC_WIDGET ↓ Launcher 卡片刷新 ``` 播放状态也是类似: ```text BluetoothAvrcpClient.onPlaybackStateChanged() ↓ BtInfoPushManager.sendMusicStateToLauncher() ↓ DataManager.putObject(BT_MUSIC_INFO, btInfo) ↓ Launcher 卡片刷新 ``` ## MusicInfo 字段 | 字段 | 含义 | 来源 | |---|---|---| | `artist` | 歌手 | `MediaMetadata.METADATA_KEY_ARTIST` | | `title` | 歌曲名 | `MediaMetadata.METADATA_KEY_TITLE` | | `album` | 专辑 | `MediaMetadata.METADATA_KEY_ALBUM` | | `albumUrl` | 封面 | `MediaMetadata.METADATA_KEY_ALBUM_ART_URI` | | `songLen` | 总时长 | `MediaMetadata.METADATA_KEY_DURATION` | | `playPosition` | 当前进度 | `PlaybackStateCompat.getPosition()` | | `isPlaying` | 是否播放 | `PlaybackStateCompat.STATE_PLAYING` | ## Unknown 处理 在 `BtMusicManager.onMetadataChanged()` 中: ```text 如果 artist/title/album 为空、unknow、Not Provided ↓ 替换为 strings.xml 中的 unknow 文案 ``` 在 `BluetoothMusicActivity` 中: ```text 如果 title 为空或等于 unknow ↓ setIsOpenApp(true) ``` 含义: ```text A2DP 可能已经连接,但手机音乐 App 没有提供有效歌曲信息。 页面可能提示用户打开手机音乐 App。 ```