Audio Focus: същност на понятието, режими и управление в Android

Автор: IT Sectr Публикувано: 2026-05-23 Време за четене: 8 мин

Audio Focus — механизъм на Android, който регулира едновременното използване на аудиоизхода от няколко приложения. Той предотвратява наслагването на звуци: когато едно приложение започне възпроизвеждане, системата автоматично заглушава или спира другото. Според Android Developer Guide, 2026, Audio Focus е задължителен за всички приложения, възпроизвеждащи аудио — без него Google Play може да отхвърли актуализацията.

Основни моменти

  • Audio Focus — системен механизъм на Android за координиране на аудиовъзпроизвеждане между приложения без наслагване на звуци.
  • Заявката за фокус се изпълнява чрез AudioManager.requestAudioFocus() с посочване на тип и продължителност на възпроизвеждане.
  • Системата уведомява за промяна на фокуса чрез AudioManager.OnAudioFocusChangeListener с кодове AUDIOFOCUS_GAIN, LOSS и DUCK.
  • Auto Resume — при получаване на AUDIOFOCUS_LOSS приложението трябва да спре възпроизвеждането и да го възобнови при AUDIOFOCUS_GAIN.
  • Android 12+ изисква задължително използване на AudioFocusRequestCompat от AndroidX за създаване на заявка за фокус.

Какво е Audio Focus?

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 и възпроизвеждане на медия

Важно е да разберете, че Audio Focus не управлява възпроизвеждането автоматично. Той само уведомява приложението за събития на фокуса. Приложението само решава: да спре плейъра, да намали силата на звука или да продължи да възпроизвежда. Системата не принуждава — това е архитектурно решение, оставено на преценката на разработчика.

Изключение правят навигационните приложения (Google Maps, Yandex.Maps). Те могат да поискат фокус от тип AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, при който съществуващият плейър се заглушава, а гласовите указания звучат отгоре. След приключване на указанието плейърът автоматично възстановява силата на звука.

Как работи Audio Focus в Android

Системата поддържа един единствен активен собственик на аудиофокус. При заявка за фокус от ново приложение системата определя приоритет и изпраща събитие на текущия собственик. Ако текущият собственик игнорира събитието и продължава да възпроизвежда силно, системата не прилага санкции — отговорността е изцяло на плейъра.

Заявката за фокус включва параметъра durationHint, който информира системата за очакваната продължителност: AUDIOFOCUS_GAIN (дълго възпроизвеждане — музика, подкаст), AUDIOFOCUS_GAIN_TRANSIENT (кратко — звук на уведомление, навигация), AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK (кратко с разрешение за заглушаване на съществуващия плейър).

При загуба на фокус приложението получава един от три кода: AUDIOFOCUS_LOSS (дълготрайна загуба — друго приложение пусна музика), AUDIOFOCUS_LOSS_TRANSIENT (временна загуба — повикване, уведомление), AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK (временна загуба с възможност за заглушаване). Всеки код изисква своя реакция.

Верига от събития на Audio Focus

Потребителят слуша музика в приложение A. Идва повикване — приложение B (телефон) заявява AUDIOFOCUS_GAIN_TRANSIENT. Системата изпраща AUDIOFOCUS_LOSS_TRANSIENT на приложение A. Плейърът спира. След приключване на повикването приложение B освобождава фокуса, системата уведомява приложение A чрез AUDIOFOCUS_GAIN — плейърът възобновява възпроизвеждането. Цялата верига отнема по-малко от 50 ms.

Типове и режими на заявка за Audio Focus

Правилният избор на durationHint — ключово решение при имплементация на Audio Focus. Грешка в избора на тип води или до наслагване на звуци, или до неоправдано спиране на плейъра, или до раздразнение на потребителя.

Тип заявкаСценарийРеакция на собственика
AUDIOFOCUS_GAINСтартиране на музика, подкастAUDIOFOCUS_LOSS — плейърът трябва да спре
AUDIOFOCUS_GAIN_TRANSIENTПовикване, гласово уведомлениеAUDIOFOCUS_LOSS_TRANSIENT — пауза
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKGPS указание, кратък сигналAUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK — заглушаване
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVEГласово търсене, записAUDIOFOCUS_LOSS — пълно спиране

Особености на AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK

Duck — временно намаляване на силата на звука на основния плейър до 20–30% за времетраенето на второстепенния звук. Android предоставя API за ръчно duck чрез AudioManager.adjustSuggestedStreamVolume, но повечето плейъри имплементират заглушаване със собствени средства. Според Android Documentation (2026), обработката на duck трябва да продължава не повече от 3 секунди, след което силата на звука се възстановява.

Имплементация на Audio Focus в код

За правилна имплементация на Audio Focus трябва последователно да се изпълнят три стъпки: създаване на заявка, заявка за фокус преди възпроизвеждане и обработка на събитието в callback. Използването на AudioFocusRequestCompat от AndroidX media осигурява съвместимост с всички версии на Android.

