Files
Obsidian/项目文档/同力/蓝牙音乐/05_Launcher卡片流程.md
T
2026-11-05 14:35:04 +08:00

137 lines
2.9 KiB
Markdown

# 05_Launcher卡片流程
## Launcher 卡片做什么
Launcher 蓝牙音乐卡片负责:
```text
1. 显示蓝牙音乐标题
2. 显示歌手
3. 显示封面
4. 显示播放状态
5. 显示当前进度和总时长
6. 提供上一曲、播放/暂停、下一曲按钮
```
核心文件:
```text
F:\zdCode\tongli\YX_Launcher\src\main\java\com\yaxon\launcher\card\BluetoothMusicCardView.java
F:\zdCode\tongli\YX_Launcher\src\main\res\layout\card_bluetoothmusic.xml
```
## 卡片显示流程
```text
1. BluetoothAvrcpClient 收到歌曲信息或播放状态
↓
2. BtInfoPushManager.sendMusicInfoToLauncher()
或 sendMusicStateToLauncher()
↓
3. 组装 BtMusicInfo
↓
4. DataManager.putObject(BT_MUSIC_INFO, btInfo)
↓
5. 发送 ACTION_UPDATE_MUSIC_WIDGET 广播
↓
6. Launcher 的 Id3Info 读取 BT_MUSIC_INFO
↓
7. Id3Info 回调 BluetoothMusicCardView.onBtMusicInfo()
↓
8. BluetoothMusicCardView.bindInfo()
↓
9. 更新卡片 UI
```
## 卡片显示字段
| 卡片内容 | 数据字段 |
|---|---|
| 歌曲名 | `BtMusicInfo.mTitle` |
| 歌手 | `BtMusicInfo.mArtist` |
| 封面 | `BtMusicInfo.mAlbumUrl` |
| 播放状态 | `BtMusicInfo.mPlayState` |
| 当前进度 | `BtMusicInfo.mPlayPosition` |
| 总时长 | `BtMusicInfo.mSongLen` |
## 卡片进度条逻辑
```text
1. 收到 BtMusicInfo
↓
2. 保存 mLastPositionMs
↓
3. 保存 mLastDurationMs
↓
4. 保存 mLastUpdateUptimeMs
↓
5. 如果是播放中
↓
6. 每秒用本地时间估算进度
↓
7. updateProgress()
```
这意味着:
```text
Launcher 卡片不是每秒都等蓝牙栈回调,
而是在播放中自己按时间推进进度条。
```
## 卡片控制流程
```text
1. 用户点击 Launcher 卡片按钮
↓
2. BluetoothMusicCardView.onClick()
↓
3. notifyBtSourceActive()
↓
4. DataManager.putInt(SOURCE_ID, SOURCE_BT_MUSIC)
↓
5. sendBtControl(cmd)
↓
6. DataManager.putInt(MUSIC_BT_CONTROL_STATE, cmd)
↓
7. BtMusicAudioManager 的 ContentObserver 收到变化
↓
8. 如果蓝牙音乐没有焦点,先 requestAudioFocus()
↓
9. 根据 cmd 调用 BtMusicManager
↓
10. BtMusicManager 调用 BluetoothAvrcpClient
↓
11. 手机音乐 App 响应
↓
12. MUSIC_BT_CONTROL_STATE 重置为 -1
```
## 卡片按钮命令
| 卡片按钮 | 写入命令 |
|---|---|
| 上一曲 | `StateUtils.MUSIC_BT_CONTROL_PRE` |
| 下一曲 | `StateUtils.MUSIC_BT_CONTROL_NEXT` |
| 播放 | `StateUtils.MUSIC_BT_CONTROL_PLAY` |
| 暂停 | `StateUtils.MUSIC_BT_CONTROL_PAUSE` |
## 为什么要重置为 -1
```text
如果连续点击同一个按钮,比如连续点下一曲:
第一次写入 MUSIC_BT_CONTROL_NEXT
↓
ContentObserver 触发
↓
处理完成后写回 -1
↓
下一次再写 MUSIC_BT_CONTROL_NEXT
↓
值发生变化,ContentObserver 可以再次触发
```
如果不重置,同一个值可能不会再次触发观察。