androidflutterdartjust-audio

Flutter: How to resume audio playing in other apps on android


Issue

I am using just_audio to play audio in my app, along with audio_session. When my app plays audio, I want audio of other apps to stop or duck, and resume/unduck when my apps stops audio.

Current code

This is how I have currently figured audio_session:

final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration(
    androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransientMayDuck,
    androidWillPauseWhenDucked: false,
));

This is how I play audio:

AudioPlayer activePlayer = AudioPlayer(handleInterruptions: true);
await activePlayer.setAndroidAudioAttributes(AndroidAudioAttributes(
      usage: AndroidAudioUsage.alarm,
      contentType: AndroidAudioContentType.music,
    ));
await activePlayer.setLoopMode(loopMode);
await activePlayer.setAudioSource(AudioSource.uri(Uri.parse(ringtoneUri)));
await activePlayer.setVolume(volume);

// Other apps audio should stop/duck here
activePlayer?.play();

...

// Other apps audio should resume/unduck here
await activePlayer?.stop();

Current Behavior

Other app's audio does get ducked (reduced in volume) on play() but it doesn't get unducked (back to normal volume) on stop(). Tried this with multiple other apps.

Edit: Seems like the other app gains focus when my app gets closed. So that means I need to call something other than stop() to release focus from my app?

What am I doing wrong here?

Device Info

I am currently testing on an Android 14 (Google APIs) emulator. But get same behavior on Android 13 devices. Haven't tested on older devices yet.


Solution

  • I don't know if its by design, a bug or due to something wrong I am doing, but just_audio never abandons audio focus automatically. You have to call it yourself through audio_session by calling session.setActive(false).

    AudioPlayer activePlayer = AudioPlayer(handleInterruptions: true);
    await activePlayer.setAndroidAudioAttributes(AndroidAudioAttributes(
          usage: AndroidAudioUsage.alarm,
          contentType: AndroidAudioContentType.music,
        ));
    await activePlayer.setLoopMode(loopMode);
    await activePlayer.setAudioSource(AudioSource.uri(Uri.parse(ringtoneUri)));
    await activePlayer.setVolume(volume);
    
    // Other apps audio should stop/duck here
    await activePlayer?.play();
    
    ...
    
    // Other apps audio should resume/unduck here
    await activePlayer?.stop();
    final session = await AudioSession.instance;
    await session.setActive(false); // <-- Need to call this after audio stops