如何修改自动生成的media3通知?

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

我使用 Media3 1.0.0-beta03 构建了一个网络广播播放器。我使用来自的示例代码 开发者页面

它自动生成了媒体通知,但我不知道如何为其添加标题和副标题。

这是我的媒体服务:

class PlaybackService : MediaSessionService(), MediaSession.Callback {

    private object LC {
        lateinit var exoPlayer: ExoPlayer
        lateinit var mediaSession: MediaSession
    }

    override fun onCreate() {
        super.onCreate()
        log("----------------------------- MediaSessionService, onCreate")

        LC.exoPlayer = ExoPlayer.Builder(this).build()
        LC.exoPlayer.addListener(ExoListener())
        LC.exoPlayer.setAudioAttributes(AudioAttributes.Builder().setContentType(AUDIO_CONTENT_TYPE_MUSIC).setUsage(USAGE_MEDIA).build(),true)

        LC.mediaSession = MediaSession.Builder(this, LC.exoPlayer).setCallback(this).build()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession = LC.mediaSession

    override fun onAddMediaItems(mediaSession: MediaSession, controller: MediaSession.ControllerInfo, mediaItems: MutableList<MediaItem>): ListenableFuture<MutableList<MediaItem>> {
        val updatedMediaItems = mediaItems.map { it.buildUpon().setUri(it.mediaId).build() }.toMutableList()
        return Futures.immediateFuture(updatedMediaItems)
    }

    override fun onDestroy() {
        log("----------------------------- MediaSessionService, onDestroy")
        LC.exoPlayer.stop()
        LC.exoPlayer.release()
        LC.mediaSession.release()
        super.onDestroy()
        exitProcess(0)
    }
}

我尝试了 onUpdateNotification

android kotlin exoplayer android-mediasession android-media3
5个回答
4
投票

更新:

还有另一种方法,我发现它可以更好地完成工作。

在MediaSessionService的onCreate()函数中,我们可以像这样设置一个MediaNotificationProvider。

private lateinit var nBuilder: NotificationCompat.Builder
override fun onCreate(){
    super.onCreate()
    // init notificationCompat.Builder before setting the MediaNotificationProvider
    this.setMediaNotificationProvider(object : MediaNotification.Provider{
            override fun createNotification(
                mediaSession: MediaSession,// this is the session we pass to style
                customLayout: ImmutableList<CommandButton>,
                actionFactory: MediaNotification.ActionFactory,
                onNotificationChangedCallback: MediaNotification.Provider.Callback
            ): MediaNotification {
              createNotification(mediaSession)
           // notification should be created before you return here
                return MediaNotification(NOTIFICATION_ID,nBuilder.build())
            }

            override fun handleCustomCommand(
                session: MediaSession,
                action: String,
                extras: Bundle
            ): Boolean { 
                TODO("Not yet implemented")
            }
        })
}

fun  createNotification(session: MediaSession) {
        val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(NotificationChannel(notification_id,"Channel", NotificationManager.IMPORTANCE_LOW))

        // NotificationCompat.Builder here.
        nBuilder = NotificationCompat.Builder(this,notification_id)
            // Text can be set here 
            // but I believe setting MediaMetaData to MediaSession would be enough.
            // I havent tested it deeply yet but did display artist from session
            .setSmallIcon(R.drawable.your_drawable)
            .setContentTitle("your Content title")
            .setContentText("your content text")
            // set session here
            .setStyle(MediaStyleNotificationHelper.MediaStyle(session))
            // we don build.
    }

最后,如果您想自己更新通知信息

您可以通过调用这样的函数来做到这一点..

private fun updateNotification(/*parameter*/){

        nBuilder.setContentTitle("text") 
        nBuilder.setContentText("subtext")
        nManager.notify(NOTIFICATION_ID,nBuilder.build())
}


3
投票

如果您担心只更新通知的标题和副标题,则覆盖自动通知可能不是一个好主意,因为您可以节省大量代码行。 您是否尝试过设置通知中显示的 mediaItem 的元数据?因为如果未提供元数据,Android 将获取文件的嵌入元数据并显示。您可以通过 -

设置元数据
fun getMetaDataFromMediaClass(media: MediaClass): MediaMetadata {
        return MediaMetadata.Builder()
            .setTitle(media.title)
            .setAlbumTitle(media.title)
            .setDisplayTitle(media.title)
            .setArtist(media.subtitle)
            .setAlbumArtist(media.subtitle)
            .setArtworkUri(media.imageURL.toUri())
            .build()
    }

fun performPlayMedia(media: MediaClass) {
        val metadata = getMetaDataFromMediaClass(media)
        val mediaItem = MediaItem.Builder()
            .setUri(media.dataURL)
            .setMediaId(media.mediaID)
            .setMediaMetadata(metadata)
            .build()

        player.apply {
            setMediaItem(mediaItem)
            prepare()
            play()
        }
    }

2
投票

是的,谢谢TG。卡赛

不需要通知管理器。

class PlaybackService : MediaSessionService(), MediaSession.Callback {

