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, Yandex.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 ms.
Правилният избор на 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 трябва последователно да се изпълнят три стъпки: създаване на заявка, заявка за фокус преди възпроизвеждане и обработка на събитието в callback. Използването на 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()
}
}
}
В callback е важно да се разграничават 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също