Media3通知:如何在播放过程中动态更新标题

问题描述 投票:0回答:1

我需要根据当前播放位置修改媒体通知中显示的标题。根据文档,我可以使用

MediaNotification.Provider
但是文档也这么说

Note: Starting with API 33 the System UI notification is populated from the data in the session.
Accordingly, customizations of the MediaNotification.Provider have effect before API 33 only.

对于 33 及以上版本,我可以更新元数据,但无法再次在播放器上调用

setMediaItem
,因为这会干扰当前的播放会话(从头开始播放)。

问题1:使用media3默认通知,如何动态更新标题?

如果我唯一的选择是构建自定义通知,

问题2:如何禁用默认媒体样式通知? (目前我看到两个通知)

问题 3:如何创建自己的布局并显示/更新其数据?

服务是这样的:

class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null
    private lateinit var playerNotificationManager: PlayerNotificationManager
    private lateinit var notificationManager: NotificationManagerCompat

    override fun onCreate() {
        super.onCreate()
        val player = ExoPlayer.Builder(this)
            .setMediaSourceFactory(...)
            .build()
            .apply {
                addListener(object : Player.Listener {
                    ...
                })
                playWhenReady = true
            }

        mediaSession = MediaSession.Builder(this, player)
            .build()

        notificationManager = NotificationManagerCompat.from(this)
        createChannel()

        playerNotificationManager = PlayerNotificationManager.Builder(this, NOTIFICATION_ID, NOTIFICATION_CHANNEL)
            .setNotificationListener(object : PlayerNotificationManager.NotificationListener {
                override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
                    // Handle notification being dismissed by the user
                }

                override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) {
                    // Handle notification being posted
                    startForeground(notificationId, notification)
                }
            })
            .setMediaDescriptionAdapter(object : PlayerNotificationManager.MediaDescriptionAdapter {
                override fun getCurrentContentTitle(player: Player): CharSequence {
                    return "My Title"
                }

                override fun createCurrentContentIntent(player: Player): PendingIntent? {
                    return null
                }

                override fun getCurrentContentText(player: Player): CharSequence {
                    return "My Description"
                }

                override fun getCurrentLargeIcon(player: Player, callback: PlayerNotificationManager.BitmapCallback): Bitmap? {
                    return null
                }
            })
            .build()
        playerNotificationManager.setPlayer(player)
        ///playerNotificationManager.setMediaSessionToken(mediaSession.token) <-- not sure if session token needs to be set
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        mediaSession?.player?.stop()
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()
        super.onTaskRemoved(rootIntent)
    }

    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
        return mediaSession
    }

    @TargetApi(Build.VERSION_CODES.O)
    private fun createChannel() {
        val channel = NotificationChannel(
            NOTIFICATION_CHANNEL,
            this.getString(R.string.playback_notification_channel),
            NotificationManager.IMPORTANCE_LOW)
        channel.enableLights(false)
        channel.enableVibration(false)
        channel.setShowBadge(false)
        channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
        notificationManager.createNotificationChannel(channel)
    }

    companion object {
        private const val NOTIFICATION_CHANNEL = "player_channel"
        private const val NOTIFICATION_ID = 100
    }
}
android-mediaplayer exoplayer android-mediasession android-media3 exoplayer-media-item
1个回答
0
投票

我们不需要创建 PlayerNotificationManager,而是需要在 MediaNotification.Provider 中重写此方法

fun getNotificationContentText(MediaMetadata metadata): CharSequence

一旦创建了上面的对象,从MediaSessionService中,需要调用

setMediaNotificationProvider(provider)
© www.soinside.com 2019 - 2024. All rights reserved.