[Android] Fix background audio stopping after notification

Duncan McNamara git at videolan.org
Wed Jul 9 09:56:11 UTC 2025


vlc-android | branch: master | Duncan McNamara <dcn.mcnamara at gmail.com> | Fri May 23 13:49:54 2025 +0200| [63495e43a1bf67c414ef93d4991c6cb311657382] | committer: Nicolas Pomepuy

Fix background audio stopping after notification

When playing a podcast in the background, receiving a notification will
trigger a pause of the playback, for the notification to pass, then will
resume playback and seek backwards so the user doesn't miss any audio.

In the delayedPodcastRunnable of VLCAudioFocusHelper, resumePlayback()
and service.seek(position, fromUser = true) are called in sequence.
Both trigger a showNotification, resumePlayback through the libvlc event
Playing, seek right in it's function.

Problem is, seek will trigger the showNotification before the event
Playing happens. showNotificationInternal of PlaybackService will call
stopForeground when called while playback is stopped. Then
showNotification called from playback resuming will try to
startForeground to ensure the service isn't killed by the system, which
is not allowed as startForeground can only be called with the app in the
foreground or through user inputs like the notification buttons,
see https://developer.android.com/develop/background-work/services/fgs/
restrictions-bg-start.

To avoid calling stopForeground, seek should not be called from
VLCAudioFocusHelper with the fromUser parameter true, though we do need
to updateState should still be called to update the auto ui.

Fixes #3218

> https://code.videolan.org/videolan/vlc-android/commit/63495e43a1bf67c414ef93d4991c6cb311657382
---

 application/vlc-android/src/org/videolan/vlc/PlaybackService.kt         | 2 +-
 .../vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
index daf8ea96ad..2ddde113c3 100644
--- a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
@@ -1805,7 +1805,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner, CoroutineSc
     fun seek(time: Long, length: Double = this.length.toDouble(), fromUser: Boolean = false, fast: Boolean = false) {
         if (length > 0.0) this.setTime(time, fast) else {
             setPosition((time.toFloat() / NO_LENGTH_PROGRESS_MAX.toFloat()))
-            if (fromUser) publishState(time)
+            publishState(time)
         }
         // Required to update timeline when paused
         if (fromUser && isPaused) showNotification()
diff --git a/application/vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt b/application/vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt
index 7b74d9e76c..260f77aca6 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt
@@ -174,7 +174,7 @@ class VLCAudioFocusHelper(private val service: PlaybackService) {
             private val delayedPodcastRunnable = Runnable {
                 val position = (service.getTime() - 5_000L).coerceAtLeast(0)
                 resumePlayback()
-                service.seek(position, fromUser = true)
+                service.seek(position)
                 service.playlistManager.player.updateProgress(position)
             }
 



More information about the Android mailing list