Thanks @maxrave-dev for the audio-focus fix in core f293309 (1.5.0): that part of #2022 is now fixed. But I found another cause of music stopping, still present in 1.5.1 (Galaxy S23, Android 16, FOSS APK).
What I can observe (3 sessions tonight, same pattern each time): exactly 10 minutes after a track change, the foreground service flag is silently removed while music is still playing. About a minute later Android stops the service as idle, the app loses network, and playback starves at the next track. This leads to music stopping after 4-5 songs, as observed by @Lunar-Flame69 @MrDaraku @Allzweck @Prosto-Pasha @afabmoro97 @dafcavservicios @okcomputerfan.
20:54:54.261 D CrossfadeExoPlayerAdapter: End of stream reached <- track change, playing fine
21:04:54.330 D NotificationService: removeFlagFromNotificationLocked
pkg = com.maxrave.simpmusic notificationId = 200, flag = 64 <- +10:00.07: FGS dropped mid-track
21:05:42.245 W System.err: android_getaddrinfo failed: EAI_NODATA <- idle app loses network
21:05:54.325 W ActivityManager: Stopping service due to app idle:
u0a252 ... com.maxrave.simpmusic/...SimpleMediaService <- +1 min: service stopped
21:08:30.740 E ExoPlayerImplInternal: ... Failed to resolve stream URL <- next track starves
dumpsys activity services confirms it: isForeground=true at session start, silently false mid-playback, no pause anywhere in the log. The other two sessions show the same 10-minute delta (20:24:49 to 20:34:49, and one at 19:56:08).
My best guess at the mechanism: media3 1.9+ keeps the foreground service alive with a "user engaged" check plus a 10-minute grace timer. During a track swap, loadAndPlayTrackInternal swaps the ForwardingPlayer delegate and notifies MediaSession while the promoted precached player still has playWhenReady=false (play() comes a few lines later). That brief "not playing" sample could arm the timer, and the cancellation on re-engagement seems to never happen, maybe because media3's internal controller snapshot goes stale after the delegate swap. I'm not sure about the exact media3 internals here.
Possible fixes:
- In
loadAndPlayTrackInternal, call play() before swapDelegate() / notifyMediaItemChanged(), so MediaSession never observes playWhenReady=false during a swap (the crossfade path already does this).
- In
SimpleMediaService.onUpdateNotification, force startInForegroundRequired = true whenever session.player is actually playing, which should self-heal any wrong demotion within seconds.
Same symptom: #2222 (open), #2155, and older: #1995, #1983, #1965, #1948, #1894, #1847, #1818, #1386.
Thanks @maxrave-dev for the audio-focus fix in core
f293309(1.5.0): that part of #2022 is now fixed. But I found another cause of music stopping, still present in 1.5.1 (Galaxy S23, Android 16, FOSS APK).What I can observe (3 sessions tonight, same pattern each time): exactly 10 minutes after a track change, the foreground service flag is silently removed while music is still playing. About a minute later Android stops the service as idle, the app loses network, and playback starves at the next track. This leads to music stopping after 4-5 songs, as observed by @Lunar-Flame69 @MrDaraku @Allzweck @Prosto-Pasha @afabmoro97 @dafcavservicios @okcomputerfan.
dumpsys activity servicesconfirms it:isForeground=trueat session start, silentlyfalsemid-playback, no pause anywhere in the log. The other two sessions show the same 10-minute delta (20:24:49 to 20:34:49, and one at 19:56:08).My best guess at the mechanism: media3 1.9+ keeps the foreground service alive with a "user engaged" check plus a 10-minute grace timer. During a track swap,
loadAndPlayTrackInternalswaps the ForwardingPlayer delegate and notifies MediaSession while the promoted precached player still hasplayWhenReady=false(play()comes a few lines later). That brief "not playing" sample could arm the timer, and the cancellation on re-engagement seems to never happen, maybe because media3's internal controller snapshot goes stale after the delegate swap. I'm not sure about the exact media3 internals here.Possible fixes:
loadAndPlayTrackInternal, callplay()beforeswapDelegate()/notifyMediaItemChanged(), so MediaSession never observesplayWhenReady=falseduring a swap (the crossfade path already does this).SimpleMediaService.onUpdateNotification, forcestartInForegroundRequired = truewheneversession.playeris actually playing, which should self-heal any wrong demotion within seconds.Same symptom: #2222 (open), #2155, and older: #1995, #1983, #1965, #1948, #1894, #1847, #1818, #1386.