Audio focus android studio

Управление аудио-фокусом

Важно знать как должны взаимодействовать несколько приложений, который потенциально могут проигрывать звук. Android использует аудио-фокус, чтобы только одно приложений, захватившее фокус, могло воспроизводить звук в текущий момент времени.

Прежде чем начать воспроизведение, ваше приложение должно запросить и получить аудио-фокус. Кроме того, приложение должно следить за потерей фокуса и правильным образом обрабатывать такие ситуации.

Запрос аудио-фокуса

Итак, приложение должно захватить аудио-фокус нужного аудио-потока перед началом воспроизведения любых звуков. Это можно сделать с помощью метода requestAudioFocus(), который возвращает AUDIOFOCUS_REQUEST_GRANTED в случае успеха.

Вам нужно указать, какой поток вы используете и ожидаете временный или постоянный фокус. Запросите временный фокус, если собираетесь воспроизводить короткие звуки (например инструкции по навигации). Запросите постоянный фокус, если планируете без остановки воспроизводить звук в обозримом будущем (например, проигрывать музыку в плеере).

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

Сразу после окончания воспроизведения вызовите метод abandonAudioFocus() для отказа от фокуса. Это уведомит систему о том, что аудио-фокус вам больше не нужен и отменит регистрацию AudioManager.OnAudioFocusChangeListener. В случае отказа от временного фокуса, любое прерванное приложение может продолжить воспроизведение.

Для запроса временного фокуса есть дополнительный параметр: хотите ли вы использовать “ducking”. “Правильные” приложения обычно немедленно заглушают воспроизведение при потере фокуса. При запросе временного фокуса можно использовать ducking. Вы сообщаете приложению, что оно может продолжить воспроизведение немного убавив громкость, пока фокус находится у вас.

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

Всякий раз, когда другое приложение запрашивает фокус как описано выше, оно выбирает между постоянным и временным (с поддержкой ducking или нет) фокусом, которые вы указали при регистрации.

Обработка потери аудио-фокуса

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

Метод обратного вызова onAudioFocusChange() вызывается при изменении слушателя, которого вы зарегистрировали при запросе фокуса и принимает в качестве параметра тип события. Возможные события являются близнецами для типов фокуса, которые мы уже рассмотрели – постоянная потеря, временная потеря и временная потеря с разрешенным ducking.

Вообще говоря, временная потеря фокуса должна приглушить звук в вашем приложении, но оставить остальное состояние прежним. Вы должны продолжать отслеживать изменения фокуса и быть готовы возобновить воспроизведение, как только фокус вернулся.

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

Читайте также:  Android recovery не устанавливает прошивку

В следующем примере показано, как приостановить воспроизведение при временной потере фокуса и заново его возобновить как только фокус вернулся. Если потеря является постоянной, отключить обработчики медиа-кнопок и остановить отслеживание фокуса:

Источник

Русские Блоги

Android аудио и видео гид — управление аудио фокусом

Два или более приложения Android могут одновременно воспроизводить звук в один и тот же выходной поток. Система все перемешивает. Хотя это технически впечатляет, пользователей это очень раздражает. Чтобы избежать одновременного воспроизведения всех музыкальных приложений, в Android введена концепция фокусировки звука. Только одно приложение может фокусировать звук одновременно.

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

Аудио ориентировано на сотрудничество. Приложениям рекомендуется следовать рекомендациям по аудиофокусу, но система не применяет эти правила. Если приложение хочет продолжить громкое воспроизведение после потери фокуса звука, ничто не может его остановить. Это плохой опыт, и пользователи, скорее всего, удалят приложения, у которых такой плохой опыт.

Хорошо работающее звуковое приложение должно управлять звуковым фокусом в соответствии со следующими общими рекомендациями:

  • Вызывается непосредственно перед началом игры requestAudioFocus() И убедитесь, что вызов возвращаетсяAUDIOFOCUS_REQUEST_GRANTED. Если вы разрабатываете свое приложение так, как мы описываем в этом руководстве, вам следует onPlay() Вызывается при обратном вызове requestAudioFocus() 。
  • Когда другое приложение получает фокус со звуком, остановите или приостановите воспроизведение или уменьшите громкость.
  • Когда воспроизведение остановится, перестаньте фокусироваться на звуке.

