Реагирование на изменения при выводе звука

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

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

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

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

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

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

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

Kotlin

setVolumeControlStream(AudioManager.STREAM_MUSIC)

Java

setVolumeControlStream(AudioManager.STREAM_MUSIC);

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

Программное управление громкостью потока

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

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

На некоторых устройствах, например Chromebook и автомобилях с Android Automotive OS, есть регуляторы громкости, но приложениям не разрешено использовать методы AudioManager, описанные выше, чтобы менять уровень аудиопотока. Такие устройства называются устройствами с фиксированной громкостью. Чтобы узнать, запущено ли приложение на устройстве с фиксированной громкостью, вызовите метод isVolumeFixed().

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

Игрок Метод
AudioTrack AudioTrack.setVolume()
MediaPlayer MediaPlayer.setVolume()
ExoPlayer Используйте SimpleExoPlayer.setVolume(), чтобы задать громкость базовой дорожки AudioTrack.
Веб Задайте свойство volume для HTMLMediaElement.

Не шумите

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

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

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

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

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

Регистрируйте приемник при начале воспроизведения и отменяйте регистрацию при остановке. Если вы разработаете приложение в соответствии с инструкциями в этом руководстве, эти вызовы должны появляться в обратных вызовах сеанса мультимедиа onPlay() и 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);
  }
}