Gérer les modifications de la sortie audio

Les utilisateurs s'attendent à pouvoir contrôler le volume d'une application audio. Le comportement standard permet, entre autres, d'utiliser les commandes de volume (boutons de l'appareil ou curseurs de l'interface utilisateur) et éviter de lancer soudainement une lecture à haute voix si un périphérique comme un casque est déconnecté en cours d'utilisation.

Utilisation des commandes de volume

Lorsqu'un utilisateur appuie sur une touche de volume dans un jeu ou une application musicale, le volume doit changer, même si le lecteur est mis en pause entre deux titres ou qu'il n'y a pas de musique pour l'emplacement actuel du jeu.

Android utilise des flux audio distincts pour la musique, les alarmes, les notifications, la sonnerie des appels entrants, les sons du système, le volume des appels et les tonalités DTMF. Les utilisateurs peuvent ainsi contrôler le volume de chaque diffusion de manière indépendante.

Par défaut, appuyer sur la commande de volume modifie le volume du flux audio actif. Si votre application ne diffuse actuellement rien, appuyez sur les touches de volume pour régler le volume de la musique (ou celui de la sonnerie avant Android 9).

À moins que votre application ne soit un réveil, vous devez lire du contenu audio avec l'utilisation AudioAttributes.USAGE_MEDIA.

Pour vous assurer que les commandes de volume ajustent le flux approprié, vous devez appeler setVolumeControlStream() en transmettant le type de flux correspondant à vos attributs, que vous pouvez récupérer à partir de AudioAttributes.getVolumeControlStream.

Kotlin

setVolumeControlStream(AudioManager.STREAM_MUSIC)

Java

setVolumeControlStream(AudioManager.STREAM_MUSIC);

Effectuez cet appel dans le cycle de vie de votre application, généralement à partir de la méthode onResume() de l'activité ou du fragment qui contrôle votre contenu multimédia. Cela permet de connecter les commandes de volume à STREAM_MUSIC chaque fois que l'activité ou le fragment cibles sont visibles.

Contrôler le volume du flux de manière programmatique

Dans de rares cas, il est possible de régler le volume d'un flux audio par programmation. (par exemple, lorsque votre application remplace une UI existante). Cette action n'est pas recommandée, car Android AudioManager mélange tous les flux audio du même type. Ces méthodes modifient le volume de chaque application qui utilise le flux. Évitez de les utiliser:

Travailler avec des appareils à volume fixe

Certains appareils (tels que les Chromebooks) disposent de commandes de volume, mais n'autorisent pas les applications à utiliser les méthodes AudioManager décrites ci-dessus pour modifier le niveau d'un flux audio. C'est ce qu'on appelle des appareils à volume fixe. Pour savoir si votre application s'exécute sur un appareil à volume fixe, appelez isVolumeFixed().

Une application audio doit permettre d'équilibrer son volume de sortie avec d'autres applications qui peuvent être lues sur le même flux. Sur les appareils à volume fixe, l'application doit connecter ses propres commandes de volume à la méthode setVolume() appropriée dans le tableau ci-dessous:

Joueur Méthode
Piste audio AudioTrack.setVolume()
MediaPlayer MediaPlayer.setVolume()
ExoPlayer Utilisez SimpleExoPlayer.setVolume() pour définir le volume de la piste audio sous-jacente.

Ne soyez pas bruyant

Les utilisateurs disposent d'un certain nombre d'alternatives pour profiter du contenu audio sur leurs appareils Android. La plupart des appareils sont dotés d'un haut-parleur intégré et de connecteurs pour casques filaires. Nombre d'entre eux disposent également d'une connectivité Bluetooth et sont compatibles avec l'audio A2DP.

Lorsqu'un casque est débranché ou qu'un appareil Bluetooth est déconnecté, le flux audio est automatiquement redirigé vers le haut-parleur intégré. Si vous écoutez de la musique à un volume élevé, cela peut être une surprise bruyante.

Dans ce cas, les utilisateurs s'attendent généralement à ce que les applications incluant un lecteur de musique avec des commandes de lecture à l'écran suspendent la lecture. Les autres applications, comme les jeux qui n'incluent pas de commandes, devraient continuer à jouer. L'utilisateur peut régler le volume à l'aide des commandes matérielles de l'appareil.

Lorsque la sortie audio revient au haut-parleur intégré, le système diffuse un intent ACTION_AUDIO_BECOMING_NOISY. Vous devez créer un BroadcastReceiver qui écoute cet intent chaque fois que vous lisez du contenu audio. Votre récepteur devrait se présenter comme suit:

Kotlin

private class BecomingNoisyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {
            // Pause the playback
        }
    }
}

Java

private class BecomingNoisyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
          // Pause the playback
      }
    }
}

Enregistrez le récepteur lorsque vous lancez la lecture, puis annulez l'enregistrement lorsque vous arrêtez l'enregistrement. Si vous concevez votre application comme nous le décrivons dans ce guide, ces appels doivent apparaître dans les rappels de session multimédia onPlay() et onStop().

Kotlin

private val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
private val myNoisyAudioStreamReceiver = BecomingNoisyReceiver()

private val callback = object : MediaSessionCompat.Callback() {

    override fun onPlay() {
        registerReceiver(myNoisyAudioStreamReceiver, intentFilter)
    }

    override fun onStop() {
        unregisterReceiver(myNoisyAudioStreamReceiver)
    }
}

Java

private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();

MediaSessionCompat.Callback callback = new
MediaSessionCompat.Callback() {
  @Override
  public void onPlay() {
    registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
  }

  @Override
  public void onStop() {
    unregisterReceiver(myNoisyAudioStreamReceiver);
  }
}