android 如何保持我的前台服务通知(MediaStyle)像Google Play音乐?

t3irkdon  于 2023-03-11  发布在  Android
关注(0)|答案(2)|浏览(209)

所以,我有一个PlayerService,基本上是一个音频播放器。它是前台,使用MediaStyle,带有自定义动作(通知中的按钮),如Prev、Play/Pause、Next和Close。
问题是,当我启动一些其他的音频应用程序,如Google Play音乐,它的通知总是在我的上面!如果我启动2个其他的音频应用程序与我的,当我点击他们的通知播放图标,通知去顶部,并停留在那里。而我的总是从顶部第二位。这并不重要,如果我的应用程序正在播放与否。
尝试了所有版本的API,但是假设我主要在奥利奥之前的版本中使用它,所以我们可以忘记NotificationChannel的东西。
也试过使用MediaSession,并设置PRIORITY_MAX,但仍然没有运气。顺便说一句,AudioFocus和其他所有东西都运行良好。通知优先级是唯一的问题。
getNotification()方法:

return NotificationCompat.Builder( this, CHANNEL_ID )
            .setTicker(ticker)
            .setContentTitle(title)
            .setContentText(text)
            .setSmallIcon(icon)
            .setLargeIcon(icon)
            .setContentIntent(notificationPendingIntent)
            .addAction(prevAction)
            .addAction(playAction)
            .addAction(nextAction)
            .addAction(stopAction)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setStyle(androidx.media.app.NotificationCompat.MediaStyle()
                .setShowActionsInCompactView(0, 1, 2)
            )
            .setColor(color)
            .setWhen(System.currentTimeMillis())
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .build()

更新为:

notificationManager.notify( 1, getNotification() )

操作示例:

NotificationCompat.Action(
        R.drawable.play,
        "Play",
        PendingIntent.getBroadcast(
            this,
            REQUEST_CODE,
            playIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )
    )
xj3cbfub

xj3cbfub1#

所以,问题出在MediaSession API的某个地方。我试着在一些教程和谷歌文档的帮助下让它工作,但失败了。其中一些太难了,或者只是矫枉过正(比如Github上的UniversalMusicPlayer)。我不需要用Android Auto等实现所有这些东西。
最后,我找到了Exoplayer MediaSession扩展。这就是我如何做到这一点。
build.gradle:

implementation 'com.google.android.exoplayer:extension-mediasession:2.10.1'

清单:

<receiver android:name="androidx.media.session.MediaButtonReceiver">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON"/>
        </intent-filter>
    </receiver>

PlayerService.kt:

...
    private val player by lazy { ExoPlayerFactory.newSimpleInstance( this ) }
    private val mediaSession by lazy { MediaSessionCompat(this, TAG) }
    private val connector by lazy { MediaSessionConnector(mediaSession) }
    ...
    override fun onCreate() {
        super.onCreate()

        mediaSession.setFlags( MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS or MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS )
        connector.setPlayer(player)
    }
    ...
    private fun getNotification(): Notification {
        return NotificationCompat.Builder( this, CHANNEL_ID )
            ...
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setStyle(androidx.media.app.NotificationCompat.MediaStyle()
                .setMediaSession(mediaSession.sessionToken)
                .setShowActionsInCompactView(0, 1, 2)
            )
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .build()
    }

这里最重要的部分是连接器的东西。其他代码就像任何其他前台或音频服务。但MediaSessionConnector是一个东西在这里。只是几行,但处理所有的东西给你。你不必写一些其他的媒体***代码!除了MediaBrowser的东西,但它不是我的情况。

fzsnzjdm

fzsnzjdm2#

这只是因为你没有注册MediaSession。

mMediaSession = new MediaSessionCompat(mContext, TAG, mComponentName, null);

别忘了

mMediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
            .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
            .build());

相关问题