تقویت صدای پس‌زمینه

از اندروید ۱۷ به بعد، چارچوب صوتی محدودیت‌هایی را بر تعاملات صوتی پس‌زمینه از جمله پخش صدا، درخواست‌های فوکوس صدا و APIهای تغییر صدا اعمال می‌کند تا اطمینان حاصل شود که این تغییرات عمداً توسط کاربر آغاز می‌شوند.

تمام برنامه‌هایی که روی اندروید ۱۷ اجرا می‌شوند و این تعاملات صوتی پس‌زمینه را دارند، باید یک فعالیت قابل مشاهده داشته باشند یا باید یک سرویس پیش‌زمینه را اجرا کنند که از نوع SHORT_SERVICE نباشد. این موضوع صرف نظر از اینکه برنامه سطح API ۳۷ را هدف قرار دهد یا خیر، صدق می‌کند.

اگر برنامه‌ای اندروید ۱۷ (سطح API ۳۷) را هدف قرار دهد، یک محدودیت اضافی نیز وجود دارد. اگر برنامه در پس‌زمینه اجرا می‌شود، باید یک سرویس پیش‌زمینه را اجرا کند که دارای قابلیت‌های در حین استفاده (WIU) باشد. (یک سرویس پیش‌زمینه در صورتی قابلیت‌های WIU را دریافت می‌کند که در پاسخ به یک عملیات آغاز شده توسط کاربر یا در حالی که برنامه برای کاربر قابل مشاهده است، شروع به کار کند.) با این حال، اگر به برنامه مجوز دقیق هشدار داده شده باشد و در حال ایجاد تغییراتی در جریان‌های صوتی دارای ویژگی USAGE_ALARM باشد، الزام قابلیت‌های WIU لغو می‌شود.

اگر برنامه سعی کند APIهای صوتی را در حالی که برنامه در چرخه حیات معتبری نیست، فراخوانی کند، APIهای پخش صدا و تغییر صدا بدون ایجاد استثنا یا ارائه پیام خطا، بی‌صدا با شکست مواجه می‌شوند. API فوکوس صوتی با کد نتیجه AUDIOFOCUS_REQUEST_FAILED با شکست مواجه می‌شود.

چرا ما در حال ایجاد تغییر هستیم؟

هدف از اعمال این محدودیت‌ها، کاهش تجربه‌های ناخواسته‌ی مشکلات صوتی پس‌زمینه است. برخی از نمونه‌ها عبارتند از:

  • برنامه‌هایی که بدون سرویس پیش‌زمینه، صدا پخش می‌کنند، می‌توانند مسدود شوند. وقتی برنامه در نهایت از حالت مسدود خارج می‌شود، به‌طور غیرمنتظره‌ای پخش صدا را از سر می‌گیرد، احتمالاً چند ساعت بعد.
  • برنامه‌هایی که بدون سرویس پیش‌زمینه، صدا پخش می‌کردند، با محدودیت‌های اجرای متنوعی مواجه شدند که منجر به عملکرد صوتی ناپایدار می‌شد.
  • پخش از چرخه حیات فعالیت جدا می‌شود، که می‌تواند منجر به نشت جلسه پخش یا نشت رویدادهای فوکوس شود که بدون هیچ راهی برای توقف پخش توسط کاربر ادامه می‌یابند.

ما توسعه‌دهندگان را تشویق می‌کنیم که برنامه‌های خود را آزمایش کنند و در صورت وجود هرگونه مورد استفاده عمدی از صدا که تأثیر منفی داشته باشد، بازخورد خود را در مورد تغییر رفتار ارائه دهند. لطفاً هرگونه مشکلی را با استفاده از این ردیاب مشکلات سازگاری برنامه اندروید ۱۷ گزارش دهید.

موارد استفاده از صدای پس‌زمینه تحت تأثیر را شناسایی کنید

پیاده‌سازی پخش صدا را بررسی کنید و مشخص کنید که آیا برنامه شما قصد دارد حتی در شرایط خاص، قابلیت تعامل صوتی پس‌زمینه را ارائه دهد یا خیر.

اگر برنامه شما فقط قصد پخش صدا یا استفاده از APIهای صوتی را در حین نمایش یک فعالیت قابل مشاهده برای کاربر، از جمله استفاده از حالت تصویر در تصویر (PiP) دارد، تحت تأثیر هیچ یک از این تغییرات قرار نمی‌گیرد.

اگر برنامه شما قابلیت VOIP، از جمله برنامه‌های تماس ویدیویی را ارائه می‌دهد، باید از قبل الزامات معرفی شده برای پخش (معمولاً از طریق استفاده از APIهای مخابراتی توصیه شده) را برای ضبط موفقیت‌آمیز صدا برآورده کند و بنابراین بعید است که تحت تأثیر قرار گیرد.

