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

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

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

به جای آن اعلان‌ها را نمایش دهید

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

این سیستم هشدار و یادآوری مبتنی بر اعلان، مزایای متعددی را برای کاربران فراهم می‌کند:

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

چه زمانی برنامه‌ها می‌توانند فعالیت‌ها را شروع کنند؟

برنامه‌هایی که روی اندروید ۱۰ یا بالاتر اجرا می‌شوند، می‌توانند در صورت برآورده شدن یک یا چند مورد از شرایط زیر، فعالیت‌ها را شروع کنند:

  • این برنامه یک پنجره قابل مشاهده دارد، مانند یک فعالیت در پیش‌زمینه.
  • این برنامه یک فعالیت (activity) در پشته پشتیِ وظیفه (task) پیش‌زمینه دارد.
  • این برنامه یک فعالیت در پشته پشتی یک وظیفه موجود در صفحه Recents دارد.

  • این برنامه فعالیتی دارد که اخیراً آغاز شده است.

  • برنامه اخیراً تابع finish() را روی یک فعالیت فراخوانی کرده است. این فقط زمانی اعمال می‌شود که برنامه در زمان finish() یا یک فعالیت در پیش‌زمینه داشته باشد یا یک فعالیت در پشته پشتی وظیفه پیش‌زمینه داشته باشد.

  • این برنامه یکی از سرویس‌های زیر را دارد که توسط سیستم محدود شده است. این سرویس‌ها ممکن است نیاز به راه‌اندازی یک رابط کاربری داشته باشند.

  • این برنامه دارای سرویسی است که توسط یک برنامه‌ی قابل مشاهده‌ی متفاوت محدود شده است. برنامه‌ی متصل به سرویس باید در پس‌زمینه قابل مشاهده باقی بماند تا فعالیت‌ها با موفقیت شروع شوند.

  • برنامه یک اعلان PendingIntent از سیستم دریافت می‌کند. در مورد intent های در حال انتظار برای سرویس‌ها و دریافت‌کننده‌های اعلان، برنامه می‌تواند چند ثانیه پس از ارسال intent در حال انتظار، activity ها را شروع کند.

  • برنامه یک PendingIntent دریافت می‌کند که از یک برنامه‌ی قابل مشاهده‌ی متفاوت ارسال شده است.

  • برنامه یک اعلان سیستمی دریافت می‌کند که انتظار می‌رود برنامه در آن یک رابط کاربری را اجرا کند. نمونه‌هایی از آن شامل ACTION_NEW_OUTGOING_CALL و SECRET_CODE_ACTION است. برنامه می‌تواند چند ثانیه پس از ارسال اعلان، فعالیت‌هایی را شروع کند.

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

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

  • کاربر مجوز SYSTEM_ALERT_WINDOW را به برنامه اعطا کرده است.

هنگام شروع فعالیت‌ها از PendingIntents، انتخاب الزامی است

برای جلوگیری از شروع تصادفی Activity بر اساس شرایط ذکر شده ، از اندروید ۱۴ به بعد APIهای صریحی وجود دارند که به شما امکان می‌دهند اعطای مجوزهای برنامه برای شروع Activity را فعال یا غیرفعال کنید.

برنامه‌هایی که اندروید ۱۵ یا بالاتر را هدف قرار می‌دهند، به طور پیش‌فرض دیگر به طور ضمنی امتیازات راه‌اندازی فعالیت پس‌زمینه (BAL) را به PendingIntents که ایجاد می‌کنند، اعطا نمی‌کنند. برای انجام این کار، انتخاب صریح لازم است، این گزینه‌ها بسته به اینکه برنامه در حال ارسال یا ایجاد PendingIntents باشد، وجود دارند.

جدول اهداف در انتظار
شکل ۱: جریان تصمیم‌گیری برای راه‌اندازی فعالیت‌های پس‌زمینه.

توسط فرستنده‌ی PendingIntent

برنامه‌هایی که اندروید ۱۴ یا بالاتر را هدف قرار می‌دهند و می‌خواهند یک PendingIntent را شروع کنند، باید

  • شرایط ذکر شده را احراز کنند و
  • بر اساس آن استثنائات، اجازه دهید فعالیت‌های پس‌زمینه شروع شوند

این انتخاب فقط باید در صورتی اتفاق بیفتد که توسعه‌دهنده برنامه بداند که برنامه قرار است یک فعالیت (Activity) را شروع کند.

برای انتخاب، برنامه باید یک بسته ActivityOptions را به همراه setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) به PendingIntent.send() یا متدهای مشابه ارسال کند.

توسط خالق PendingIntent

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

در بیشتر موارد، برنامه‌ای که PendingIntent آغاز می‌کند باید انتخاب شود. با این حال، اگر برنامه‌ی در حال ایجاد نیاز به اعطای این امتیازات داشته باشد:

  • PendingIntent می‌تواند در هر زمانی که برنامه در حال ایجاد قابل مشاهده است، آغاز شود.
  • PendingIntent می‌تواند در هر زمانی آغاز شود، اگر برنامه‌ی در حال ایجاد، امتیازات ویژه‌ای داشته باشد.

برای شرکت در این فرآیند، برنامه باید یک بسته‌ی ActivityOptions به همراه setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) را به PendingIntent.getActivity() یا متدهای مشابه ارسال کند.

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

حالت سختگیرانه

با شروع از اندروید ۱۶، توسعه‌دهنده برنامه می‌تواند حالت Strict را فعال کند تا هنگام مسدود شدن راه‌اندازی یک فعالیت (یا در معرض خطر مسدود شدن هنگام راه‌اندازی SDK هدف برنامه) مطلع شود.

کد نمونه‌ای که باید از همان ابتدا در متد Application.onCreate() در برنامه، فعالیت یا سایر اجزای برنامه فعال شود:

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     StrictMode.setVmPolicy(
         StrictMode.VmPolicy.Builder()
         .detectBlockedBackgroundActivityLaunch()
         .penaltyLog()
         .build());
     )
 }

برای جزئیات بیشتر، مستندات حالت سختگیرانه (Strict mode) را مطالعه کنید.