11

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.

Community
  • 1
  • 1
Andrew Brooke
  • 12,073
  • 8
  • 39
  • 55

2 Answers2

1

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

pantos27
  • 629
  • 4
  • 13
  • It seems that the `setVisibility` method just has to do with what information appears on a secure lockscreen. Adding this method to my Media notification did not change the behavior – Andrew Brooke Feb 20 '17 at 20:19
  • @AndrewBrooke You should create a **new** notification and post it every time the information changes, of course. – pantos27 Feb 20 '17 at 21:50
  • That's what I'm currently doing. The notification gets updated, but the image on the lock screen does not, other than the first time. – Andrew Brooke Feb 20 '17 at 23:47
  • @AndrewBrooke where do you get the bitmap variable in `.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, bitmap)` – pantos27 Feb 21 '17 at 13:40
  • I'll eventually be loading in a bitmap by URL using Picasso (and this has the same behavior), but I've also tried loading a drawable resource as a bitmap. Like I said, the bitmap is correct each time. – Andrew Brooke Feb 21 '17 at 13:55
  • @AndrewBrooke can you post the code for when you create the notification? note that there are a few keys in the MediaMetadata class like: `METADATA_KEY_ALBUM_ART, METADATA_KEY_ALBUM_ART_URI, METADATA_KEY_ART, METADATA_KEY_ART_URI` – pantos27 Feb 21 '17 at 14:42
  • Updated my question with that code. I did try `METADATA_KEY_ALBUM_ART`, but that actually didn't display the image at all, only `METADATA_KEY_ART` worked – Andrew Brooke Feb 21 '17 at 15:02
0

in your metadata you should add metadata.putLong(MediaMetadata.METADATA_KEY_DURATION, duration);. duration variable should be long and it should always get updated. That solved my problem.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 18 '23 at 13:36