محدودیت‌های راه‌اندازی سرویس پیش‌زمینه‌ای از پس‌زمینه

برنامه‌هایی که Android 12 (سطح میانای برنامه‌سازی کاربردی ۳۱) یا بالاتر را هدف‌یابی می‌کنند نمی‌توانند سرویس‌های پیش‌زمینه‌ای را درحالی‌که برنامه در پس‌زمینه اجرا می‌شود شروع کنند، به‌جز چند مورد خاص. اگر برنامه‌ای سعی کند سرویس پیش‌زمینه‌ای را درحالی‌که برنامه در پس‌زمینه اجرا می‌شود راه‌اندازی کند و سرویس پیش‌زمینه‌ای یکی از موارد استثنایی را برآورده نکند، سیستم ForegroundServiceStartNotAllowedException را برمی‌گرداند.

علاوه‌براین، اگر برنامه‌ای بخواهد سرویس پیش‌زمینه‌ای راه‌اندازی کند که به اجازه‌های درحین استفاده (برای مثال، حسگر بدن، دوربین، میکروفون، یا اجازه‌های مکان) نیاز دارد، نمی‌تواند سرویس را درحالی‌که برنامه در پس‌زمینه است ایجاد کند، حتی اگر برنامه مشمول یکی از معافیت‌های محدودیت‌های راه‌اندازی در پس‌زمینه باشد. دلیل این امر در بخش محدودیت‌های شروع سرویس‌های پیش‌زمینه‌ای که به اجازه‌های درحین استفاده نیاز دارند توضیح داده شده است.

معافیت از محدودیت‌های شروع در پس‌زمینه

در شرایط زیر، برنامه‌تان می‌تواند سرویس‌های پیش‌زمینه‌ای را حتی زمانی که برنامه‌تان در پس‌زمینه اجرا می‌شود راه‌اندازی کند:

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

در 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