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 فوکوس را آزاد میکند، سیستم از طریق AUDIOFOCUS_GAIN به برنامه A اطلاع میدهد — پخشکننده پخش را از سر میگیرد. کل زنجیره کمتر از 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 — کاهش موقت صدای پخشکننده اصلی به ۲۰–۳۰٪ در مدت پخش صدای ثانویه است. Android API برای duck دستی از طریق AudioManager.adjustSuggestedStreamVolume فراهم میکند، اما اکثر پخشکنندهها کاهش صدا را با ابزارهای خود پیادهسازی میکنند. طبق Android Documentation (2026)، پردازش duck نباید بیش از ۳ ثانیه طول بکشد، پس از آن صدا بازیابی میشود.
برای پیادهسازی صحیح 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 پخشکننده به طور موقت صدا را به ۲۰–۳۰٪ در مدت پخش صدای خارجی کاهش میدهد.
طبق Android Developer Guide (2026)، duck باید از طریق ضرب سطح صدای فعلی AudioTrack در ضریب ۰٫۲–۰٫۳ پیادهسازی شود. از AudioManager.setStreamVolume استفاده نکنید — این صدای سیستم را تغییر میدهد و روی برنامههای دیگر تأثیر میگذارد. Duck فقط در سمت پخشکننده خود انجام میشود.
در تماس ورودی، سیستم به طور خودکار از طریق برنامه تلفن AUDIOFOCUS_GAIN_TRANSIENT درخواست میکند. پخشکننده AUDIOFOCUS_LOSS_TRANSIENT دریافت کرده و متوقف میشود. پس از پایان تماس یا اگر کاربر تماس را رد کرد، فوکوس بازمیگردد — پخشکننده به طور خودکار پخش را از سر میگیرد، اگر پخشکننده موسیقی باشد.
برای برنامههای ناوبری (Google Maps) هنگام راهنماییهای صوتی از AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK استفاده میشود. پخشکننده به مدت ۲–۳ ثانیه کم صدا میشود، سپس صدا بازیابی میشود. اگر کاربر به جای موسیقی به پادکست گوش میدهد، به جای duck بهتر است مکث کند — در پادکستها هر ثانیه مهم است.
در عمل، توسعهدهندگان با چند سناریوی استاندارد مواجه میشوند که در آنها Audio Focus رفتار متفاوتی دارد. موارد معمول و واکنشهای صحیح به آنها را بررسی میکنیم.
پیادهسازی پرچمی که به یاد میآورد آیا موسیقی قبل از از دست دادن فوکوس در حال پخش بود مهم است. اگر کاربر خودش مکث کرده و سپس تماس وارد شده — از سرگیری لازم نیست. پرچم در مکث صریح کاربر بازنشانی و در شروع پخش تنظیم میشود.
طبق تحقیقات UX Google (2024)، از سرگیری خودکار پس از تماس رضایت کاربران را ۲۲٪ افزایش میدهد. اما اگر پخشکننده پس از اینکه کاربر ویدئو را شروع کرده از سر گرفته شود — این باعث ناراحتی میشود. پرچم 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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید