java - MediaPlayerService 销毁后传输控件不更新
问题描述
好的。我一直在努力解决这个问题。由于最新的 Wear OS 升级,播放/暂停传输控件显示在通知面板中,而不是在通知上显示媒体控件。我的媒体播放器服务工作正常,直到它被暂停一段时间并且android在它移动到后台时破坏它。如果用户从传输控件中选择播放按钮,则音乐开始播放,但传输控件不再更新,这意味着用户只能点击播放并且不能再暂停。如果他们需要停止音频并且不能,这可能会非常令人沮丧。
这是我初始化媒体会话的代码。这在 onCreate 中调用
private void initMediaSession() {
if (mediaSessionManager != null) return;
mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
//Create a new mediaSession
mediaSession = new MediaSessionCompat(getApplicationContext(), "com.turndapage.navmusic.mediaplayer");
//Get mediaSessions Transport Controls
mediaSession.getController().getTransportControls();
//Set Mediasession ready to receive media commands
mediaSession.setActive(true);
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
callback = new MediaSessionCompat.Callback() {
// Implement callbacks
@Override
public void onPlay() {
super.onPlay();
Cat.d("Playing from transport controls.");
// This is the event that is triggered from the transport controls
resumeMedia();
}
@Override
public void onPause() {
super.onPause();
Cat.d("Pausing from transport controls");
pauseMedia();
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
skipToNext();
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
skipToPrevious();
}
@Override
public void onStop() {
super.onStop();
stop();
}
@Override
public void onSeekTo(long position) {
super.onSeekTo(position);
mediaPlayer.seekTo((int)position);
}
@Override
public void onFastForward() {
super.onFastForward();
fastForward();
}
@Override
public void onRewind() {
super.onRewind();
rewind();
}
@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
int id = Integer.parseInt(mediaId.replace("song", ""));
int thisIndex = 0;
for(Song song : songLibrary.getSongs()) {
if(song.getID() == id) {
ArrayList<Song> songs = getCurrentList();
thisIndex = songs.indexOf(song);
break;
}
}
int[] ids = new int[getCurrentList().size()];
for(int i = 0; i < ids.length; i++) {
ids[i] = getCurrentList().get(i).getID();
}
startPlaying(ids, thisIndex);
}
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
KeyEvent event = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
Cat.e("onMediaButtonEvent called: " + event);
if (event.getAction() == KeyEvent.ACTION_UP) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_PAUSE:
pauseMedia();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
playMedia();
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
//skipToNext();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
//skipToPrevious();
break;
}
}
return super.onMediaButtonEvent(mediaButtonEvent);
}
};
// Attach a callback to receive MediaSession update
mediaSession.setCallback(callback);
setSessionToken(mediaSession.getSessionToken());
}
当用户点击播放传输控件时调用此方法
public void resumeMedia() {
wasPlaying = true;
if(mediaPlayer != null) {
try {
if (!getPlaying()) {
mediaPlayer.seekTo(resumePosition);
mediaPlayer.start();
sendPlayPauseUpdate(true);
buildNotification(true);
}
ComplicationHelper.updatePlayPause(this, true);
} catch (IllegalStateException ex) {
ex.printStackTrace();
//restoreState();
startMediaPlayer();
}
}
}
发送播放/暂停更新只是向活动发送广播以更新那里的控件。
在通知代码中,我有这个来更新媒体会话的播放状态。如您所见,暂停或播放操作仅根据媒体播放器是否正在播放而添加。尽管如此,仍然显示播放动作:
long actions = MEDIA_SESSION_ACTIONS;
if(isPlaying)
actions |= PlaybackStateCompat.ACTION_PAUSE;
else
actions |= PlaybackStateCompat.ACTION_PLAY;
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setActions(actions)
.setState(isPlaying ? PlaybackStateCompat.STATE_PLAYING :
PlaybackStateCompat.STATE_PAUSED, resumePosition, 1)
.build());
以下是媒体会话操作:
// Media Session Actions
private static final long MEDIA_SESSION_ACTIONS =
PlaybackStateCompat.ACTION_SEEK_TO |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH |
PlaybackStateCompat.ACTION_PREPARE |
PlaybackStateCompat.ACTION_PREPARE_FROM_SEARCH |
PlaybackStateCompat.ACTION_PLAY_PAUSE |
PlaybackStateCompat.ACTION_STOP |
PlaybackStateCompat.ACTION_FAST_FORWARD |
PlaybackStateCompat.ACTION_REWIND;
我试过的:
- 将媒体会话更改为静态并返回
- 使回调成为一个变量,而不是在创建时创建一个新的。
- 手动将 mediasession 的播放状态设置为从传输控件播放后播放
尽管我正在使用挂起的意图来发送启动命令来运行恢复功能而不是传输控件,但这可以在手机应用程序上找到。如果我使用手机播放音频并且控件更新正确,即使手机应用程序使用完全相同的类,我也可以从手表的传输控件恢复播放。
请让我知道是否有任何其他信息可能会有所帮助。
谢谢!
-乔尔
解决方案
推荐阅读
- python - 删除重复数据并将其余数据附加到 pandas
- sql - 如何在 Postgresql 中更新后创建触发器
- flutter - 如何防止在颤振中重建
- jasmine - Jasmine 中执行 0 of 1(跳过 1)错误
- python - Jupyter notebook 导入错误:DLL 加载失败
- ios - '==' 如何与 UIViewControllers 一起工作?
- php - 在 PHP 中创建数组。确实需要解决底层问题
- laravel - 这些路由名称在 Laravel 中设置在哪里?
- ddev - ddev - brew - docker 的小问题
- sql-server - 动态查询“子句”参数不起作用