Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Media session has "no title" on AOD (Always on display)

In my app I displayed a notification with a foreground service, which is in charge of playing music. The notification is handled by com.google.android.exoplayer2.ui.PlayerNotificationManager android.support.v4.media.session.MediaSessionCompat com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector

    mediaSession = MediaSessionCompat(this, "Player", null, null)
    mediaSession.isActive = true
    mediaSessionConnector = MediaSessionConnector(mediaSession)
    mediaSessionConnector.setPlayer(exoPlayer)
    playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
            this,
            "notification_channel_player",
            R.string.notification_channel_name_player,
            0,
            PLAYER_NOTIFICATION_ID,
            object : PlayerNotificationManager.MediaDescriptionAdapter {
                override fun createCurrentContentIntent(player: Player?): PendingIntent? {
                    // intent
                }

                override fun getCurrentLargeIcon(player: Player?, callback: PlayerNotificationManager.BitmapCallback?): Bitmap? {
                    // large icon
                }

                override fun getCurrentContentText(player: Player?): String? {
                    // artist
                }

                override fun getCurrentContentTitle(player: Player?): String {
                    // title
                }

            },
            object : NotificationListener {
                override fun onNotificationPosted(notificationId: Int, notification: Notification?, ongoing: Boolean) {
                    startForeground(notificationId, notification)
                }
            })

    playerNotificationManager.setSmallIcon(R.drawable.ic_notification)
    // has previous and next
    playerNotificationManager.setUseNavigationActions(true)
    playerNotificationManager.setUseNavigationActionsInCompactView(true)
    // no fast-forward and rewind
    playerNotificationManager.setFastForwardIncrementMs(0)
    playerNotificationManager.setRewindIncrementMs(0)
    // no stop
    playerNotificationManager.setUseStopAction(false)

    playerNotificationManager.setMediaSessionToken(mediaSession.sessionToken)
    playerNotificationManager.setPlayer(exoPlayer)

When the screen is on, there is no problem displaying the content title and text. But when I lock screen and in AOD mode, on my Pixel 3 I see a "No title" displayed. But if I use Apple Music, it displays the title and artists very well.

My app : enter image description here

Apple music: enter image description here

My question is, how can I configure this title and text based on my current implementation? Thanks.

like image 841
YunhaoLIU Avatar asked Dec 02 '19 18:12

YunhaoLIU


3 Answers

I just answer my own question because I have found and solved the problem.

I have only set the notification's media description adapter, but in fact, the media session needs to set metadata too. Since we are using mediaSessionConnector, it can be setup by passing a QueueNavigator to the mediaSessionConnector, so we can use the player instance and window index to build current media's metadata. e.x:

    val timelineQueueNavigator = object : TimelineQueueNavigator(mediaSession) {
        override fun getMediaDescription(player: Player?, windowIndex: Int): MediaDescriptionCompat {
            player?.let { safePlayer ->
                return MediaDescriptionCompat.Builder().apply {
                    setTitle("......")
                    setSubtitle("......")
                }.build()
            }
            return MediaDescriptionCompat.Builder().build()
        }
    }
    mediaSessionConnector.setQueueNavigator(timelineQueueNavigator)

Another point is, by default the mediaSessionConnector use MediaSessionConnector.DefaultMediaMetadataProvider. It doesn't setup METADATA_KEY_ARTIST which will be used in AOD mode as the artist. So I have created my own MediaMetadataProvider, adding METADATA_KEY_ARTIST.

if (description.subtitle != null) {
    val subTitle = description.subtitle.toString()
    builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, subTitle)
    builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, subTitle)
}
like image 133
YunhaoLIU Avatar answered Nov 10 '22 16:11

YunhaoLIU


Here I used METADATA_KEY_TITLE and METADATA_KEY_ARTIST for title and the description:

MediaMetaData data = PlayerManager.getInstance().getCurrentMediaMetaData();
                        Bitmap bitmap = ((BitmapDrawable) AppController.getInstance().getResources().getDrawable(R.drawable.app_logo)).getBitmap();
                        Bundle extras = new Bundle();
                        extras.putString(MediaMetadataCompat.METADATA_KEY_TITLE,data.getMediaTitle());
                        extras.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, data.getMediaAlbum());
                        return new MediaDescriptionCompat.Builder()
                                .setIconBitmap(bitmap)
                                .setExtras(extras)
                                .build();
like image 2
DeePanShu Avatar answered Nov 10 '22 17:11

DeePanShu


You may have to build the notification like this:

Notification.Builder(context, channel).setContentTitle("Title").setContentText("Description").build()

Please, add your code here. It will be easier to help.

EDIT:

You are not returning the title at the adapter:

 override fun getCurrentContentTitle(player: Player?): String = "Add the title here"
like image 1
Bruno Martins Avatar answered Nov 10 '22 18:11

Bruno Martins