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, который использует обратный вызов как ожидается.

0 ответов

Другие вопросы по тегам