Обработка изменений в аудиовыходе

Пользователи ожидают, что смогут контролировать громкость аудиоприложения. Стандартное поведение включает в себя возможность использовать регуляторы громкости (кнопки или ручки на устройстве или ползунки в пользовательском интерфейсе), а также избегать внезапного громкого воспроизведения, если периферийное устройство, например наушники, отключено во время использования.

Использование регуляторов громкости

Когда пользователь нажимает клавишу регулировки громкости в игре или музыкальном приложении, громкость должна измениться, даже если проигрыватель находится на паузе между песнями или в текущей игровой локации нет музыки.

Android использует отдельные аудиопотоки для воспроизведения музыки, сигналов тревоги, уведомлений, звонка входящего вызова, системных звуков, громкости разговора и тонов DTMF. Это позволяет пользователям независимо контролировать громкость каждого потока.

По умолчанию нажатие регулятора громкости изменяет громкость активного аудиопотока. Если ваше приложение в данный момент ничего не воспроизводит, нажатие клавиш громкости регулирует громкость музыки (или громкость звонка до Android 9).

Если ваше приложение не является будильником, вам следует воспроизводить звук с использованием AudioAttributes.USAGE_MEDIA .

Чтобы гарантировать, что элементы управления громкостью настраивают правильный поток, вы должны вызвать setVolumeControlStream() , передав тип потока, соответствующий вашим атрибутам, которые вы можете получить из AudioAttributes.getVolumeControlStream .

Котлин

setVolumeControlStream(AudioManager.STREAM_MUSIC)

Ява

setVolumeControlStream(AudioManager.STREAM_MUSIC);

Сделайте этот вызов в жизненном цикле вашего приложения, обычно из метода onResume() действия или фрагмента, который управляет вашими медиафайлами. Это подключает элементы управления громкостью к STREAM_MUSIC всякий раз, когда целевое действие или фрагмент виден.

Программное управление объемом потока

В редких случаях можно установить громкость аудиопотока программно. Например, когда ваше приложение заменяет существующий пользовательский интерфейс. Это не рекомендуется, поскольку Android AudioManager смешивает все аудиопотоки одного типа вместе. Эти методы изменяют громкость каждого приложения, использующего поток. Избегайте их использования:

Работа с устройствами фиксированной громкости

Некоторые устройства (например, Chromebook) имеют регуляторы громкости, но не позволяют приложениям использовать описанные выше методы AudioManager для изменения уровня аудиопотока. Их называют устройствами фиксированного объема . Вы можете узнать, работает ли ваше приложение на устройстве с фиксированным объемом, вызвав isVolumeFixed() .

Аудиоприложение должно обеспечивать возможность балансировать громкость своего вывода с громкостью других приложений, которые могут воспроизводиться в том же потоке. На устройствах с фиксированной громкостью приложение должно подключить собственные регуляторы громкости к соответствующему методу setVolume() в таблице ниже:

Игрок Метод
АудиоТрек AudioTrack.setVolume()
Медиаплеер MediaPlayer.setVolume()
Экзоплеер Используйте SimpleExoPlayer.setVolume() , который устанавливает громкость базового AudioTrack.

Не шуми

У пользователей есть несколько альтернатив, когда дело доходит до прослушивания звука со своих устройств Android. Большинство устройств имеют встроенный динамик, разъемы для наушников для проводных гарнитур, а многие также имеют возможность подключения Bluetooth и поддержку звука A2DP.

Когда гарнитура отключена или устройство Bluetooth отключено, аудиопоток автоматически перенаправляется на встроенный динамик. Если вы слушаете музыку на большой громкости, это может стать шумным сюрпризом.

Пользователи обычно ожидают, что в этом случае приложения, включающие музыкальный проигрыватель с экранными элементами управления воспроизведением, приостановят воспроизведение. Другие приложения, например игры без элементов управления, должны продолжать работать. Пользователь может регулировать громкость с помощью аппаратных средств управления устройством.

Когда аудиовыход переключается обратно на встроенный динамик, система передает намерение ACTION_AUDIO_BECOMING_NOISY . Вам следует создать BroadcastReceiver , который прослушивает это намерение всякий раз, когда вы воспроизводите звук. Ваш приемник должен выглядеть так:

Котлин

private class BecomingNoisyReceiver : BroadcastReceiver() {

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

Ява

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
      }
    }
}

Зарегистрируйте ресивер при начале воспроизведения и отмените его регистрацию при остановке. Если вы разрабатываете свое приложение так, как мы описываем в этом руководстве, эти вызовы должны появиться в обратных вызовах медиа-сессии onPlay() и onStop() .

Котлин

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)
    }
}

Ява

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);
  }
}