Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaMetadataCompat METADATA_KEY_ART only sets image the first time

In my application, I'm making use of MediaSessionCompat to handle playing audio from my media player service. Particularly, I want to broadcast the current song's metadata to bluetooth devices (which works), and set the lock screen image to the current song's album art.

Similar to this question: Set lock screen background in Android (like Spotify do)

Each time the song changes, I first clear off the current MediaMetadataCompat and PlaybackStateCompat from the MediaSessionCompat like so:

mSession.setActive(false);
mSession.setMetadata(null);
mSession.setPlaybackState(null);

Then, I create new instances of those classes with their respective builders

MediaMetadataCompat metadata = new MediaMetadataCompat.Builder()
        .putString(MediaMetadataCompat.METADATA_KEY_TITLE,
                                songName)
        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST,
                                artistName)
        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM,
                                albumName)
        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, durationMs)
        .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, bitmap)
        .build();

PlaybackStateCompat state = new PlaybackStateCompat.Builder()
        .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PAUSE |
                                    PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
        .setState(PlaybackStateCompat.STATE_PLAYING, positionMs, 1.0f, SystemClock.elapsedRealtime())
        .build();

Then I set the new metadata on the MediaSessionCompat

mSession.setActive(true);
mSession.setMetadata(metadata);
mSession.setPlaybackState(state);

On my bluetooth device, the Metadata works fine, and changes each time the song changes. On my phone however, the lock screen album cover updates only the first time. I've confirmed that the bitmap I'm setting is the new one, but the image does not change.

I'm also creating a media style notification in the service to allow the user to control the music from a persistent notification and from their lock screen.

NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
style.setShowActionsInCompactView(0, 1, 2, 3, 4);

Intent intent = new Intent(this, DestinationActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .setStyle(style)
            .setContentTitle(songName)
            .setContentText(artistName)
            .setLargeIcon(bitmap);

// Code to set notification actions 

startForeground(NOTIFICATION_ID_PLAYER_CONTROLS, builder.build());

However, the setLargeIcon method for my media notification does not have an effect on the album cover being displayed on the lock screen. This makes it show up in the notification itself, but not as the lock screen background.

like image 325
Andrew Brooke Avatar asked Feb 19 '17 22:02

Andrew Brooke


1 Answers

What you need is a MediaStyle notification

MediaControllerCompat controller = mediaSession.getController();
MediaMetadataCompat mediaMetadata = controller.getMetadata();
MediaDescriptionCompat description = mediaMetadata.getDescription();

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);

builder.setContentTitle(description.getTitle())
   .setContentText(description.getSubtitle())
   .setSubText(description.getDescription())
   .setLargeIcon(description.getIconBitmap())
   .setContentIntent(controller.getSessionActivity())
   .setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(context,PlaybackStateCompat.ACTION_STOP))
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);

The VISIBILITY_PUBLIC value will let the information you set here be visible on your lock screen

For more info see this gist by @ianhanniballake https://gist.github.com/ianhanniballake/47617ec3488e0257325c

like image 135
pantos27 Avatar answered Sep 17 '22 19:09

pantos27