برنامههایی که Android 12 (سطح میانای برنامهسازی کاربردی ۳۱) یا بالاتر را هدفیابی میکنند نمیتوانند سرویسهای پیشزمینهای را درحالیکه برنامه در پسزمینه اجرا میشود شروع کنند، بهجز چند مورد خاص. اگر برنامهای سعی کند سرویس پیشزمینهای را درحالیکه برنامه در پسزمینه اجرا میشود راهاندازی کند و سرویس پیشزمینهای یکی از موارد استثنایی را برآورده نکند، سیستم ForegroundServiceStartNotAllowedException را برمیگرداند.
علاوهبراین، اگر برنامهای بخواهد سرویس پیشزمینهای راهاندازی کند که به اجازههای درحین استفاده (برای مثال، حسگر بدن، دوربین، میکروفون، یا اجازههای مکان) نیاز دارد، نمیتواند سرویس را درحالیکه برنامه در پسزمینه است ایجاد کند، حتی اگر برنامه مشمول یکی از معافیتهای محدودیتهای راهاندازی در پسزمینه باشد. دلیل این امر در بخش محدودیتهای شروع سرویسهای پیشزمینهای که به اجازههای درحین استفاده نیاز دارند توضیح داده شده است.
معافیت از محدودیتهای شروع در پسزمینه
در شرایط زیر، برنامهتان میتواند سرویسهای پیشزمینهای را حتی زمانی که برنامهتان در پسزمینه اجرا میشود راهاندازی کند:
- برنامه شما از وضعیتی که برای کاربر قابلمشاهده است، مثل فعالیت، انتقال مییابد.
- برنامه شما میتواند فعالیتی را از پسزمینه شروع کند، بهجز در مواردی که برنامه فعالیتی در پشته قبلیها از تکلیف موجود داشته باشد.
برنامه شما بااستفاده از پیامرسانی ابریِ Firebase پیامی با اولویت بالا دریافت میکند.
کاربر کنشی را روی عنصر میانای کاربر مرتبط با برنامه شما انجام میدهد. برای مثال، ممکن است با حباب، اعلان، ابزاره، یا فعالیت تعامل داشته باشد.
برنامه شما برای تکمیل کنشی که کاربر درخواست کرده است، زنگ دقیق را فراخوانی میکند.
برنامه شما روش ورودی فعلی دستگاه است.
برنامه شما رویدادی دریافت میکند که مربوط به حصار جغرافیایی یا انتقال تشخیص فعالیت است.
پساز اینکه دستگاه بازراهاندازی شد و کنش هدف
ACTION_BOOT_COMPLETED،ACTION_LOCKED_BOOT_COMPLETED، یاACTION_MY_PACKAGE_REPLACEDرا در گیرنده رویداد ثبتشده دریافت کرد.برنامه شما کنش هدف
ACTION_TIMEZONE_CHANGED،ACTION_TIME_CHANGED، یاACTION_LOCALE_CHANGEDرا در گیرنده رویداد ثبتشده دریافت میکند.برنامه شما رویداد
ACTION_TRANSACTION_DETECTEDرا ازNfcServiceدریافت میکند.برنامههایی با نقشها یا اجازههای سیستم خاص، مانند مالکان دستگاه و مالکان نمایه.
برنامه شما از مدیر دستگاه همپا استفاده میکند و اجازه
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUNDیا اجازهREQUEST_COMPANION_RUN_IN_BACKGROUNDرا اعلام میکند. هرگاه ممکن بود، ازREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUNDاستفاده کنید.کاربر بهینهسازیهای باتری را برای برنامه شما خاموش میکند.
برنامه شما اجازه
SYSTEM_ALERT_WINDOWرا دارد. توجه: اگر برنامه شما Android نسخه ۱۵ یا بالاتر را هدف قرار میدهد، باید اجازهSYSTEM_ALERT_WINDOWرا داشته باشد و برنامه باید درحالحاضر پنجره همپوشانی نمایان داشته باشد.
محدودیتهای شروع سرویسهای پیشزمینهای که به اجازههای «درحال استفاده» نیاز دارند
در Android نسخه ۱۴ (سطح API ۳۴) یا بالاتر، شرایط خاصی وجود دارد که باید از آنها مطلع باشید اگر سرویس پیشزمینهای را شروع میکنید که به اجازههای «درحال استفاده» نیاز دارد.
اگر برنامه شما Android نسخه ۱۴ یا بالاتر را هدف قرار میدهد، سیستمعامل
هنگام ایجاد سرویس پیشزمینهای بررسی میکند تا مطمئن شود برنامه شما همه
اجازههای مناسب را برای آن نوع سرویس دارد. برای مثال، وقتی سرویس پیشزمینهای از نوع میکروفون ایجاد میکنید، سیستمعامل تأیید میکند که برنامهتان درحالحاضر اجازه RECORD_AUDIO را دارد. اگر این اجازه را نداشته باشید، سیستم
SecurityException را نشان میدهد.
برای اجازههای «هنگام استفاده»، این امر باعث بروز مشکل احتمالی میشود. اگر برنامهتان اجازه
«هنگام استفاده» داشته باشد، فقط زمانی که در
پیشزمینه است این اجازه را دارد. این یعنی اگر برنامهتان در پسزمینه باشد و بخواهد سرویس پیشزمینهای از نوع دوربین، مکان، یا میکروفون ایجاد کند، سیستم میبیند که برنامهتان درحالحاضر اجازههای لازم را ندارد و SecurityException را برمیگرداند.
بهطور مشابه، اگر برنامهتان در پسزمینه باشد و
سرویس سلامتی ایجاد کند که به اجازه BODY_SENSORS نیاز داشته باشد، برنامه
درحالحاضر آن اجازه را ندارد و سیستم استثنایی را ایجاد میکند.
(اگر سرویس سلامتی باشد که به اجازههای متفاوتی نیاز دارد،
مثل ACTIVITY_RECOGNITION، این مورد اعمال نمیشود.) فراخوانی
PermissionChecker.checkSelfPermission()
مانع این مشکل نمیشود. اگر برنامهتان اجازه «هنگام استفاده» داشته باشد و
checkSelfPermission() را فراخوانی کند تا بررسی کند این اجازه را دارد یا نه، این روش
PERMISSION_GRANTED را برمیگرداند، حتی اگر برنامه در پسزمینه باشد. وقتی
روش PERMISSION_GRANTED را برمیگرداند، یعنی «برنامه شما این اجازه را دارد
درحالیکه برنامه درحال استفاده است.»
به همین دلیل، اگر سرویس پیشزمینهای شما به اجازه «درحین استفاده» نیاز دارد،
باید Context.startForegroundService() یا Context.bindService() را زمانی فراخوانی کنید که
برنامهتان فعالیت نمایانی دارد، مگراینکه سرویس در یکی از
معافیتهای تعریفشده قرار گیرد.
معافیت از محدودیتهای اجازههای «درحال استفاده»
در برخی شرایط، حتی اگر سرویس پیشزمینهای درحالیکه برنامه در پسزمینه اجرا میشود شروع شود، همچنان میتواند به اطلاعات مکان، دوربین، و میکروفون دسترسی داشته باشد، درحالیکه برنامه در پیشزمینه اجرا میشود («درحال استفاده»).
در همین شرایط، اگر سرویس نوع سرویس پیشزمینهای location را اعلام کند و توسط برنامهای شروع شود که اجازه ACCESS_BACKGROUND_LOCATION را دارد، این سرویس میتواند همیشه به اطلاعات مکان دسترسی داشته باشد، حتی زمانی که برنامه در پسزمینه اجرا میشود.
فهرست زیر شامل این موقعیتها است:
- یکی از مؤلفههای سیستم سرویس را شروع میکند.
- این سرویس با تعامل با ابزارههای برنامه شروع میشود.
- سرویس با تعامل با اعلان شروع میشود.
- سرویس بهعنوان
PendingIntentشروع میشود که از برنامه نمایان دیگری ارسال شده است. - سرویس توسط برنامهای شروع میشود که کنترلکننده خطمشی دستگاه است و در حالت مالک دستگاه اجرا میشود.
- این سرویس توسط برنامهای شروع میشود که
VoiceInteractionServiceرا ارائه میدهد. - سرویس توسط برنامهای شروع میشود که
اجازه ممتاز
START_ACTIVITIES_FROM_BACKGROUNDرا دارد.
مشخص کردن اینکه کدام سرویسها در برنامهتان تحتتأثیر قرار گرفتهاند
هنگام آزمایش برنامه، سرویسهای پیشزمینهای آن را راهاندازی کنید. اگر سرویس شروعشدهای دسترسی محدود به مکان، میکروفون، و دوربین داشته باشد، پیام زیر در Logcat نشان داده میشود:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME