Android MediaSessionCompat не отображает кнопки управления мультимедиа на KitKat
Я создаю музыкальный проигрыватель и в настоящее время пытаюсь внедрить средства управления мультимедиа Lockscreen и информацию о воспроизведении. Моя первая попытка была с RemoteControlClient, но этот метод устарел, и я столкнулся с ошибкой, которую не смог устранить. Поэтому я попытался переключиться на класс MediaSessionCompat, все работает, за исключением элементов управления мультимедиа.
ComponentName eventReceiver = new ComponentName(getPackageName(), RemoteMediaReceiver.class.getName());
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
mediaSession = new MediaSessionCompat(this, "TAG", eventReceiver, mediaPendingIntent);
mediaSession.setCallback(new MediaSessionCompat.Callback() {
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
Log.d("MediaSession", "onMediaButtonEvent");
return super.onMediaButtonEvent(mediaButtonEvent);
}
@Override
public void onPlay() {
Log.d("MediaSession", "onPlay");
super.onPlay();
}
@Override
public void onPause() {
Log.d("MediaSession", "onPause");
super.onPause();
}
@Override
public void onSkipToNext() {
Log.d("MediaSession", "onSkipToNext");
super.onSkipToNext();
}
@Override
public void onSkipToPrevious() {
Log.d("MediaSession", "onSkipToPrevious");
super.onSkipToPrevious();
}
@Override
public void onSeekTo(long pos) {
Log.d("MediaSession", String.format("onSeekTo %d", pos));
super.onSeekTo(pos);
}
@Override
public void onStop() {
Log.d("MediaSession", "onStop");
super.onStop();
}
});
mediaSession.setPlaybackState(playbackState(PlaybackStateCompat.STATE_STOPPED, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 0));
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
Вот как я настраиваю медиа-сессию, тогда у меня есть вспомогательные методы, которые обновляют его состояние и метаданные, например
public void start(){
mControl.setPlaying(true);
notify(State.PLAY);
if(!audioFocus) requestFocus();
//remoteCC.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING, mp.getCurrentPosition(), 1.0f);
mediaSession.setPlaybackState(playbackState(PlaybackStateCompat.STATE_PLAYING, mp.getCurrentPosition(), 1));
mediaSession.setActive(true);
mp.start();
}
public void pause(){
mControl.setPlaying(false);
notify(State.PAUSE);
//remoteCC.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
mediaSession.setPlaybackState(playbackState(PlaybackStateCompat.STATE_PAUSED, mp.getCurrentPosition(), 0));
mediaSession.setActive(true);
mp.pause();
}
public void mediaSessionNewSong(){
Song song = mControl.getSongSet().safeCurrent();
Bitmap bitmap = AlbumArtCache.instance().get(song.album_id);
if(bitmap == null) bitmap = AlbumArtCache.instance().get(-1);
MediaMetadataCompat.Builder metadata = new MediaMetadataCompat.Builder();
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.album);
metadata.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artist);
metadata.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, song.track);
metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.title);
metadata.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration);
metadata.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap.copy(bitmap.getConfig(), false));
mediaSession.setMetadata(metadata.build());
mediaSession.setActive(true);
}
Кикер в том, что я могу получить RemoteControlClient вручную с помощью getRemoteControlClient() и установить его флаги управления транспортом, чтобы кнопки отображались, но затем они не используют предоставленный класс обратного вызова, они используют eventReceiver, и я столкнулся с ошибкой, которая у меня была с моей оригинальной реализацией RemoteClientControl. Что я не вижу? Вся документация, которую я прочитал, и другие вопросы, которые я видел, предполагают, что это должно работать.
РЕДАКТИРОВАТЬ: Да, мои извинения, это большая база кода, поэтому я забыл все свои вспомогательные методы
public PlaybackStateCompat playbackState(int state, long position, float playbackSpeed){
return new PlaybackStateCompat.Builder()
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS | PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SEEK_TO)
.setState(state, position, playbackSpeed)
.build();
}
Я обновил свою библиотеку с 22.0.0 до 22.2.1, и теперь отображаются кнопки (прогресс:D), но кажется, что удаленный клиентский элемент управления использует eventReceiver вместо обратного вызова MediaSession, за исключением seekTo, который использует обратный вызов как ожидается.