اگر برنامه شما قصد دارد پخش صدا را در حالی که صفحه نمایش خاموش است یا فعالیت شما قابل مشاهده نیست ، ادامه دهد، که بیشتر در برنامه‌های پخش موسیقی یا برنامه‌های پادکست دیده می‌شود، در نظر گرفته می‌شود که برنامه شما قابلیت پخش صدای پس‌زمینه را ارائه می‌دهد و باید الزامات جدید را برآورده کند.

سناریوهای صوتی پس‌زمینه که احتمالاً تأثیر خواهند گذاشت

اگر برنامه شما از مدل ادامه تعامل صوتی که هنگام باز بودن برنامه یا در پاسخ به یک اقدام صریح کاربر آغاز شده است، پیروی نکند، احتمالاً عملکرد برنامه شما به طور خاموش سرکوب خواهد شد.

برای مثال، اگر برنامه شما در پاسخ به BOOT_COMPLETE یک سرویس پیش‌زمینه را اجرا کند و سعی در تعامل با صدا داشته باشد، این سرویس سرکوب خواهد شد.

بهترین شیوه‌های صوتی پس‌زمینه برای کاهش تأثیر

  • برای مدیریت پخش صدای پس‌زمینه، از کامپوننت MediaSessionService کتابخانه‌ی جت‌پک media3 استفاده کنید.

    اگر این کار را انجام دهید، به دلیل کمک کتابخانه در مدیریت چرخه عمر پخش، بعید است برنامه شما تحت تأثیر سخت شدن پس‌زمینه قرار گیرد.

  • اگر از کتابخانه media3 استفاده نمی‌کنید، باید به صورت دستی mediaPlayback FGS را شروع کنید. در صورت احتمال بروز صدا در پس‌زمینه، همیشه یک سرویس پیش‌زمینه را در حالی که برنامه در پیش‌زمینه است، شروع کنید.

    برای مثال، اگر برنامه شما یک برنامه پخش ویدیو است که معمولاً فقط در پیش‌زمینه اجرا می‌شود اما شامل امکانی برای کاربر است که می‌تواند در هنگام خاموش بودن صفحه نمایش به پخش ادامه دهد، وقتی که تریگر پخش توسط کاربر اجرا می‌شود، برنامه شما باید همچنان یک سرویس پیش‌زمینه را اجرا کند.

    انجام این کار تضمین می‌کند که سرویس پیش‌زمینه با قابلیت‌های WIU آغاز می‌شود.

  • در طول خرابی‌های گذرای کمتر از ۱۰ دقیقه، mediaPlayback FGS را فعال نگه دارید.

    اگر برنامه شما دچار یک خطای گذرا شود، مانند مشکل بافرینگ به دلیل فعالیت شبکه، یا یک وقفه گذرای مورد انتظار مانند AUDIOFOCUS_LOSS_TRANSIENT ، قصد پخش باید ادامه یابد. بنابراین FGS شما باید فعال بماند.

  • سرویس پیش‌زمینه را در پایان پخش متوقف کنید و پخش را فقط در صورتی که کاربر صریحاً پخش را از سر بگیرد، مجدداً آغاز کنید.

    در صورت وجود سیگنال دائمی برای پایان پخش (برای مثال، محتوا بدون پخش خودکار، AUDIOFOCUS_LOSS ، رویداد مکث از UMO یا رویداد کلید رسانه) یا یک خرابی غیرقابل بازیابی، برنامه شما باید تعامل صوتی را متوقف کند، سرویس پیش‌زمینه را متوقف کند و جلسه رسانه را پایان دهد. انجام همه این کارها مطابق با تصور کاربر از "پایان دادن" به تعامل صوتی پس‌زمینه مورد نظر است. پس از انجام این کار، برنامه شما دیگر قابلیت‌های تعامل صوتی پس‌زمینه را ندارد.

    متعاقباً، اگر کاربر به طور صریح پخش را از سر بگیرد، مثلاً از طریق رابط کاربری برنامه شما یا از طریق دکمه پخش Universal Media Object، هدف شروع پخش صدا باید بازگردد و در نتیجه یک FGS تازه شروع شده ایجاد شود.

  • رفتار پخش صدا را با دستورات پوسته adb آزمایش کنید.

آزمایش تغییرات

شما می‌توانید با اجرای دستور ADB زیر، سازگاری برنامه خود را در برنامه‌هایی که اندروید ۱۷ یا بالاتر (از نسخه بتا ۳ به بعد) اجرا می‌شوند، آزمایش کنید:

adb shell cmd audio set-enable-hardening <enable|disable|throw>

