Как включить аудио фокус на телефоне

Как включить аудио фокус на телефоне

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

У класса достаточно большое количество констант и методов, но сам класс прост в использовании.

Пользователи могут слышать звук через встроенный динамик, разъём для проводной гарнитуры, Bluetooth (A2DP аудио). Вы можете через AudioManager определить, куда в настоящее время направляется аудиопоток и выполнить какое-нибудь действие, например, приглушить звук:

Система оповещает через широковещательное намерение ACTION_AUDIO_BECOMING_NOISY о смене источника звука. Зарегистрируйте BroadcastReceiver и прослушивайте нужное намерение.

В некоторых других примерах на сайте также используется AudioManager.

Управление громкостью и воспроизведением

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

Также вы можете управлять воспроизведением аудиопотока — пауза, стоп и т.д.

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

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

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

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

Кнопки контроля воспроизведения, такие как воспроизведение, "пауза", "стоп", "вперёд" и "назад" доступны на некоторых телефонах и многих проводных или беспроводных гарнитурах. Когда пользователь нажимает одну из этих аппаратных кнопок, система рассылает намерение с действием ACTION_MEDIA_BUTTON.

Чтобы обработать нажатие медиа-кнопки, вам необходимо зарегистрировать BroadcastReceiver в файле манифеста:

Реализация приёмника сама должна извлекать нажатую клавишу, переданную в оповещении. Объект Intent включает в себя ключ EXTRA_KEY_EVENT, класс KeyEvent включает в себя список статических констант KEYCODE_MEDIA_*, который содержит все возможные медиа-кнопки, такие как KEYCODE_MEDIA_PLAY_PAUSE и KEYCODE_MEDIA_NEXT.

Следующий фрагмент показывает, как получить нажатую медиа-кнопку и изменить воспроизведение медиа.

Так как несколько приложений могут обрабатывать нажатия медиа-кнопок, вы должны программно управлять тем, когда ваше приложение должно получать нажатия кнопок. Следующий код может использоваться в вашем приложении для регистрации и отмены регистрации вашего приемника событий от медиа-кнопок с помощью AudioManager.

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

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

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

Запрос аудиофокуса делается с помощью метода requestAudioFocus(), который возвращает AUDIOFOCUS_REQUEST_GRANTED, если запрос был успешным.

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

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

Читайте также:  Таймер с алиэкспресс инструкция

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

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

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

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

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

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

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

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

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

Управление микрофоном

Проверить, выключен ли микрофон, можно с помощью метода isMicrophoneMute():

Включить или выключить микрофон можно с помощью метод setMicrophoneMute():

Использование динамиков

Метод isSpeakerphoneOn() позволяет определить, играет ли музыка через динамики.

Переключиться на динамики или отключить их можно через метод setSpeakerphoneOn():

Дополнительное чтение

Режим «Без звука» — управление режимами Обычный, Без звука, Вибрация.

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

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

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

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

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

Читайте также:  Solidworks авторешение как включить

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

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 – воспроизведение будет коротким, но текущее воспроизведение может просто на это время убавить звук и продолжать играть

Итак, мы запрашиваем фокус и говорим, что это надолго — AUDIOFOCUS_GAIN. Метод requestAudioFocus возвращает статус:
AUDIOFOCUS_REQUEST_FAILED = 0 – фокус не получен
AUDIOFOCUS_REQUEST_GRANTED = 1 – фокус получен

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

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

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

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

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

Метод onAudioFocusChange получает на вход статус фокуса этого приложения. Тут 4 варианта:
AUDIOFOCUS_LOSS – фокус потерян в результате того, что другое приложение запросило фокус AUDIOFOCUS_GAIN. Т.е. нам дают понять, что другое приложение собирается воспроизводить что-то долгое и просит нас пока приостановить наше воспроизведение.
AUDIOFOCUS_LOSS_TRANSIENT — фокус потерян в результате того, что другое приложение запросило фокус AUDIOFOCUS_GAIN_TRANSIENT. Нам дают понять, что другое приложение собирается воспроизводить что-то небольшое и просит нас пока приостановить наше воспроизведение
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK — фокус потерян в результате того, что другое приложение запросило фокус AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. Нам дают понять, что другое приложение собирается воспроизводить что-то небольшое, и мы можем просто убавить звук, не приостанавливая воспроизведение
AUDIOFOCUS_GAIN – другое приложение закончило воспроизведение, звук снова наш

Читайте также:  Название группы в ватсапе прикольное для друзей

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

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

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

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

Sound request focus, result: 1

Music onAudioFocusChange: AUDIOFOCUS_LOSS

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

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

Sound: abandon focus

Music onAudioFocusChange: AUDIOFOCUS_GAIN

Срабатывает метод onCompletion, в котором взрыв отдает фокус (abandon focus). И, следовательно, музыка получает сообщение о том, что фокус снова ее (AUDIOFOCUS_GAIN).

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

Music: abandon focus

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

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

Кнопки Sound GT и Sound GTD срабатывают аналогично, я уже не буду их нажимать. Отличие будет в том, что взрыв будет запрашивать фокусы соответственно AUDIOFOCUS_GAIN_TRANSIENT и AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. А музыка будет получать статусы AUDIOFOCUS_LOSS_TRANSIENT и AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK.

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

Перепишем метод 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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Класс AudioManager имеет метод abandonAudioFocus() и другой метод requestAudioFocus() . Интересно, что такое аудиофокус? И что произойдет, если объект AudioManager получит AudioManager или потерял фокус звука?

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

Ссылка на основную публикацию
Как быстро выучить таблицу кубов и квадратов
Вдохновленный этой статьей, решил поделиться с вами способом быстрого возведения в квадрат. Возведение в квадрат более редкая операция, нежели умножение...
Зажигалка djeep как заправить
Как заправить зажигалку? Перед тем как заправить зажигалку повторно, нужно удобно расположиться вхорошо проветриваемом помещении. Наличие навыков поможет все сделать...
Изменить букву диска не активна
Откровенно говоря, толком не знаю, зачем может понадобиться изменить букву диска в Windows, кроме разве тех случаев, если какая-то программа...
Как в автокаде вписать текст в рамку
Преимущественное большинство пользователей во время работы над чертежами в программе AutoCAD сталкиваются с необходимостью добавления надписей с различным содержимым. Для...
Adblock detector