аудиофокус запрещен что это

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник

Аудиофокус — управление доступом к звуковой подсистеме

Это перевод статьи Respecting Audio Focus Kristan Uccello, Google Developer Relations

Считается грубым перебивать во время доклада, это показывает неуважение к докладчику и раздражает аудиторию. Если ваше приложение не учитывает правила работы с аудиофокусом, значит, оно не уважает остальные приложения и раздражает пользователя. Если Вы никогда не слышали об аудиофокусе, стоит обратить внимание на документацию Android developer training material.
Когда несколько приложений могут воспроизводить аудио важно думать о том, как они будут взаимодействовать. Чтобы избежать ситуации когда все плееры играют одновременно Андроид использует понятие аудиофокуса для контроля воспроизведения звуков: ваше приложение должно воспроизводить аудио только тогда, когда оно получило аудиофокус. В этой статье описаны несколько советов о том, как правильно и наилучшим для пользователя образом обрабатывать изменения состояния аудиофокуса.

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

Не надо быть жадным и запрашивать аудиофокус прямо в момент старта приложения; лучше подождать, пока приложение не начнет что-то делать с аудиопотоком. При получении аудиофокуса через сервис AudioManager, можно воспользоваться константами AUDIOFOCUS_GAIN* для обозначения необходимого режима фокуса.

В примере мы запрашиваем постоянный аудиофокус. Вместо этого, мы могли бы запросить временный (AUDIOFOCUS_GAIN_TRANSIENT) фокус, который подходит для воспроизведения звуков длительностью до 45 секунд.
Еще приложение может использовать режим “крякания” (AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) для ситуаций, когда допустимо совместное использование аудиоподсистемы вместе с другими приложениями (например, для фразы “жги еще” в фитнес-приложении, ожидая, что фоновая музыка не будет прерываться). Приложение, запрашивающее фокус в режиме “крякания”, не должно использовать аудиоподсистему дольше 15 секунд подряд.

Обрабатываем изменения состояния аудиофокуса

Для обработки событий изменения состояния аудиофокуса приложение должно создать экземпляр OnAudioFocusChangeListener. В этом обработчике необходимо обработать события AUDIOFOCUS_GAIN* и AUDIOFOCUS_LOSS*. Стоит заметить, что событие AUDIOFOCUS_GAIN имеет несколько особенностей, описанных во втором примере.

Константа AUDIOFOCUS_GAIN используется в коде в двух различных ролях. Во-первых, для получения аудиофокуса как в примере 1. При этом не происходит событие обработчика OnAudioFocusChangeListener, то есть при успешном запросе (и получении) аудиофокуса обработчик НЕ получит соответствующее событие AUDIOFOCUS_GAIN.
AUDIOFOCUS_GAIN также используется в реализации OnAudioFocusChangeListener как вариант события. Как указано ранее, событие AUDIOFOCUS_GAIN не возбуждается при запросе аудиофокуса. Напротив, оно может произойти только после возникновения соответствующего события AUDIOFOCUS_LOSS*. AUDIOFOCUS_GAIN — единственная константа, которая используется в обеих ситуациях.
Существуют четыре ситуации, которые необходимо учитывать в обработчике события изменения состояния аудиофокуса. Когда приложение получает событие AUDIOFOCUS_LOSS, это обычно означает, что обратно аудиофокус оно не получит. В этом случае приложение должно освободить ресурсы, связанные с аудиоподсистемой, и остановить воспроизведение. В качестве примера, представьте, что пользователь слушает музыку через ваше приложение, а затем запускает игру, которая забирает аудиофокус у аудиоплеера. Невозможно предсказать, через сколько времени пользователь закроет игру. Скорее всего, он перейдет на главный экран (оставив игру в фоне) и запустит еще одно приложение. Или он вернется в аудиоплеер, возобновив его работу, что потребует нового запроса аудиофокуса в onResume.
Однако есть другой случай, достойный обсуждения. Существует разница между потерей аудиофокуса навсегда (как в примере выше) или временно. Когда приложение получает событие AUDIOFOCUS_LOSS_TRANSIENT, ожидается, что приложение приостановит использование аудио до тех пор, пока оно не получит событие AUDIOFOCUS_GAIN. Когда возникает событие AUDIOFOCUS_LOSS_TRANSIENT приложение должно запомнить, что потеря фокуса временная, для того, чтобы при возврате фокуса разобраться, какое поведение корректно. (см. пример 2).
Иногда приложение теряет аудиофокус (т.е. получает AUDIOFOCUS_LOSS), а прервавшее приложение завершается, или каким-то другим образом теряет аудиофокус. В этой ситуации последнее приложение, которое имело аудиофокус, может получить событие AUDIOFOCUS_GAIN.
В последующем событии AUDIOFOCUS_GAIN приложение должно понять, получило ли оно аудиофокус после временной потери и должно просто возобновить проигрывание, либо восстановиться и настроить воспроизведение после полной потери фокуса.
Если приложение использует аудио только на короткое время (не более 45 секунд), оно должно запрашивать аудиофокус в режиме AUDIOFOCUS_GAIN_TRANSIENT и отпускать его сразу после завершения воспроизведения или записи звука. Аудиофокус в системе обрабатывается как стек: фокус получает то приложение, которое владело им последним.
Когда аудиофокус получен, самое время создать MediaPlayer или MediaRecorder и зарезервировать ресурсы. Также когда приложение получает AUDIOFOCUS_LOSS, хорошей практикой является освобождение всех зарезервированных ресурсов. Существует три варианта получения аудиофокуса, соответствующие разным вариантам потери фокуса. Неплохо бы явно обрабатывать все варианты потери фокуса в обработчике OnAudioFocusChangeListener.

