Android5.0 提出了全新的MediaSession概念用于播放器与控制器之间进行交互,它取代之前的RemoteControlClient,并提供了更为灵活的客户端受控端模型。
但是MediaSession框架只能在安卓5系统上使用,如何兼容低版本呢? Google在support-v4(21以上版本)中也提供了MediaSessionCompact兼容包。通过它可以告诉Android系统与其他的应用,自己正在播放的内容是什么以及自己支持哪些类型的播放控制。
在播放音乐时,通过MediaSessionCompat可以实现锁屏按键上的监听,从而转换成自己的操作。
官方文档
https://developer.android.com/reference/android/support/v4/media/session/MediaSessionCompat.html
本文介绍的是基于MediaSessionCompat实现锁屏界面进行音乐播放控制功能
我们将MediaSessionCompat的初始化,控制,更新等操作都封装到MediaSessionManager中,方便与播放器交互控制。
详细步骤
1,初始化MediaSessionCompat实例
//音乐的控制逻辑都在MusicPlayService服务中,将service实例传递过来,与MediaSessionManager进行交互
public MediaSessionManager(MusicPlayService service) {
this.musicPlayService = service;
initSession();
}
public void initSession() {
try {
mMediaSession = new MediaSessionCompat(musicPlayService, MY_MEDIA_ROOT_ID);
//指明支持的按键信息类型
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
//监听的事件(播放,暂停,上一曲,下一曲)
stateBuilder = new PlaybackStateCompat.Builder()
.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS);
mMediaSession.setPlaybackState(stateBuilder.build());
//设置监听回调
mMediaSession.setCallback(sessionCb);
//必须设置为true,这样才能开始接收各种信息
mMediaSession.setActive(true);
} catch (Exception e) {
LogTool.ex(e);
}
}
2,初始化回调,用于监听锁屏界面上的按钮事件
private MediaSessionCompat.Callback sessionCb = new MediaSessionCompat.Callback() {
//锁屏播放点击事件
@Override
public void onPlay() {
super.onPlay();
//将事件传递给service处理
musicPlayService.handleStartPlay();
}
//锁屏暂停点击事件
@Override
public void onPause() {
super.onPause();
musicPlayService.handlePausePlay();
}
//锁屏下一曲点击事件
@Override
public void onSkipToNext() {
super.onSkipToNext();
musicPlayService.handleNextPlay();
}
//锁屏上一曲点击事件
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
musicPlayService.handlePrePlay();
}
};
3,播放歌曲时,需要更新屏幕上的歌曲信息
public void updateLocMsg() {
try {
//同步歌曲信息
MediaMetadataCompat.Builder md = new MediaMetadataCompat.Builder();
//歌曲名
md.putString(MediaMetadataCompat.METADATA_KEY_TITLE, MusicUtil.getInstance().getCurrPlayMusicInfo().getName());
//歌手名
md.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, MusicUtil.getInstance().getCurrPlayMusicInfo().getAuthor());
//专辑名
md.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, MusicUtil.getInstance().getCurrPlayMusicInfo().getAlbum());
//歌曲时长
md.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, MusicUtil.getInstance().getCurrPlayMusicInfo().getDuration());
mMediaSession.setMetadata(md.build());
} catch (Exception e) {
LogTool.ex(e);
}
}
4,点击控制按钮时,更新播放状态
public void updatePlaybackState(int currentState) {
int state = (currentState == MusicPlayService.PLAY_STATE_PAUSED) ? PlaybackStateCompat.STATE_PAUSED : PlaybackStateCompat.STATE_PLAYING;
//第三个参数必须为1,否则锁屏上面显示的时长会有问题
stateBuilder.setState(state, musicPlayService.mMediaPlyer.getCurrentPosition(), 1.0f);
mMediaSession.setPlaybackState(stateBuilder.build());
}
MediaSessionManager设置完毕,只需要在MusicPlayService的onCreate中初始化MediaSessionManager,
在播放\暂停音乐的时候调用updatePlaybackState更新状态,更新歌曲的时候调用updateLocMsg更新信息即可。
需要注意的是,锁屏上的信息需要在音乐播放时切换到锁屏界面才会显示,如果音乐暂停,切换到音乐播放界面是不会显示的。
最终效果如下图所示:
具体代码已经上传至:https://github.com/Clearlee/LockScreenMusicControl