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

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

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

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

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

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

در اندروید ۱۴ (سطح 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