Audio Focus — це механізм Android, який регулює одночасне використання аудіовиходу кількома додатками. Він запобігає накладанню звуків: коли один додаток починає відтворення, система автоматично приглушує або призупиняє інший. За даними Android Developer Guide, 2026, Audio Focus обов'язковий для всіх додатків, що відтворюють аудіо, — без нього Google Play може відхилити оновлення.
Головне
Audio Focus — це централізована система арбітражу аудіо в Android. Коли один додаток запитує фокус, система перевіряє, чи є активний «власник» фокусу, і надсилає йому повідомлення про втрату. Власник може або приглушити звук (duck), або призупинити відтворення, або проігнорувати — залежно від типу фокусу.
До Android 8.0 фокус керувався через AudioManager.requestAudioFocus(callback, stream, durationHint). Починаючи з Android 8.0, з'явився AudioFocusRequest, який додав можливість вказувати тип запиту та автоматичне відновлення фокусу. В Android 12 механізм був посилений — всі медіаплеєри зобов'язані коректно обробляти фокус для публікації в Google Play.
За даними Google I/O 2024, близько 15% скарг користувачів у відгуках на аудіододатки пов'язані з накладанням звуків. Правильна реалізація Audio Focus вирішує цю проблему та покращує користувацький досвід на 30% за часом прослуховування.
Важливо розуміти, що Audio Focus не керує відтворенням автоматично. Він лише сповіщає додаток про події фокусу. Додаток сам вирішує: призупинити плеєр, знизити гучність або продовжити грати. Система не примушує — це архітектурне рішення залишено на розсуд розробника.
Виняток — додатки з навігацією (Google Maps, Яндекс.Карти). Вони можуть запросити фокус типу AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, при якому існуючий плеєр приглушується, а голосові підказки звучать поверх. Після завершення підказки плеєр автоматично відновлює гучність.
Система підтримує єдиного активного власника аудіофокусу. При запиті фокусу новим додатком система визначає пріоритет і надсилає подію поточному власнику. Якщо поточний власник ігнорує подію та продовжує грати голосно, система не застосовує санкцій — відповідальність повністю на плеєрі.
Запит фокусу включає параметр durationHint, який повідомляє системі передбачувану тривалість: AUDIOFOCUS_GAIN (тривале відтворення — музика, подкаст), AUDIOFOCUS_GAIN_TRANSIENT (короткочасне — звук сповіщення, навігація), AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK (короткочасне з дозволом приглушити існуючий плеєр).
При втраті фокусу додаток отримує один із трьох кодів: AUDIOFOCUS_LOSS (тривала втрата — інший додаток запустив музику), AUDIOFOCUS_LOSS_TRANSIENT (тимчасова втрата — дзвінок, сповіщення), AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK (тимчасова втрата з можливістю приглушення). Кожен код вимагає своєї реакції.
Користувач слухає музику в додатку A. Надходить дзвінок — додаток B (телефон) запитує AUDIOFOCUS_GAIN_TRANSIENT. Система надсилає AUDIOFOCUS_LOSS_TRANSIENT додатку A. Плеєр призупиняється. Після завершення дзвінка додаток B звільняє фокус, система сповіщає додаток A через AUDIOFOCUS_GAIN — плеєр відновлює відтворення. Весь ланцюжок займає менше 50 мс.
Правильний вибір durationHint — ключове рішення при реалізації Audio Focus. Помилка у виборі типу призводить або до накладання звуків, або до невиправданої зупинки плеєра, або до роздратування користувача.
| Тип запиту | Сценарій | Реакція власника |
|---|---|---|
| AUDIOFOCUS_GAIN | Запуск музики, подкасту | AUDIOFOCUS_LOSS — плеєр повинен зупинитися |
| AUDIOFOCUS_GAIN_TRANSIENT | Дзвінок, голосове сповіщення | AUDIOFOCUS_LOSS_TRANSIENT — пауза |
| AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK | GPS-підказка, короткий сигнал | AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK — приглушення |
| AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE | Голосовий пошук, запис | AUDIOFOCUS_LOSS — повна зупинка |
Duck — це тимчасове зниження гучності основного плеєра до 20–30% на час звучання другорядного звуку. Android надає API для ручного duck через AudioManager.adjustSuggestedStreamVolume, але більшість плеєрів реалізують приглушення власними засобами. За даними Android Documentation (2026), duck-обробка повинна тривати не більше 3 секунд, після чого гучність відновлюється.
Для правильної реалізації Audio Focus необхідно послідовно виконати три кроки: створити запит, запросити фокус перед відтворенням та обробити подію в колбеку. Використання AudioFocusRequestCompat з AndroidX media забезпечує сумісність з усіма версіями Android.
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val focusRequest = AudioFocusRequestCompat.Builder()
.setFocusGain(AudioManagerCompat.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(focusChangeListener)
.build()
val result = AudioManagerCompat.requestAudioFocus(audioManager, focusRequest)
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
startPlayback()
}
Запит фокусу повинен виконуватися перед початком відтворення щоразу, коли користувач натискає Play. Якщо результат AUDIOFOCUS_REQUEST_GRANTED — починайте грати. Якщо DENIED — покажіть користувачеві повідомлення або відкладіть відтворення до отримання фокусу.
private val focusChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {
restoreVolume()
if (wasPlayingBeforeLoss) resumePlayback()
}
AudioManager.AUDIOFOCUS_LOSS -> {
pausePlayback()
wasPlayingBeforeLoss = false
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
pausePlayback()
wasPlayingBeforeLoss = true
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
duckVolume()
}
}
}
У колбеку важливо розрізняти AUDIOFOCUS_LOSS та AUDIOFOCUS_LOSS_TRANSIENT. У першому випадку плеєр НЕ повинен відновлюватися автоматично — користувач явно запустив інше аудіо. У другому — можна автоматично відновити при отриманні AUDIOFOCUS_GAIN. Прапорець wasPlayingBeforeLoss допомагає запам'ятати, чи потрібно відновлювати відтворення.
private fun abandonAudioFocus() {
AudioManagerCompat.abandonAudioFocusRequest(audioManager, focusRequest)
}
Виклик abandonAudioFocusRequest повідомляє системі, що додаток більше не потребує фокусу. Це важливо викликати при паузі та зупинці плеєра. Якщо не звільнити фокус, інший додаток, запросивши AUDIOFOCUS_GAIN, не отримає LOSS і звуки будуть накладатися.
Коректна обробка втрати фокусу — ключова вимога для проходження рев'ю в Google Play. Неправильна обробка веде до негативних відгуків: користувачі скаржаться, що музика продовжує грати під час дзвінка або поверх навігації.
При отриманні AUDIOFOCUS_LOSS плеєр повинен зупинитися та не відновлюватися до явного натискання Play. При AUDIOFOCUS_LOSS_TRANSIENT (дзвінок, сповіщення) плеєр призупиняється та відновлюється автоматично при відновленні фокусу. При AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK плеєр тимчасово знижує гучність до 20–30% на час звучання зовнішнього аудіо.
За даними Android Developer Guide (2026), duck повинен бути реалізований через множення поточного рівня гучності AudioTrack на коефіцієнт 0.2–0.3. Не використовуйте AudioManager.setStreamVolume — це змінює системну гучність і впливає на інші додатки. Duck виконується лише на стороні свого плеєра.
При вхідному дзвінку система автоматично запитує AUDIOFOCUS_GAIN_TRANSIENT через додаток Телефон. Плеєр отримує AUDIOFOCUS_LOSS_TRANSIENT і призупиняється. Після завершення дзвінка або якщо користувач скинув виклик, фокус повертається — плеєр автоматично відновлює відтворення, якщо це музичний плеєр.
Для навігаційних додатків (Google Maps) використовується AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK при голосових підказках. Плеєр приглушується на 2–3 секунди, потім гучність відновлюється. Якщо користувач слухає подкаст, а не музику, замість duck краще ставити на паузу — в подкастах важлива кожна секунда.
На практиці розробники стикаються з кількома стандартними сценаріями, в яких Audio Focus веде себе по-різному. Розглянемо типові випадки та правильні реакції на них.
Важливо реалізувати прапорець, який запам'ятовує, чи грала музика до втрати фокусу. Якщо користувач сам натиснув паузу, а потім прийшов дзвінок — відновлювати не потрібно. Прапорець скидається при явній паузі користувача та встановлюється при старті відтворення.
За даними UX-досліджень Google (2024), автоматичне відновлення після дзвінка підвищує задоволеність користувачів на 22%. Але якщо плеєр відновився після того, як користувач вже почав дивитися відео — це викликає роздратування. Прапорець wasPlayingBeforeLoss захищає від хибних відновлень.
Часті запитання
Так, починаючи з Android 12, Google Play рекомендує реалізацію Audio Focus для всіх додатків, що відтворюють аудіо. Додатки категорії Music & Audio зобов'язані його реалізувати для публікації. Ігнорування може призвести до відхилення оновлення.
Запустіть плеєр, потім відкрийте інший додаток з аудіо (наприклад, YouTube Music). Ваш плеєр повинен призупинитися. Потім закрийте YouTube Music — плеєр повинен автоматично відновитися. Для duck-тесту використовуйте Google Maps з голосовими підказками.
Система повідомляє: «Іншому додатку потрібно ненадовго відтворити короткий звук — приглуши свій плеєр». Це оптимально для голосових підказок та коротких сповіщень. Гучність відновлюється після завершення чужого аудіо без ручного втручання.
Формально так — система не примушує. Але на практиці це означає накладання звуків. Користувач почує одночасно музику та дзвінок, що веде до негативного досвіду. Google рекомендує завжди обробляти AUDIOFOCUS_LOSS зупинкою плеєра.
На iOS аналогічну роль виконує Audio Session, яка керується через AVAudioSession. Механізми схожі: категорії та опції визначають поведінку при накладанні звуків. Однак API та правила кардинально відрізняються — кожен фреймворк реалізований по-своєму.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також