Обработка аудиофокуса различается в зависимости от версии Android:

  • Начиная с Android 2.2 (уровень API 8), приложения вызываютrequestAudioFocus()с участиемabandonAudioFocus()Для управления аудио фокусом. Приложение также должно зарегистрироватьAudioManager.OnAudioFocusChangeListenerЧтобы получать обратные вызовы и управлять собственным уровнем звука.
  • Для приложений с Android 5.0 (уровень API 21) или выше звуковые приложения должны использоватьAudioAttributesЧтобы описать тип звука, воспроизводимого вашим приложением. Например, приложение, которое воспроизводит голос, должно указыватьCONTENT_TYPE_SPEECH。
  • Приложения под управлением Android 8.0 (уровень API 26) или выше должны использовать requestAudioFocus() Метод, он принимаетAudioFocusRequestпараметр. AudioFocusRequest содержит информацию о звуковом контексте и функциональных возможностях приложения. Система использует эту информацию для автоматического управления получением и потерей фокуса звука.

Аудио фокус на Android 8.0 и выше

Начиная с Android 8.0 (уровень API 26), когда вы вызываете requestAudioFocus (), вы должны предоставить параметр AudioFocusRequest. Чтобы освободить аудиофокус, вызовите метод AbandonAudioFocusRequest (), который также принимает AudioFocusRequest в качестве параметра. При запросе и отказе от фокуса следует использовать один и тот же экземпляр AudioFocusRequest.

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

нужно FocusGain Поля; все остальные поля необязательны. Объясните основной метод:

Это поле требуется в каждом запросе. Его значение такое же, как durationHint, используемое в вызове requestaudiofococus () до android8.0: AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT , AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ,или AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 。

audioattributes описывает варианты использования системных приложений. Когда приложение получает или теряет фокус звука, система будет смотреть на них. Атрибуты заменяют концепцию типов потоков. В Android 8.0 (уровень API 26) и выше любая операция, кроме регулировки громкости, не поддерживает тип потока. Используйте те же атрибуты в запросе фокуса, что и в аудиоплеере (как показано в таблице ниже).

Используйте одинAudioAttributes.BuilderСначала укажите атрибуты, а затем используйте этот метод для назначения атрибутов запросу.

Если не указано, AudioAttributes по умолчанию AudioAttributes.USAGE_MEDIA 。

Когда другое приложение запрашивает использование AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK При выполнении обработки фокуса сфокусированное приложение обычно не получает обратный вызов onAudioFocusChange (), потому что система может выполнить эту операцию сама. Если вам нужно приостановить воспроизведение вместо уменьшения громкости, вызовите setWillPauseWhenDucked (true), создайте и установите OnAudioFocusChangeListener, как описано в разделе «Автоматическое приглушение» ниже.

Когда фокус заблокирован другим приложением, запрос аудиофокуса может завершиться ошибкой. Этот метод допускает отложенное усиление фокуса: возможность асинхронного получения фокуса, когда фокус доступен.

Обратите внимание, что усиление с задержкой фокуса допустимо только при указании AudioManager.OnAudioFocusChangeListener. Поскольку ваше приложение должно получить обратный вызов, чтобы знать, что фокус был разрешен для получения.

OnAudioFocusChangeListener требуется только тогда, когда в запросе указано willPauseWhenDucked (true) или setAcceptsDelayedFocusGain (true).

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

В следующем примере показано, как использовать AudioFocusRequest.Bulder для создания AudioFocusRequest и запроса и отказа от фокуса звука:

Читайте также:  Visual novel maker android

Автоматическое ныряние

В Android 8.0 (уровень API 26), когда другое приложение использует AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK При запросе фокуса система может снизить громкость и возобновить воспроизведение звука, не вызывая приложение onAudioFocusChange() Перезвонить.

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

Если вы хотите, чтобы ваше приложение приостанавливало работу, когда требуется уклонение, вместо уменьшения его объема, создайте OnAudioFocusChangeListener , Использовать onAudioFocusChange() Методы обратного вызова для достижения желаемого поведения паузы / возобновления. Вызовите setOnAudioFocusChangeListener (), чтобы зарегистрировать слушателя, и вызовите setWillPauseWhenDucked (true), чтобы система использовала ваш обратный вызов вместо выполнения автоматических операций приглушения.

