我在AppCompat支持库修订版22中使用MediaSessionCompat
。在Lollipop上我收到通知&锁屏的背景也是专辑封面。一切都很酷。
在Pre-Lollipop设备上,锁屏上的音乐控件根本没有显示。这很奇怪&我尝试了所有的东西,但它没有出现,甚至没有背景变化。
我希望有人能解决这个问题。
注意:RemoteControlClient
曾用于Lollipop&奇巧
/**
* Initializes the remote control client
*/
private void setupMediaSession() {
/* Activate Audio Manager */
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
ComponentName mRemoteControlResponder = new ComponentName(getPackageName(),
MediaButtonReceiver.class.getName());
final Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(mRemoteControlResponder);
mMediaSessionCompat = new MediaSessionCompat(getApplication(), "JairSession", mRemoteControlResponder, null);
mMediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
PlaybackStateCompat playbackStateCompat = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_SEEK_TO |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_STOP
)
.setState(
isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
getCurrentPosition(),
1.0f)
.build();
mMediaSessionCompat.setPlaybackState(playbackStateCompat);
mMediaSessionCompat.setCallback(mMediaSessionCallback);
mMediaSessionCompat.setSessionActivity(retrievePlaybackActions(5));
mMediaSessionCompat.setActive(true);
updateMediaSessionMetaData();
mTransportController = mMediaSessionCompat.getController().getTransportControls();
这里是updateMediaSessionMetaData()
:
/**
* Updates the lockscreen controls, if enabled.
*/
private void updateMediaSessionMetaData() {
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, getArtistName());
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, getAlbumName());
builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, getTrackName());
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, getDuration());
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, MusicUtils.getArtwork(this, getAlbumID(), true));
mMediaSessionCompat.setMetadata(builder.build());
}
媒体会话回调方法
private final MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() {
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
final String intentAction = mediaButtonEvent.getAction();
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) {
if (PrefUtils.isHeadsetPause(getBaseContext())) {
Log.d(LOG_TAG, "Headset disconnected");
pause();
}
} else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
final KeyEvent event = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null) return super.onMediaButtonEvent(mediaButtonEvent);
final int keycode = event.getKeyCode();
final int action = event.getAction();
final long eventTime = event.getEventTime();
if (event.getRepeatCount() == 0 && action == KeyEvent.ACTION_DOWN) {
switch (keycode) {
case KeyEvent.KEYCODE_HEADSETHOOK:
if (eventTime - mLastClickTime < DOUBLE_CLICK) {
playNext(mSongNumber);
mLastClickTime = 0;
} else {
if (isPlaying())
pause();
else resume();
mLastClickTime = eventTime;
}
break;
case KeyEvent.KEYCODE_MEDIA_STOP:
mTransportController.stop();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (isMediaPlayerActive()) {
if (isPlaying()) mTransportController.pause();
else mTransportController.play();
}
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
mTransportController.skipToNext();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
mTransportController.skipToPrevious();
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
mTransportController.pause();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
mTransportController.play();
break;
}
}
}
return super.onMediaButtonEvent(mediaButtonEvent);
}
@Override
public void onPlay() {
super.onPlay();
resume();
}
@Override
public void onPause() {
super.onPause();
pause();
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
playNext(mSongNumber);
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
playPrevious(mSongNumber);
}
@Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
seekTo(pos);
}
@Override
public void onStop() {
super.onStop();
pause();
commitMusicData();
updatePlayingUI(STOP_ACTION);
stopSelf();
}
};
媒体按钮接收器清单条目
<!-- Media button receiver -->
<receiver android:name=".receiver.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
我几周以来一直试图解决这个问题但没有成功,并迫切需要帮助。
编辑:MediaSessionCompat的教程或示例也没问题
答案 0 :(得分:10)
虽然API14-19设备上使用的MediaSession
,RemoteControlClient
并非严格要求,但确实需要audio focus,强烈建议所有媒体播放都是强烈推荐的。
添加以下行:
AudioManager audioManager = (AudioManager)
getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_GAIN) {
return; //Failed to gain audio focus
}
在播放任何媒体之前,应获得音频焦点并显示控件。
答案 1 :(得分:8)
最后,我想出了一个解决方案。感谢@ianhanniballake&amp; @user1549672
bobj.b3vl[i]
。也在官方Android文档上BroadcastReceiver
setupMediaSession()
Flags
MediaSessionCallbacks
上的MediaSession
,MediaPlayer#onPause()
&amp;最后当@user1549672 MediaPlayer#onStart()
MediaSession
对象
醇>
那就是全部,大部分材料(代码)都在上面提供。这个问题花了几个月才解决,最后还是完成了。
答案 2 :(得分:3)
最后我得到了你和我的问题的答案。问题是你需要在更新mediasession时指定动作(mMediaSessionCompat.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE)。所以你的代码现在看起来应该是
private void updateMediaSessionMetaData() {
int playState = mPlaying
? PlaybackStateCompat.STATE_PLAYING
: PlaybackStateCompat.STATE_PAUSED;
mMediaSessionCompat.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadata.METADATA_KEY_ARTIST, getArtist())
.putString(MediaMetadata.METADATA_KEY_ALBUM, getAlbum())
.putString(MediaMetadata.METADATA_KEY_TITLE, getSongTitle())
.putLong(MediaMetadata.METADATA_KEY_DURATION, duration())
.putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, mSongPosn)
.putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS, songs.size())
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, albumArt)
.build());
mMediaSessionCompat.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(playState, position(), 1.0f)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE| PlaybackStateCompat.ACTION_SKIP_TO_NEXT|PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS).build());
更新:为MediaCallback&amp;添加了代码。接收器
private final class MediaSessionCallback extends MediaSessionCompat.Callback {
@Override
public void onPlay() {
pausePlayer();
}
@Override
public void onPause() {
pausePlayer();
}
public void onSeekTo(long pos) {
seek(pos);
}
@Override
public void onSkipToNext() {
playNext();
}
@Override
public void onSkipToPrevious() {
playPrev();
}
}
接收者:
public class MusicIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
Intent intent1 = new Intent(MusicService.ACTION_PAUSE);
intent1.setClass(context,
com.xyz.service.MusicService.class);
// send an intent to our MusicService to telling it to pause the
// audio
context.startService(intent1);
} else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(
Intent.EXTRA_KEY_EVENT);
if (keyEvent.getAction() != KeyEvent.ACTION_DOWN)
return;
switch (keyEvent.getKeyCode()) {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
Intent intentToggle = new Intent(
MusicService.ACTION_TOGGLE_PLAYBACK);
intentToggle.setClass(context,
com.xyz.service.MusicService.class);
context.startService(intentToggle);
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
Intent intentPlay = new Intent(MusicService.ACTION_PLAY);
intentPlay.setClass(context,
com.xyz.service.MusicService.class);
context.startService(intentPlay);
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
Intent intentPause = new Intent(MusicService.ACTION_PAUSE);
intentPause.setClass(context,
com.xyz.service.MusicService.class);
context.startService(intentPause);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
Intent intentNext = new Intent(MusicService.ACTION_NEXT);
intentNext.setClass(context,
com.xyz.service.MusicService.class);
context.startService(intentNext);
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
Intent intentPrev = new Intent(MusicService.ACTION_PREV);
intentPrev.setClass(context,
com.xyz.service.MusicService.class);
context.startService(intentPrev);
break;
default:
break;
}
}
}
}