android 10 seek bar on notification
Asked Answered
L

4

5

does anyone know about the seekbar function on notifications in android 10?

I can't seem to get the position indicator to show the current position. the bar is just blank but I can seek the media clicking the bar in the notification.

I have the normal notification builder code and I have added this to make the seekbar clickable in the "MediaPlayer.Event.Playing" event of libvlc

MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder();


metadataBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getLength());

PlaybackStateCompat.Builder mStateBuilder = new PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_PLAYING,  1, 1.0f)
        .setBufferedPosition(mMediaPlayer.getLength())
        .setActions(
                PlaybackStateCompat.ACTION_PLAY |
                        PlaybackStateCompat.ACTION_PAUSE |
                        PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
                        PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
                        PlaybackStateCompat.ACTION_SEEK_TO |
                        PlaybackStateCompat.ACTION_PLAY_PAUSE);


mediaSession.setMetadata(metadataBuilder.build());
mediaSession.setPlaybackState(mStateBuilder.build());

the media playing is about half way but there is no indicator of its position.

notification

Leaves answered 29/12, 2019 at 5:4 Comment(2)
This only appears to happen to certain devices where on other devices the seek bar will display perfectly fine. Additionally on the same device other media players have perfectly fine displaying seek bars, such as Youtube, Youtube Red, Google Play Music, etc. I am not sure what is causing this as I am also affected on one device however on another device issue is not present.Arlinearlington
The problem is in the small notification icon. Look at the answer here: https://mcmap.net/q/2030349/-android-10-mediastyle-notification-seek-bar-is-blackPeppergrass
D
10

After searching for a long time, eventually I came up with the solution. Please take the below steps to have the SeekBar displayed in your notification in Android 10 or higher.

  • Step 1: Put the duration of your file in milliseconds as a Long value with the key MediaMetadataCompat.METADATA_KEY_DURATION in your MediaSession.setMetadata
mediaSession.setMetadata(MediaMetadataCompat.Builder()
    .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, resource)
    .putString(
        MediaMetadataCompat.METADATA_KEY_ARTIST,
        activeBookFile.title
    )
    .putString(
        MediaMetadataCompat.METADATA_KEY_ALBUM,
        AudioPlayerService.activeBook.title
    )
    .putString(
        MediaMetadataCompat.METADATA_KEY_TITLE,
        AudioPlayerService.activeBook.title
    )
    .putLong(
        MediaMetadataCompat.METADATA_KEY_DURATION,
        activeBookFile.duration
    )
    .build()
)
  • Step 2: Add ACTION_SEEK_TO to all your PlaybackStateCompat.setAction() methods
  • Step 3: Provide a valid currentPosition in millseconds and the current state of your playing item then pass them to PlaybackStateCompat.setState() method.
  • Step 4: Set the playBackState object to your mediaSession using setPlaybackState()
fun updateMediaPlaybackState(currentPos: Long) {
    mediaSession.setPlaybackState(
        PlaybackStateCompat.Builder()
            .setActions(
                PlaybackStateCompat.ACTION_PLAY
                        or PlaybackStateCompat.ACTION_PLAY_PAUSE
                        or PlaybackStateCompat.ACTION_PAUSE
                        or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
                        or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
                        or PlaybackStateCompat.ACTION_SEEK_TO
            )
            .setState(
                getPlaybackState(),
                currentPos,
                1f,
                SystemClock.elapsedRealtime()
            )
            .build()
    )
}
@PlaybackStateCompat.State
private fun getPlaybackState(): Int {
        return when (currentState) {
            is PlayerStoppedState -> PlaybackStateCompat.STATE_STOPPED
            is PlayerPausedState -> PlaybackStateCompat.STATE_PAUSED
            is PlayerResumingState -> PlaybackStateCompat.STATE_PLAYING
            is PlayerLoadingState, is PlayerBufferingState -> PlaybackStateCompat.STATE_BUFFERING
            is PlayerErrorState -> PlaybackStateCompat.STATE_ERROR
            else -> PlaybackStateCompat.STATE_NONE
        }
    }
  • Step 5: To support user touch on the SeekBar override onSeekTo(pos: Long) method in MediaSessionCompat.Callback()
class PlayerMediaSessionCallback(mediaPlayer: MediaPlayer?) : MediaSessionCompat.Callback() {

// other callback methods

    override fun onSeekTo(pos: Long) {
        mediaPlayer?.seekTo(pos)
    }
}
  • Note: Remember to call updateMediaPlaybackState() and showNotification() whenever a state change happened for your player(paly, pause, skipNext, skipPrevious, seek, etc.)
Duodecillion answered 10/9, 2021 at 22:7 Comment(1)
@JonathanF. You're welcome. So glad that it was helpful for you.Duodecillion
L
0

update: it does appear to be showing the position but it is hard to see when the color of the notification is dark. for some reason the seekbar is not inverting its color based on the notification color.

if anyone comes across this problem make the background of the notification white and look to see if it is tracking the position.

so now i need to figure out how to get the bar to display a light color on a dark background

notification

Leaves answered 30/12, 2019 at 2:42 Comment(0)
P
0

You need add small icon with white color. You shouldn't use icon with other colors.

NotificationCompat.Builder builder = new NotificationCompat.Builder(service,NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_white)
Puton answered 8/9, 2020 at 7:45 Comment(0)
B
0

You have to add the current position of the song like this .setState(if (isPlaying()) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED, getCurrentPosition().toLong(), 1f)

Example-

val stateBuilder = PlaybackStateCompat.Builder()
            .setActions(MEDIA_SESSION_ACTIONS)
            .setState(
                if (isPlaying()) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED,
                getCurrentPosition().toLong(), 1f
            )

        mediaSessionCompat.setPlaybackState(stateBuilder.build())

Note: Above codes are in Kotlin

Buford answered 18/11, 2020 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.