Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service doesn't get stopped after setting idle state with androidStopForegroundOnPause disabled #1083

Open
Zensonaton opened this issue Jul 29, 2024 · 7 comments

Comments

@Zensonaton
Copy link

Documented behaviour

AudioServiceConfig.androidStopForegroundOnPause: Whether the Android service should switch to a lower priority state when playback is paused allowing the user to swipe away the notification. Note that while in this lower priority state, the operating system will also be able to kill your service at any time to reclaim resources.

BaseAudioHandler.stop: Stop playback and release resources. The default implementation (which may be overridden) updates playbackState by setting the processing state to AudioProcessingState.idle which disables the system notification.

Actual behaviour

Changing androidStopForegroundOnPause from true (default) to false no longer allows stopping foreground service (and notification) by setting AudioProcessingState.idle:

playbackState.add(
  PlaybackState(
    playing: false,
    processingState: AudioProcessingState.idle,
  )
);

Minimal reproduction project

Official example: main.dart

Reproduction steps

Proper behavior:

  1. Press "play".
  2. Press "stop".
  3. Notification gets destroyed, and Android task manager no longer shows app in its "task manager".

Wrong behavior.

  1. Change androidStopForegroundOnPause to false.
  2. Press "play".
  3. Press "stop".
  4. Notification does not get dismissed, and Android "task manager" shows that app is still running.

Output of flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.22.2, on Microsoft Windows [Version 10.0.22631.3958], locale ru-RU)
[✓] Windows Version (Installed version of Windows is version 10 or higher)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✗] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.8.3)
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.91.1)
[✓] Connected device (3 available)
[✓] Network resources

Devices exhibiting the bug

Google Pixel 8, Android 14 (AP2A.240705.005)

Context

I'm forced to use androidStopForegroundOnPause = false because my app can pause playback due to interruptions. After setting androidStopForegroundOnPause = true, my app can pause playback, but it gets ForegroundServiceStartNotAllowedException exception.

@ryanheise
Copy link
Owner

Changing androidStopForegroundOnPause from true (default) to false no longer allows stopping foreground service (and notification) by setting AudioProcessingState.idle:

That's the correct behaviour. If you want to instruct Android to call stopForeground on pause, you have to set this to true (the default).

@Zensonaton
Copy link
Author

Yeah, that makes sense, but the problem I'm facing - no way to get rid of that notification by setting the state to idle.
There is no method like "destroyNotification", and this is a problem for me.

@Zensonaton
Copy link
Author

So, I want to clarify a bit: I'm not asking "why doesn't service stop when player is paused", but rather "why doesn't service stop when player is in idle state".

After digging a bit, I found this issue: #996. This comment explains the exact same issue I have.
I'm strongly against ignoring battery optimizations, so I can't use this here.

@jagged91
Copy link

jagged91 commented Aug 27, 2024

I'm facing a similar issue @Zensonaton. I feel like as things currently stand, there are two options:

  1. Keep androidStopForegroundOnPause = true and risk the service being killed in the background (this seems to happen when receiving notifications or calls during playback - possibly the switch to the lower priority state makes it a good candidate to be killed by the OS)
  2. Set androidStopForegroundOnPause = false which seems to keep the service alive correctly but has the downside of the audio notification lingering after playback has finished. It does (obviously) get dismissed when you swipe the app away, but not ideal. I know exactly where in the app logic I'd want to dismiss the notification (i.e. when navigating away from my in-app audio player UI).

I also agree that the battery optimization option isn't great, but I also understand that we're kinda fighting against flaws in the OS at this point.

@rootd
Copy link

rootd commented Aug 30, 2024

Is it possible to integrate a "destroyNotification" function to manually dismiss the notification?

@nateshmbhat
Copy link

I'm using the default AudioServiceConfig but still the notification behavior is inconsistent after stopping the audio and calling the stop method of BaseAudioHandler. let's say 5 out of 10 times the notification gets dismissed while the rest of times it stays there.

AudioServiceConfig(
        androidNotificationChannelId: 'test Notifications',
        androidNotificationChannelName: 'test Notifications',
        androidShowNotificationBadge: false)

@Colton127
Copy link

I made a few modifications that I think better aligns with the current AudioProcessingState: https://github.com/Colton127/audio_service

AudioProcessingState.idle: Stop foreground service and remove notification.

AudioProcessingState.completed: Stop foreground service, but keep notification active, allowing users to restart playback at a later time through the notification.

On my branch, AudioProcessingState.idle always kills the notification on Android 14, but I don't think it's possible on Android 11.

I believe the lifecycle of the service should mirror that of Spotify and YouTube: The service remains active until the notification or app is swiped away by the user. Previously, this wasn't necessary, but now that we cannot momentarily pause and resume the service in the background, we need to keep it alive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants