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

Stopping the audio doesnt remove the notification #1082

Open
animesh-flashfeed opened this issue Jul 19, 2024 · 7 comments
Open

Stopping the audio doesnt remove the notification #1082

animesh-flashfeed opened this issue Jul 19, 2024 · 7 comments

Comments

@animesh-flashfeed
Copy link

Documented behaviour

stop() → Future
Stop playback and release resources.

I have used both for dismissing the notification
await audioHandler?.stop();
await BaseAudioHandler().stop();

Actual behaviour

The notification doesn't get dismissed

Minimal reproduction project

Official example: example_playlist.dart

Reproduction steps

  1. Click the stop button and it doesn't dismiss the notification

Output of flutter doctor

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.91.1)
[✓] Connected device (4 available)            
[✓] Network resources

• No issues found!```
### Devices exhibiting the bug
Pixel 6a, Android Version 14
@ryanheise
Copy link
Owner

I have used both for dismissing the notification
await audioHandler?.stop();
await BaseAudioHandler().stop();

Your code is not pertinent to the bug report because your bug report submits the "official example: example_playlist.dart" as the minimal reproduction project.

Note that there are several examples demonstrating different features of audio_service. If you want to see an example that demonstrates how to close the notification, see lib/main.dart.

@XuanTung4195
Copy link

Same and I've done some debugging.
It does not cancel the notification even though it did call NotificationManager.cancel();
Check the answer here
The legacyStopForeground() must be called before onDestroy() or else the notification cannot be removed by code.

@IliaKhuzhakhmetov
Copy link

Got the same issue

@KRTirtho
Copy link

Facing the same issue here. But, this only happens when androidStopForegroundOnPause: false and androidNotificationOngoing: false if both are true the service does stop as expected after removing the app from task manager

But, this results in an issue where user pauses for momentarily and the OS kills the whole app for memory which is not ideal. This is espeically bad in Chinese android skins. Those OEM skins are too much aggressive

One cheeky way to get around this is while keeping both androidNotificationOngoing: false, androidStopForegroundOnPause: false, is to exit(0) on the BaseAudioHandler's overriden onTaskRemoved method

class MyAudioService extends BaseAudioHandler {
  // ... other stuff
  @override
  Future<void> onTaskRemoved() async {
    await myAudioPlayer.stop();
    if(Platform.isAndroid) exit(0);
  }
 // ... other stuff
}

Caution

This can get the app rejected on AppStore. Usually, programmatic process termination is somehow against their policy.

@ryanheise
Copy link
Owner

This behaviour can be controlled through controlled state transitions although I will also investigate @XuanTung4195 's note above as this may help it to work more robustly.

@nateshmbhat
Copy link

facing the same issue. the behavior is inconsistent. sometimes the notification gets removed but sometimes it just stays.

@fuz12
Copy link

fuz12 commented Oct 24, 2024

I have the same problem. I wrote my own audio service on media3. The notification deletion works. It's all about the removeSession method, maybe it's worth going this way too. If necessary, I can send a code with how to use my service.

class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null

    // Create your Player and MediaSession in the onCreate lifecycle event
    override fun onCreate() {
        super.onCreate()
        val player = ExoPlayer.Builder(this).build()
        mediaSession = MediaSession.Builder(this, player).build()
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        Log.d("PlaybackService", "onTaskRemoved")
        var condition = mediaSession?.player?.playWhenReady;
        if (mediaSession != null) {
            removeSession(mediaSession!!)
        }
        if (condition == null || !condition) {
            stopSelf()
        }
    }

    override fun onUpdateNotification(session: MediaSession, startInForegroundRequired: Boolean) {
        Log.d("PlaybackService", "onUpdateNotification")

        super.onUpdateNotification(session, startInForegroundRequired)
    }

    // Remember to release the player and media session in onDestroy
    @OptIn(UnstableApi::class)
    override fun onDestroy() {
        mediaSession?.run {
            Log.d("PlaybackService", "onDestroy")
            player.release()
            stopForeground(STOP_FOREGROUND_REMOVE)
            pauseAllPlayersAndStopSelf()
            if (mediaSession != null) removeSession(mediaSession!!)
            release()
            mediaSession = null
        }
        super.onDestroy()
    }

    // This example always accepts the connection request
    override fun onGetSession(
        controllerInfo: MediaSession.ControllerInfo
    ): MediaSession? = mediaSession
}

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

7 participants