Search code examples
androidflutterjust-audio

How to setup audio session for alarm ringtones in flutter?


I am creating an alarm clock application, using just_audio to play the alarm ringtones and audio_session to configure the audio type. Without configuring the audio, the app uses the media volume for the audio. I want the app to tell the system that this is an alarm audio, so it uses the system alarm volume for the ringtones and play it even in DnD etc.

What I have tried

Here is the setup that I currently have:

// Configuring audio session using audio_session
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration(
  androidAudioAttributes: AndroidAudioAttributes(
    flags: AndroidAudioFlags.audibilityEnforced,
    usage: AndroidAudioUsage.alarm,
  ),
));

// Initializing and playing the audio using just_audio
player = AudioPlayer();
await player.setAudioSource(AudioSource.uri(ringtoneUri));
await player.setLoopMode(loopMode);
player.play();

On some devices that I have tested (Android 6 and 8), it uses the phone ringtone volume, while on others (Android 11), it correctly uses the alarm volume.

What is the correct method to do it, so it uses the alarm volume on all devices?


Solution

  • Turns out, it was the AndroidAudioFlags.audibilityEnforced flag, which seems to be pretty unrealiable, and can cause differing behavior on different devices. Removing it causes the volume to be controlled by alarm stream volume.

    Android Docs: FLAG_AUDIBILITY_ENFORCED

    Working code

    final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration(
      androidAudioAttributes: AndroidAudioAttributes(
        usage: AndroidAudioUsage.alarm,
      ),
    ));
    
    // Initializing and playing the audio using just_audio
    player = AudioPlayer();
    await player.setAudioSource(AudioSource.uri(ringtoneUri));
    await player.setLoopMode(loopMode);
    player.play();