این دستور گزینه‌های زیر را دارد:

  • enable : تمام محدودیت‌های سخت‌سازی صدا را برای همه برنامه‌ها فعال می‌کند. الزام سرویس‌های پیش‌زمینه WIU صرف نظر از اینکه برنامه اندروید ۱۷ (سطح API ۳۷) را هدف قرار می‌دهد یا خیر، اعمال می‌شود. علاوه بر این، این الزام حتی اگر برنامه در حال ایجاد تغییراتی در جریان‌های هشدار باشد و مجوز دقیق هشدار را داشته باشد، اعمال می‌شود.

  • disable : تمام محدودیت‌های سخت‌سازی صدا را غیرفعال می‌کند.

  • throw : تمام محدودیت‌های سخت‌سازی صدا را برای همه برنامه‌ها فعال می‌کند، مانند enable . علاوه بر این، این پرچم، خطاهای بلند را فعال می‌کند و IllegalStateException را برای تعاملات صدا و فوکوس ایجاد می‌کند. برای پخش صدا، متد write به طور مداوم یک کد خطا برمی‌گرداند. برای حالت‌های پخش بدون نوشتن صریح، برنامه از کار می‌افتد.

از adb dumpsys audio یا logcat برای شناسایی اینکه آیا برنامه به دلیل اجرای سخت‌سازی صدا با شکست‌های خاموش مواجه شده است یا خیر، استفاده کنید. در این صورت، یک ورودی با پیشوند AudioHardening به همراه نام بسته شما وجود خواهد داشت. اگر پیام حاوی level: full ، برنامه شما در حال اجرای یک سرویس پیش‌زمینه است، اما این سرویس قابلیت while-in-use را ندارد. اگر پیام حاوی level: partial ، برنامه شما اصلاً سرویس پیش‌زمینه را اجرا نمی‌کند.

آشنایی با FGS با قابلیت استفاده در حین استفاده

به‌طورکلی، سرویس‌های پیش‌زمینه (FGS) باید زمانی که یک برنامه در پیش‌زمینه است، راه‌اندازی شوند تا عملیات آغاز شده توسط کاربر را گسترش دهند. در برخی موارد خاص ، برنامه‌ها مجاز به راه‌اندازی یک سرویس پیش‌زمینه در حالی که برنامه در پس‌زمینه است، هستند. با این حال، این سرویس‌های پیش‌زمینه معمولاً قابلیت‌های «در حال استفاده» (WIU) را دریافت نمی‌کنند.

WIU به عنوان یک دروازه امنیتی عمل می‌کند - مانع از آن می‌شود که FGS که در پس‌زمینه شروع شده است، در مواقعی که کاربر ممکن است از فعالیت برنامه آگاه نباشد، درگیر رفتارهای حساس خاصی شود. این مانع از دسترسی برنامه به داده‌های حساس مانند مکان، دوربین یا میکروفون می‌شود و از اندروید ۱۷ به بعد، APIهای صوتی را که معمولاً به یک زمینه رابط کاربری قابل مشاهده نیاز دارند، نیز مسدود می‌کند.

در اینجا یک مرجع مفید وجود دارد:

  • FGS استاندارد: سرویس‌هایی که در حین مشاهده برنامه یا با مجوز اجرای فعالیت پس‌زمینه شروع به کار می‌کنند، دسترسی WIU دریافت می‌کنند.
  • FGS شروع‌شده از پس‌زمینه (BFSL): اکثر آنها دسترسی WIU را اعطا نمی‌کنند. استثنائات اصلی که WIU را اعطا می‌کنند، تعاملاتی هستند که شامل قصد صریح کاربر می‌شوند، مانند کلیک‌های اعلان، تعاملات ویجت یا رویدادهای کلید رسانه از یک دستگاه خارجی.
  • FGS آغاز شده توسط سیستم: سرویس‌های پیش‌زمینه در صورتی به WIU دسترسی داده می‌شوند که توسط واگذاری سیستم-سرور (به عنوان مثال، از کتابخانه Telecom jetpack) یا توسط اتصالات سیستم که نشان‌دهنده یک حالت پیش‌زمینه ارتقا یافته برای انجام عملکردهای اختصاصی هستند (مانند VoiceInteractionService ) آغاز شوند.

برای اطلاعات بیشتر به بخش «محدودیت‌های شروع یک سرویس پیش‌زمینه از پس‌زمینه» مراجعه کنید.

لیست کامل APIهای صوتی تحت تأثیر قرار گرفته

عملکرد صوتی

نتیجه

APIهای تحت تأثیر

پخش صوتی

پخش بی‌صدا شده است

بدون استثنا، بدون پیام خطا توسط هیچ API ارائه نمی‌شود

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES برای اندروید

هر کتابخانه رسانه‌ای سمت کلاینت که پخش را مدیریت می‌کند، مانند media3، Exoplayer و Oboe، نیز می‌تواند تحت تأثیر قرار گیرد.

درخواست فوکوس صوتی

تابع AUDIOFOCUS_REQUEST_FAILED را برمی‌گرداند.

هیچ تاثیری بر پخش صدای برنامه‌های دیگر ندارد، فوکوس به دست نمی‌آید

AudioManager.requestAudioFocus()

رابط‌های برنامه‌نویسی (API) برای حالت صدا و زنگ

هیچ تاثیری بر حالت زنگ یا میزان صدا ندارد (فراخوانی متد به طور بی‌صدا نادیده گرفته می‌شود)

بدون استثنا، بدون پیام خطا توسط هیچ API ارائه نمی‌شود

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()