Създаване и изпълнение на заявка за Audio Focus

kotlin
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 — покажете на потребителя съобщение или отложете възпроизвеждането до получаване на фокус.

Callback за обработка на промяна на фокус

kotlin
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()
        }
    }
}

В callback е важно да се разграничават AUDIOFOCUS_LOSS и AUDIOFOCUS_LOSS_TRANSIENT. В първия случай плейърът НЕ трябва да се възобновява автоматично — потребителят изрично е пуснал друг звук. Във втория — може автоматично да се възобнови при получаване на AUDIOFOCUS_GAIN. Флагът wasPlayingBeforeLoss помага да се запомни дали трябва да се възстанови възпроизвеждането.

Освобождаване на Audio Focus

kotlin
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 се държи различно. Нека разгледаме типичните случаи и правилните реакции на тях.

  • Музика + повикване — плейърът спира (AUDIOFOCUS_LOSS_TRANSIENT). След повикването автоматично се възобновява, ако потребителят не е извършвал действия в плейъра.
  • Музика + навигация — плейърът се заглушава за времето на гласовото указание (DUCK). Силата на звука се възстановява след приключване на фразата.
  • Потребителят пусна друго приложение — плейърът получава AUDIOFOCUS_LOSS и спира. Възобновяване само чрез бутона Play.
  • Видео + музика на заден план — видеоплейърът заявява AUDIOFOCUS_GAIN. Музикалният плейър получава LOSS и спира.
  • Гласово търсене (Google Assistant) — приложението получава AUDIOFOCUS_LOSS_TRANSIENT, спира и автоматично се възобновява след отговора на асистента.

Автоматично възобновяване след загуба на фокус

Важно е да се имплементира флаг, който помни дали музиката е свирила преди загубата на фокус. Ако потребителят сам е натиснал пауза, а после е дошло повикване — не трябва да се възобновява. Флагът се нулира при изрична пауза от потребителя и се задава при стартиране на възпроизвеждане.

Според UX проучвания на Google (2024), автоматичното възобновяване след повикване повишава удовлетвореността на потребителите с 22%. Но ако плейърът се възобнови, след като потребителят вече е започнал да гледа видео — това предизвиква раздразнение. Флагът wasPlayingBeforeLoss предпазва от фалшиви възобновявания.

Често задавани въпроси

Задължителен ли е Audio Focus за всички приложения с аудио?

Да, като се започне от Android 12, Google Play препоръчва имплементация на Audio Focus за всички приложения, възпроизвеждащи аудио. Приложенията от категория Music & Audio са задължени да го имплементират за публикуване. Игнорирането може да доведе до отхвърляне на актуализацията.

Как да проверя, че Audio Focus работи правилно?

Стартирайте плейъра, след това отворете друго приложение с аудио (например YouTube Music). Вашият плейър трябва да спре. След това затворете YouTube Music — плейърът трябва автоматично да се възобнови. За duck тест използвайте Google Maps с гласови указания.

Какво е AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK на практика?

Системата съобщава: „Друго приложение трябва за кратко да възпроизведе звук — заглуши своя плейър“. Това е оптимално за гласови указания и кратки уведомления. Силата на звука се възстановява след приключване на външния звук без ръчна намеса.

Може ли да се отхвърли заявка за загуба на Audio Focus?

Формално да — системата не принуждава. Но на практика това означава наслагване на звуци. Потребителят ще чуе едновременно музика и повикване, което води до негативно изживяване. Google препоръчва винаги да обработвате AUDIOFOCUS_LOSS чрез спиране на плейъра.

Работи ли Audio Focus на други платформи освен Android?

На iOS аналогична роля играе Audio Session, управлявана чрез AVAudioSession. Механизмите са подобни: категориите и опциите определят поведението при наслагване на звуци. Въпреки това API и правилата се различават коренно — всяка рамка е имплементирана по свой начин.

Обобщение

  • Audio Focus — системен арбитър на аудио в Android, който предотвратява наслагване на звуци от различни приложения.
  • Заявката за фокус се изпълнява чрез AudioFocusRequestCompat с посочване на durationHint: GAIN, TRANSIENT или TRANSIENT_MAY_DUCK.
  • Callback OnAudioFocusChangeListener обработва четири събития: GAIN, LOSS, LOSS_TRANSIENT и LOSS_TRANSIENT_CAN_DUCK.
  • При AUDIOFOCUS_LOSS плейърът спира, при TRANSIENT — спира с автоматично възобновяване, при DUCK — заглушава се.
  • Важно е да запомните флага wasPlayingBeforeLoss, за да не възобновявате възпроизвеждане след изрична пауза от потребителя.
  • Освобождаването на фокус чрез abandonAudioFocusRequest е задължително при пауза и спиране на плейъра.
  • На iOS аналогът на Audio Focus е Audio Session (AVAudioSession) със собствени категории и режими.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също