Prevent MediaSessionService from posting notification immediately after setting mediaItem
I'm using MediaSessionService with a MediaController, and I've noticed that as soon as I call setMediaItem(), the service automatically posts a notification — even before playback starts.
However, in my use case, I want to delay the notification until the user explicitly starts playback. For example:
I call setMediaItem() just to prepare the UI — to show duration, title, and a play button.
Only when the user taps "Play" should playback begin and the notification be shown.
If the user closes the player before hitting Play, I don’t want the notification to appear at all.
Similarly, on Pause or Close, I may want to temporarily hide the notification.
Is there a recommended way to suppress or delay the notification from being posted automatically when a media item is set?
Would appreciate any guidance or recommended patterns to achieve this. Thanks! Cc @marcbaechinger
Thanks for your question.
The beta of the next release has a new setter on MediaSessionService that allows to configure whether or not to display a notification when the player is IDLE.
Once the player is prepared though, the default implementation is to show a notification or not as determined by MediaNotificationManager.shouldShowNotification which is basically to always show a notification when not IDLE. This default isn't easily configurable.
I'd see two approaches I'd consider depending of the actual use case you may have.
Low-level approach
As a rather low-level approach, you can override MediaSessionService.onUpdateNotification(). This decouples the notification from the state of the player as it is implemented by default in MediaNotificatiojnManager. You then basically need to do all the foreground service state handling and the posting of notifications yourself.
If the user closes the player before hitting Play.... Similarly, on Pause or Close...
For simpler cases this can be straight forward. If for instance, it is sufficient to only have a running service when the UI is in the foreground with a media controller binding to the service, then the service isn't required to be put in to the foreground at all. In such a case when the service never needs to be in the foreground, notifications can be posted kind of arbitrarily I think.
Player API approach
Another approach would be to stick with the default implementation and create a SimpleBasePlayer that is wrapping an actual ExoPlayer instance. This allows you to quickly change the state of the wrapping player to make the notification been show or not (basically alternating IDLE or the actual state of the wrapped ExoPlayer to switch the notification off/on).
These are two ideas that come to mind.
We're having some difficulties on our end with notifications due to media3 behaviors even in 1.8.0. We've tested all values of SHOW_NOTIFICATION_FOR_IDLE_PLAYER_* and yet we still see notifications when the app starts up, even when nothing is playing. Additionally, even after calling pauseAllPlayersAndStopSelf() in onTaskRemoved(), some devices still re-display the notification.
This behavior also does not seem consistent across different Android versions or devices.
We're still investigating and will try to isolate this down to a test case.
When I start the session demo app, then in the background the MediaLibraryService is started, the app calls a service method to get the root ID and the like.
This happens when the app starts and without any further user interaction a session is created with a player that is in STATE_IDLE.
In logcat I can see that the session, the player and the controller has been started. The player is kind of only instantiated. So the player is empty and in state is STATE_IDLE.
Logcat confirms that when I grep package:mine EventLogger | ExoPlayerImpl | MediaSessionImpl | MediaController:
2025-10-16 16:38:14.904 23423-23423 MediaController androidx.media3.demo.session I Init 1541423 [AndroidXMedia3/1.8.0] [tokay, Pixel 9, Google, 36]
2025-10-16 16:38:14.935 23423-23423 ExoPlayerImpl androidx.media3.demo.session I Init a824c13 [AndroidXMedia3/1.8.0] [tokay, Pixel 9, Google, 36]
2025-10-16 16:38:15.019 23423-23423 MediaSessionImpl androidx.media3.demo.session I Init 5345b9d [AndroidXMedia3/1.8.0] [tokay, Pixel 9, Google, 36]
2025-10-16 16:38:15.128 23423-23423 EventLogger androidx.media3.demo.session D audioSessionId [eventTime=0.18, mediaPos=0.00, window=0, 185]
2025-10-16 16:38:15.144 23423-23423 MediaController androidx.media3.demo.session I Init cd9bf58 [AndroidXMedia3/1.8.0] [tokay, Pixel 9, Google, 36]
When inspecting the platform session with adb shell dumpsys media_session I find the following output:
androidx.media3.session.id. androidx.media3.demo.session/androidx.media3.session.id./11 (userId=0)
ownerPid=23423, ownerUid=10302, userId=0
package=androidx.media3.demo.session
launchIntent=PendingIntent{cd4181a: PendingIntentRecord{3c25f4b androidx.media3.demo.session startActivity}}
mediaButtonReceiver=MBR {pi=null, componentName=ComponentInfo{androidx.media3.demo.session/androidx.media3.session.MediaButtonReceiver}, type=1, pkg=androidx.media3.demo.session}
active=true
flags=7
rating type=0
controllers: 2
state=PlaybackState {state=NONE(0), position=0, buffered position=0, speed=0.0, updated=275636468, actions=7339653, custom actions=[Action:mName='Zufallsmix deaktivieren, mIcon=2131231301, mExtras=Bundle[mParcelledData.dataSize=140]], active item id=0, error=null}
audioAttrs=AudioAttributes: usage=USAGE_MEDIA content=CONTENT_TYPE_UNKNOWN flags=0x800 tags= bundle=null
volumeType=LOCAL, controlType=ABSOLUTE, max=0, current=0, volumeControlId=null
metadata: null
queueTitle=null, size=0
The important pieces are state=NONE(0) and queueTitle=null, size=0 which tells that the player is still idle and that no items are in the playlist. Accordingly, I can't see a notification.
I have then commented out these two lines in the demo app to avoid that the player is prepared and playback starts when items are added to the player.
When I then navigate to for instance the Kai Engel playlist then I see that the items are displayed in the list view.
adb shell dumpsys media_session confirms that there are nine items in the playlist (queueTitle=null, size=9), the player is still not prepared (state=NONE(0)) and metadata is set (metadata: size=11, description=Irsen's Tale, Kai Engel, Irsen's Tale). In this state again, I don't have a notification posted.
androidx.media3.session.id. androidx.media3.demo.session/androidx.media3.session.id./12 (userId=0)
ownerPid=26354, ownerUid=10302, userId=0
package=androidx.media3.demo.session
launchIntent=PendingIntent{703f12a: PendingIntentRecord{a4ab1b androidx.media3.demo.session startActivity}}
mediaButtonReceiver=MBR {pi=null, componentName=ComponentInfo{androidx.media3.demo.session/androidx.media3.session.MediaButtonReceiver}, type=1, pkg=androidx.media3.demo.session}
active=true
flags=7
rating type=0
controllers: 2
state=PlaybackState {state=NONE(0), position=0, buffered position=0, speed=0.0, updated=276444692, actions=7339701, custom actions=[Action:mName='Zufallsmix deaktivieren, mIcon=2131231301, mExtras=Bundle[mParcelledData.dataSize=140]], active item id=2, error=null}
audioAttrs=AudioAttributes: usage=USAGE_MEDIA content=CONTENT_TYPE_UNKNOWN flags=0x800 tags= bundle=null
volumeType=LOCAL, controlType=ABSOLUTE, max=0, current=0, volumeControlId=null
metadata: size=11, description=Irsen's Tale, Kai Engel, Irsen's Tale
queueTitle=null, size=9
So without knowing how exactly the demo app is configured, I think it's possible to have the session created with a player created that has the playlist filled with items, but is not yet prepared. In this condition, no notification was posted yet, not for a foreground service notification, nor for the notification manager.
When I then press play, the notification appears.
--
Can you check these conditions are met in your case? If that doesn't work for you as expected, can you do the minimal thing your app is supposed to do to get it into the state of which you expect no notification, and then, if there is such a notification, can you do a adb shell dumpsys media_session and post the output here into this issue?
Please also add what mode you pass to MediaSessionService.setShowNotificationForIdlePlayer(@ShowNotificationForIdlePlayerMode int) when this happens.
Additionally, even after calling pauseAllPlayersAndStopSelf() in onTaskRemoved(), some devices still re-display the notification.
That's not related to the startup thingy and the mode. If this happens then I'd guess this is either a resumption notification, or if this is not enabled then the service crashed and has been restarted by the system because it wasn't correctly stopped and is on START_STICKY.
If you see this again, I think you'd need to grab a bug raport right after this happened. If you're unable to share bug reports publicly, please send them to [email protected] using a subject in the format "Issue #2585". Please also update this issue to indicate you’ve done this.
@marcbaechinger Hi, thank you for the update. After much investigation and testing across multiple devices, we were able to achieve the correct behavior with these changes:
- Default the player to STATE_IDLE instead of STATE_READY.
- setShowNotificationForIdlePlayer(SHOW_NOTIFICATION_FOR_IDLE_PLAYER_AFTER_STOP_OR_ERROR) in service onCreate (I think this is also the default, but we set it explicitly to make sure).
- Make sure all controllers are released when no longer needed.
- Make sure we're running the latest version of media3-session.
And work that we were already doing, but we were just missing the above for everything to work:
- Make sure onStartCommand returns START_NOT_STICKY (we were already doing this).
- Override onTaskRemoved to call pauseAllPlayersAndStopSelf():
Glad it's working!
onStartCommand
OOI: why do you need to override onStartCommand?
Glad it's working!
onStartCommand
OOI: why do you need to override
onStartCommand?
The default returns START_STICKY. We don't want the service to come back if it was terminated by the system, so we return START_NOT_STICKY instead.