136 lines
2.9 KiB
Markdown
136 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 可以再次触发
|
||
|
|
```
|
||
|
|
|
||
|
|
如果不重置,同一个值可能不会再次触发观察。
|
||
|
|
|