    private object LC {
        lateinit var exoPlayer: ExoPlayer
        lateinit var mediaSession: MediaSession
    }

    @SuppressLint("UnsafeOptInUsageError")
    override fun onCreate() {
        super.onCreate()
        log("----------------------------- MediaSessionService, onCreate")

        LC.exoPlayer = ExoPlayer.Builder(this).build()
        LC.exoPlayer.addListener(BackgroundService())
        LC.exoPlayer.setAudioAttributes(AudioAttributes.Builder().setContentType(AUDIO_CONTENT_TYPE_MUSIC).setUsage(USAGE_MEDIA).build(),true)

        LC.mediaSession = MediaSession.Builder(this, LC.exoPlayer).setCallback(this).build()

        setMediaNotificationProvider(object : MediaNotification.Provider{
            override fun createNotification(
                mediaSession: MediaSession,
                customLayout: ImmutableList<CommandButton>,
                actionFactory: MediaNotification.ActionFactory,
                onNotificationChangedCallback: MediaNotification.Provider.Callback
            ): MediaNotification {
                // This run every time when I press buttons on notification bar:
                return updateNotification(mediaSession)
            }

            override fun handleCustomCommand(session: MediaSession, action: String, extras: Bundle): Boolean { return false }
        })
    }

    @SuppressLint("UnsafeOptInUsageError")
    private fun updateNotification(session: MediaSession): MediaNotification {

        val notify = NotificationCompat.Builder(this,"Radio")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            // This is globally changed every time when
            // I add a new MediaItem from background service
            .setContentTitle(GL.MEDIA.radio)
            .setContentText(GL.MEDIA.artist)
            .setStyle(MediaStyleNotificationHelper.MediaStyle(session))
            .build()

        return MediaNotification(1, notify)
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession = LC.mediaSession

    override fun onAddMediaItems(mediaSession: MediaSession, controller: MediaSession.ControllerInfo, mediaItems: MutableList<MediaItem>): ListenableFuture<MutableList<MediaItem>> {
        val updatedMediaItems = mediaItems.map { it.buildUpon().setUri(it.mediaId).build() }.toMutableList()
        return Futures.immediateFuture(updatedMediaItems)
    }

    override fun onDestroy() {
        log("----------------------------- MediaSessionService, onDestroy")
        LC.exoPlayer.stop()
        LC.exoPlayer.release()
        LC.mediaSession.release()
        super.onDestroy()
    }
}

0
投票

事实证明,非常简单。

MediaService 类中有一个需要重写的方法,称为 onUpdateNotification()。它为我们提供了媒体会议。

所以我们可以覆盖它并创建我们自己的NotificationCompat


// Override this method in your service

 override fun onUpdateNotification(session: MediaSession) {
        createNotification(session) //calling method where we create notification
    }

在 createNotification() 方法中,我们创建通知并使用 MediaStyleHelper.MediaStyle() 设置其样式,并在那里设置会话参数 就像下面这样。

并一如既往地创建通知


fun  createNotification(session: MediaSession) {
        val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(NotificationChannel(notification_id,"Channel", NotificationManager.IMPORTANCE_LOW))

        // NotificationCompat here.
        val notificationCompat = NotificationCompat.Builder(this,notification_id)
            // Text can be set here 
            // but I believe setting MediaMetaData to MediaSession would be enough.
            // I havent tested it deeply yet but did display artist from session
            .setSmallIcon(R.drawable.your_drawable)
            .setContentTitle("your Content title")
            .setContentText("your content text")
            // set session here
            .setStyle(MediaStyleNotificationHelper.MediaStyle(session)) 
            .build()
        notificationManager.notify(1,notificationCompat)
    }

我希望这会有所帮助,而且还为时不晚。

编辑:

另一个更简洁的选择是仅使用所需的 MediaMetaData 创建 MediaItem 并将其添加到 ExoPlayer。如果来源是 Hls,请尝试不要向 MediaMetaData 添加标题。


0
投票

根据我的测试,与之前的 Android 版本相比,Android 13 中媒体样式通知提供的信息非常有限,并且发生了很大的变化。除了 METADATA_KEY_ART 之外,还显示 TITLE 或 DISPLAY_TITLE,而后者是首选。还显示了艺术家。另一方面,SUBTITLE 甚至 ALBUM 和 COMPOSER 都被忽略,同时浪费了大量的屏幕空间。这使得媒体风格通知实际上无法用于不流行(即非流行)音乐。并确保元数据分配给媒体会话,而不是通知本身。

© www.soinside.com 2019 - 2024. All rights reserved.