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