Задержка в фокусе

Иногда система не может утвердить запрос аудиофокуса, потому что фокус «заблокирован» другим приложением, например, при совершении вызова. В этом примере requestAudioFocus() возвращение AUDIOFOCUS_REQUEST_FAILED . В этом случае ваше приложение не должно продолжать воспроизведение звука, потому что оно не сфокусировано.

Этот метод называется setAcceptsDelayedFocusGain (true), что позволяет приложению обрабатывать запросы фокуса асинхронно. После установки этого флага запрос, сделанный при заблокированном фокусе, вернет AUDIOFOCUS_REQUEST_DELAYED . Когда условие блокировки аудиофокуса больше не существует, например, когда вызов завершается, система предоставит ожидающий запрос фокуса и вызовет onAudioFocusChange (), чтобы уведомить приложение.

Чтобы обрабатывать задержанное усиление фокуса, вы должны создать OnAudioFocusChangeListener, который использует метод обратного вызова onAudioFocusChange () для достижения желаемого поведения и зарегистрировать слушателя, вызвав setOnAudioFocusChangeListener ().

До Android 8.0 аудио фокус

Когда вы вызываете requestAudioFocus (), вы должны указать подсказку продолжительности, которая может использоваться другим приложением, которое в данный момент сфокусировано и воспроизводит:

Если вы планируете воспроизводить звук в обозримом будущем (например, при воспроизведении музыки), запросите постоянный звуковой фокус (AUDIOFOCUS_GAIN), и вы хотите, чтобы предыдущий держатель звукового фокуса прекратил воспроизведение.

Читайте также:  Installing python on android

Запросите временный фокус (AUDIOFOCUS_GAIN_TRANSIENT), если вы хотите воспроизводить звук только в течение короткого времени и хотите, чтобы предыдущий владелец приостановил воспроизведение.

Запросите переходный фокус приглушения (AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK), чтобы указать, что вы хотите воспроизводить звук только в течение короткого периода времени, и если предыдущий владелец фокуса «пригнул» (опустил) свой аудиовыход, вы все равно можете продолжить воспроизведение. Оба аудиовыхода микшируются в аудиопоток. Ducking особенно подходит для приложений, которые периодически используют аудиопотоки, например, для звуковых дорожек.

Для метода requestAudioFocus () также требуется AudioManager.OnAudioFocusChangeListener. Этот слушатель должен быть создан в том же действии или службе, что и ваш медиа-сеанс. Он реализует обратный вызов onAudioFocusChange (), и ваше приложение получит этот обратный вызов, когда другие приложения получат или откажутся от аудио-фокуса.

Следующий фрагмент кода запрашивает постоянный фокус аудио на потоке STREAM_MUSIC и регистрирует OnAudioFocusChangeListener для обработки последующих изменений в фокусе звука. (ПодРеакция на изменение звукового фокусаЧасть обсуждает смену слушателей. )

Когда вы закончите играть, вызовите AbandonAudioFocus ().

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

Реакция на изменение звукового фокуса

Когда приложение получает звуковой фокус, оно должно иметь возможность освободить его, когда другое приложение запрашивает собственный звуковой фокус. Когда это происходит, ваше приложение получает вызов метода onAudioFocusChange () в AudioFocusChangeListener, который был указан при вызове requestAudioFocus ().

Параметр focusChange, переданный в onAudioFocusChange (), указывает на происходящее изменение. Он соответствует подсказке продолжительности, используемой приложением для получения фокуса. Ваше приложение должно ответить соответствующим образом.

Переходный не в фокусе

Если изменение фокуса временное (AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK или AUDIOFOCUS_LOSS_TRANSIENT), приложение должно уменьшить громкость (если вы не полагаетесь на автоматическое приглушение) или приостановить воспроизведение, но сохранить то же состояние другими способами.

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

Постоянная потеря внимания

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

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

Обработчик использует Runnable, как показано ниже.

Источник

Оцените статью