Источник

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

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

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

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

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

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

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

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

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

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

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 и запроса и отказа от фокуса звука:

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

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

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

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

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

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

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

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

Запросите временный фокус (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, как показано ниже.

Источник

Полный список

— используем Audio Focus

Наверняка вы замечали, что при прослушивании музыки, если срабатывает уведомление, то на время звучания уведомления звук музыки или прерывается или становится тише. Это можно реализовать с помощью аудио-фокуса.

Попробую сначала объяснить схему движения фокуса на словах. Если рассматривать пример музыки и уведомления, то пусть музыку играет некое приложение_1, а уведомления выдает некое приложение_2. Приложение_1, когда начинает воспроизведение, запрашивает аудио-фокус, получает его и играет музыку. Далее приходит смс или письмо, и приложение_2 хочет воспроизвести звук уведомления. Оно также запрашивает аудио-фокус и получает его. Но при этом система видит, что фокус сейчас у приложения_1. Система сообщает приложению_1, что фокус оно пока что потеряло. Звук уведомления воспроизводится, приложение_2 отдает фокус, а приложению_1 сообщают, что фокус снова его. Когда приложение_1 заканчивает играть музыку, оно отдает фокус. Т.е. приложение должно не только запрашивать фокус при необходимости, но и явно отдавать его, когда он более не нужен. Для этого есть специальные методы, мы их рассмотрим дальше.

Тут еще важно понимать, что эти сообщения от системы к приложениям о том, что фокус потерян/восстановлен являются просто уведомительными. И разработчик приложения сам решает, как он будет это обрабатывать: проигнорит, убавит звук или приостановит воспроизведение. Например, я протестировал два плеера на своем планшете. На одном включил музыку и свернул его, музыка продолжала играть в фоне. В другом плеере я запустил просмотр фильма. В результате я слышал и фильм и музыку. Аудио-фокус позволяет избежать этого.

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

Напишем приложение, в котором реализуем пример с музыкой и звуком. При нажатии на одну кнопку будем запускать проигрывание музыки, а при нажатии на другую – воспроизводить короткий звук. И привяжем к этой схеме аудио-фокус.

Project name: P1281_AudioFocus
Build Target: Android 2.3.3
Application name: AudioFocus
Package name: ru.startandroid.develop.p1281audiofocus
Create Activity: MainActivity

Добавим строки в strings.xml:

Кнопка Music будет запускать музыку, а три другие кнопки – звук. Их три, потому что есть три разных типа фокуса, которые может запросить приложение. Мы протестируем все три.

В папку mnt/sdcard/Music/ поместите какой-нить файл с именем music.mp3. Например, его можно взять здесь. В папку res/raw поместите файл explosion.mp3, например отсюда.

В onCreate мы просто получаем AudioManager. Именно через него мы будем запрашивать фокус.

onClickMusic срабатывает при нажатии кнопки Music. Здесь мы создаем MediaPlayer и даем ему путь к файлу с музыкой. Методом setOnCompletionListener устанавливаем Activity, как получателя уведомления о окончании воспроизведения. Далее идет работа с фокусом. afListenerMusic – это слушатель (реализующий интерфейс OnAudioFocusChangeListener), который будет получать сообщения о потере/восстановлении фокуса. Он является экземпляром класса AFListener, который мы рассмотрим чуть дальше.

Фокус запрашивается с помощью метода requestAudioFocus. На вход необходимо передать:
— слушателя, который будет получать сообщения о фокусе
— тип потока
— тип фокуса

Тип фокуса говорит о том, насколько долго приложение собирается воспроизводить свой звук и насколько важно, чтобы другое приложение при этом замолчало. Всего есть три типа фокуса:
AUDIOFOCUS_GAIN – приложение дает понять, что оно собирается долго воспроизводить свой звук, и текущее воспроизведение должно приостановиться на это время
AUDIOFOCUS_GAIN_TRANSIENT – воспроизведение будет коротким, и текущее воспроизведение должно приостановиться на это время
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK – воспроизведение будет коротким, но текущее воспроизведение может просто на это время убавить звук и продолжать играть

После того, как получили фокус, стартуем воспроизведение.

Метод onClickSound срабатывает при нажатии на любую из трех кнопок Sound. Здесь мы определяем, какая из трех кнопок была нажата. Тем самым мы в переменную durationHint пишем тип аудио-фокуса, который будем запрашивать. Далее создаем MediaPlayer, который будет воспроизводить наш звук взрыва из папки raw. Присваиваем ему слушателя окончания воспроизведения. Запрашиваем фокус с типом, который определили выше. Стартуем воспроизведение.

Метод onCompletion, срабатывает по окончании воспроизведения. Мы определяем, какой именно MediaPlayer закончил играть и методом abandonAudioFocus сообщаем системе, что больше не претендуем на аудио-фокус. На вход методу передаем того же слушателя, который давали при запросе фокуса.

В onDestroy освобождаем ресурсы и отпускаем фокус.

Класс AFListener реализует интерфейс OnAudioFocusChangeListener и является получателем сообщений о потере/восстановлении фокуса. При создании мы даем ему соответствующий MediaPlayer (позже станет понятно зачем) и текст, который нам понадобится для логов.

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

Все сохраним и запустим приложение. Жмем Music, воспроизведение музыки началось. В логах видим.

Т.е. музыка запросила фокус и получила его (статус = 1).

Жмем Sound G, чтобы воспроизвести звук взрыва и запросить фокус AUDIOFOCUS_GAIN.

Sound request focus, result: 1

Music onAudioFocusChange: AUDIOFOCUS_LOSS

Фокус запрошен и получен взрывом. А музыка получила уведомление о том, что фокус она потеряла (AUDIOFOCUS_LOSS).

Слышим звук взрыва. После того как звук взрыва закончился:

Sound: abandon focus

Music onAudioFocusChange: AUDIOFOCUS_GAIN

Если дождаться, когда закончится музыка увидим такое сообщение.

Music: abandon focus

Музыка отдала фокус.

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

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

Перепишем метод onAudioFocusChange класса AFListener:

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

Я выбрал самые простые меры, чтобы не усложнять урок. Но их можно улучшить. Например, при потере фокуса надолго (AUDIOFOCUS_LOSS) можно освобождать ресурсы, и снова создавать MediaPlayer при получении фокуса. Либо можно вообще полностью отдать фокус (abandon), и тогда пользователю надо будет явно вернуться в ваше приложение, чтобы возобновить воспроизведение.

Когда вы запрашиваете фокус, метод requestFocus возвращает вам ответ, получилось захватить фокус или нет. Хелп рекомендует учитывать этот параметр и стартовать воспроизведение только при положительном результате (AUDIOFOCUS_REQUEST_GRANTED). Я, правда, не знаю как тут можно получить отрицательный результат. Если у кого есть соображения на этот счет – пишите на форуме.

На следующем уроке:

— пишем звук с помощью MediaRecorder

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *