وضع قفل المهام

يوضّح دليل المطوِّر كيفية قفل الأجهزة المخصّصة على تطبيق واحد أو مجموعة من التطبيقات. إذا كنت أحد مطوّري برامج إدارة الخدمات الجوّالة للمؤسسات (EMM) أو الشركة التي تُجري عملية تكامل للحلول، يُرجى قراءة هذا الدليل لإضافة وضع القفل إلى حلك.

نظرة عامة

يمكن لنظام Android تشغيل المهام بطريقة شاملة تشبه Kiosk اسم وضع مهمة القفل. يمكنك استخدام وضع قفل المهمة إذا كنت تعمل على تطوير تطبيق Kiosk أو مشغّل تطبيقات لعرض مجموعة من التطبيقات. عند تشغيل النظام في وضع قفل المهمة، لا يمكن لمستخدمي الأجهزة عادةً الاطّلاع على الإشعارات أو الوصول إلى التطبيقات غير المدرَجة في القائمة المسموح بها أو العودة إلى الشاشة الرئيسية (ما لم تكن الشاشة الرئيسية مدرَجة في القائمة المسموح بها).

لا يمكن تشغيل سوى التطبيقات المدرَجة في القائمة المسموح بها من خلال وحدة التحكّم بسياسة الجهاز (DPC) عندما يكون النظام في وضع قفل المهمة. التطبيقات مُدرَجة في القائمة المسموح بها لأنّ المستخدم الذي يستخدم الجهاز لا يمكنه دائمًا مغادرة "وضع القفل".

تعتمد كيفية دمج التطبيق المدرَج في القائمة المسموح بها في وضع القفل مع وحدة التحكّم بسياسة الجهاز (DPC) على القائمة المسموح بها على المشكلة التي تريد حلّها. وفي ما يلي بعض الأمثلة:

  • هو حزمة تطبيق واحدة تجمع بين وضع Kiosk (لتقديم المحتوى) ووحدة التحكّم بسياسة الجهاز (DPC) المصغَّرة (لإضافة نفسها إلى القائمة المسموح بها لوضع قفل المهام).
  • يشير هذا المصطلح إلى وحدة التحكّم بسياسة الجهاز (DPC) التي تمثل جزءًا من حل إدارة الخدمات الجوّالة للمؤسسات، وتطلق التطبيقات المتوافقة مع الأجهزة الجوّالة الخاصة بالعميل في وضع القفل.

أماكن التوفّر

يمكن تشغيل النظام في وضع قفل المهمة في الإصدار Android 5.0 أو الإصدارات الأحدث. يعرض الجدول 1 إصدارات Android التي تتيح إدراج التطبيقات في القائمة المسموح بها حسب المستخدم.

الجدول 1. توافق إصدار Android مع أوضاع مشرف وحدة التحكّم بسياسة الجهاز (DPC)
إصدار Android المشرفون على وحدة التحكّم بسياسة الجهاز (DPC) Notes
Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات) أو إصدار أحدث جهاز مُدار بالكامل
Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات) أو إصدار أحدث مستخدم ثانوي تابع يجب أن يكون المستخدم الثانوي تابعًا للمستخدم الأساسي. يمكنك الاطّلاع على نظرة عامة على العديد من المستخدمين.
Android 9.0 (المستوى 28 من واجهة برمجة التطبيقات) أو إصدار أحدث مستخدم ثانوي

في نظام التشغيل Android 9.0 أو الإصدارات الأحدث، يمكن لوحدة التحكّم بسياسة الجهاز بدء نشاط أي تطبيق في وضع قفل المهمة. في الإصدارات السابقة، يجب أن يتيح التطبيق بدء نشاطه الخاص في وضع مهمة القفل.

إضافة التطبيقات إلى القائمة المسموح بها

يجب أن تضيف وحدة التحكّم بسياسة الجهاز التطبيقات إلى القائمة المسموح بها حتى يمكن استخدامها في وضع قفل المهمة. يمكنك استدعاء DevicePolicyManager.setLockTaskPackages() لإدراج التطبيقات في القائمة المسموح بها لوضع قفل المهمة كما هو موضّح في النموذج التالي:

Kotlin

// Allowlist two apps.
private val KIOSK_PACKAGE = "com.example.kiosk"
private val PLAYER_PACKAGE = "com.example.player"
private val APP_PACKAGES = arrayOf(KIOSK_PACKAGE, PLAYER_PACKAGE)

// ...

val context = context
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
val adminName = getComponentName(context)
dpm.setLockTaskPackages(adminName, APP_PACKAGES)

Java

// Allowlist two apps.
private static final String KIOSK_PACKAGE = "com.example.kiosk";
private static final String PLAYER_PACKAGE = "com.example.player";
private static final String[] APP_PACKAGES = {KIOSK_PACKAGE, PLAYER_PACKAGE};

// ...

Context context = getContext();
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminName = getComponentName(context);
dpm.setLockTaskPackages(adminName, APP_PACKAGES);

لمعرفة التطبيقات المُدرَجة سابقًا في القائمة المسموح بها لتفعيل وضع القفل، يمكن لوحدة التحكّم بسياسة الجهاز الاتصال بها DevicePolicyManager.getLockTaskPackages(). يمكن للتطبيقات الأخرى استدعاء DevicePolicyManager.isLockTaskPermitted() للتأكد من أن حزمة التطبيق تدعم وضع قفل المهمة.

بدء وضع قفل المهمة

في نظام التشغيل Android 9.0 (المستوى 28 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، يمكنك بدء نشاط تطبيق آخر في وضع مهمة القفل. إذا كان النشاط قيد التشغيل بالفعل في المقدمة أو الخلفية، فستحتاج إلى إعادة تشغيل النشاط. يمكنك الاتصال بـ ActivityOptions.setLockTaskEnabled() وتقديم هذه الخيارات عند بدء النشاط. يوضح المقتطف التالي طريقة واحدة يمكنك من خلالها:

Kotlin

// Set an option to turn on lock task mode when starting the activity.
val options = ActivityOptions.makeBasic()
options.setLockTaskEnabled(true)

// Start our kiosk app's main activity with our lock task mode option.
val packageManager = context.packageManager
val launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE)
if (launchIntent != null) {
    context.startActivity(launchIntent, options.toBundle())
}

Java

// Set an option to turn on lock task mode when starting the activity.
ActivityOptions options = ActivityOptions.makeBasic();
options.setLockTaskEnabled(true);

// Start our kiosk app's main activity with our lock task mode option.
PackageManager packageManager = context.getPackageManager();
Intent launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE);
if (launchIntent != null) {
  context.startActivity(launchIntent, options.toBundle());
}

في إصدارات Android التي تسبق الإصدار 9.0، يبدأ التطبيق أنشطته الخاصة في وضع قفل المهام من خلال استدعاء Activity.startLockTask(). لتسمية هذه الطريقة، يجب أن يكون النشاط قيد التشغيل في المقدّمة (راجِع مفاهيم دورة حياة النشاط) لذا نقترح استدعاء طريقة onResume() في Activity أوFragment. في ما يلي كيفية الاتصال بـ startLockTask():

Kotlin

// In our Fragment subclass.
override fun onResume() {
    super.onResume()
    // First, confirm that this package is allowlisted to run in lock task mode.
    if (dpm.isLockTaskPermitted(context.packageName)) {
        activity.startLockTask()
    } else {
        // Because the package isn't allowlisted, calling startLockTask() here
        // would put the activity into screen pinning mode.
    }
}

Java

// In our Fragment subclass.
@Override
public void onResume() {
  super.onResume();

  // First, confirm that this package is allowlisted to run in lock task mode.
  if (dpm.isLockTaskPermitted(context.getPackageName())) {
    getActivity().startLockTask();
  } else {
    // Because the package isn't allowlisted, calling startLockTask() here
    // would put the activity into screen pinning mode.
  }
}

لا تبدأ وضع قفل المهمة عندما يكون الجهاز مقفلاً لأنّ المستخدم قد لا يتمكّن من فتح قفل الجهاز. يمكنك استدعاء طُرق KeyguardManager لمعرفة ما إذا كان الجهاز مقفلاً واستخدام معاودة الاتصال خلال مراحل نشاط Activity (مثل onResume() يتم طلبها بعد فتح القفل) لتفعيل وضع القفل.

يمكن أن يبدأ التطبيق في وضع قفل المهام أنشطة جديدة طالما لم يبدأ النشاط مهمة جديدة، باستثناء المهام التي تؤدّي إلى تشغيل تطبيق مُدرَج في القائمة المسموح بها. لفهم كيفية ارتباط المهام بالأنشطة، يُرجى الاطّلاع على دليل فهم المهام وحزمة Back Stack.

وبدلاً من ذلك، يمكنك أن توضح في ملف بيان التطبيق سلوك النشاط عند تشغيل النظام في وضع قفل المهمة. لتفعيل النظام تلقائيًا لنشاطك في وضع قفل المهمة، اضبط السمة android:lockTaskMode على if_whitelisted كما هو موضّح في المثال التالي:

<activity
    android:name=".MainActivity"
    android:lockTaskMode="if_whitelisted">
    <!-- ... -->
</activity>

يمكنك معرفة مزيد من المعلومات حول تحديد خيارات الإعلان في ملف بيان التطبيق من خلال قراءة مرجع lockTaskMode.

إيقاف وضع قفل المهمة

يمكن لوحدة التحكّم بسياسة الجهاز إيقاف وضع قفل المهمة عن بُعد عن طريق إزالة حزمة التطبيقات من القائمة المسموح بها. عليك طلب الإجراء DevicePolicyManager.setLockTaskPackages()، في الإصدار Android 6.0 (المستوى 23 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، وحذف اسم الحزمة من مصفوفة القائمة المسموح بها. وعند تعديل القائمة المسموح بها، يعود التطبيق إلى المهمة السابقة في الحزمة.

إذا كان هناك نشاط كان يُعرف في السابق باسم startLockTask()، يمكن أن يستدعي النشاط الطلب Activity.stopLockTask() لإيقاف وضع قفل المهمة. لا تعمل هذه الطريقة إلا مع النشاط الذي بدأ قفل وضع المهمة.

عمليات معاودة الاتصال خلال مراحل النشاط

قد يجد وحدة التحكّم بسياسة الجهاز (DPC) أنه من المفيد معرفة وقت دخول تطبيق (يتم تشغيله على حساب المستخدم نفسه) إلى وضع قفل المهمة وخروجه منه. لتلقّي عمليات معاودة الاتصال، عليك تجاهل طرق معاودة الاتصال التالية في الفئة الفرعية DeviceAdminReceiver لوحدة التحكّم بسياسة الجهاز:

onLockTaskModeEntering()
يتم الاتصال بعد دخول أحد التطبيقات في وضع قفل المهمة. يمكنك الحصول على اسم الحزمة لتطبيق من الوسيطة pkg.
onLockTaskModeExiting()
يتم الاتصال به بعد خروج أحد التطبيقات من وضع القفل. لا تتلقّى معاودة الاتصال هذه معلومات حول التطبيق.

في حال تشغيل تطبيق آخر في وضع قفل المهمة، عليك تتبُّع حالة التشغيل في تطبيقك الخاص. للتحقّق مما إذا كان التطبيق الحالي يعمل في وضع القفل، استخدِم الطرق في ActivityManager كما هو موضّح في المثال التالي:

Kotlin

// Check if this app is in lock task mode. Screen pinning doesn't count.
var isLockTaskModeRunning = false

val activityManager = context
        .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    isLockTaskModeRunning =
            activityManager.lockTaskModeState ==
            ActivityManager.LOCK_TASK_MODE_LOCKED
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Deprecated in API level 23.
    isLockTaskModeRunning = activityManager.isInLockTaskMode
}

if (isLockTaskModeRunning) {
    // Show the exit button ...
}

Java

// Check if this app is in lock task mode. Screen pinning doesn't count.
boolean isLockTaskModeRunning = false;

ActivityManager activityManager = (ActivityManager)
    getContext().getSystemService(Context.ACTIVITY_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  isLockTaskModeRunning = activityManager.getLockTaskModeState()
      == ActivityManager.LOCK_TASK_MODE_LOCKED;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  // Deprecated in API level 23.
  isLockTaskModeRunning = activityManager.isInLockTaskMode();
}

if (isLockTaskModeRunning) {
  // Show the exit button ...
}

تخصيص واجهة المستخدم

عند تشغيل تطبيق في وضع قفل المهمة، تتغير واجهة مستخدم النظام بالطرق التالية:

  • شريط الحالة فارغ مع إخفاء الإشعارات ومعلومات النظام.
  • يتم إخفاء زرَّي "الصفحة الرئيسية" و"نظرة عامة".
  • لا يمكن للتطبيقات الأخرى بدء أنشطة جديدة.
  • يتم إيقاف شاشة القفل (في حال ضبطها).

في نظام التشغيل Android 9.0 أو الإصدارات الأحدث، عندما يكون وضع قفل المهام مفعَّلاً، يمكن لوحدة التحكّم بسياسة الجهاز تفعيل ميزات معيّنة لواجهة مستخدم النظام على الجهاز، وهي مفيدة للمطوّرين الذين ينشئون مشغّل تطبيقات مخصَّصًا. استدعِ DevicePolicyManager.setLockTaskFeatures() كما هو في المقتطف التالي:

Kotlin

// Enable the Home and Overview buttons so that our custom launcher can respond
// using our custom activities. Implicitly disables all other features.
dpm.setLockTaskFeatures(
        adminName,
        DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
              DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW)

Java

// Enable the Home and Overview buttons so that our custom launcher can respond
// using our custom activities. Implicitly disables all other features.
dpm.setLockTaskFeatures(adminName,
    DevicePolicyManager.LOCK_TASK_FEATURE_HOME |
          DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW);

يوقف النظام أي ميزات لا تدرجها في الوسيطة flags. تستمر ميزات واجهة المستخدم المفعَّلة بين عمليات التشغيل في وضع قفل المهمة. إذا كان الجهاز في وضع قفل المهمة مسبقًا، ستظهر على الفور أي تغييرات تجريها على ميزات مهمة القفل. يصف الجدول 2 ميزات واجهة المستخدم التي يمكنك تخصيصها.

الجدول 2. ميزات قابلة للتخصيص لواجهة مستخدم النظام في وضع القفل
ميزة واجهة مستخدم النظام الوصف
LOCK_TASK_FEATURE_HOME يؤدي هذا الخيار إلى عرض زر الصفحة الرئيسية. تفعيل مشغّلات التطبيقات المخصّصة: لن يكون هناك أي إجراء عند النقر على زر الشاشة الرئيسية المفعَّل إلا إذا أضفت مشغّل Android التلقائي إلى القائمة المسموح بها.
LOCK_TASK_FEATURE_OVERVIEW يؤدي هذا الخيار إلى عرض زر "نظرة عامة" (يؤدي النقر على هذا الزر إلى فتح شاشة العناصر الأخيرة). إذا فعّلت هذا الزر، يجب أيضًا تفعيل زر الصفحة الرئيسية.
LOCK_TASK_FEATURE_GLOBAL_ACTIONS تعمل هذه السياسة على تفعيل مربّع حوار الإجراءات العامة الذي يظهر عند الضغط مع الاستمرار على زر التشغيل. الميزة الوحيدة التي يتم تفعيلها عند عدم طلب setLockTaskFeatures(). لا يمكن للمستخدم عادةً إيقاف الجهاز في حال إيقاف مربّع الحوار هذا.
LOCK_TASK_FEATURE_NOTIFICATIONS لتفعيل الإشعارات لجميع التطبيقات. يؤدي هذا الإجراء إلى عرض رموز الإشعارات في شريط الحالة وإشعارات التنبيه ومركز الإشعارات القابل للتوسيع. إذا مكنت هذا الزر، فيجب تمكين زر الصفحة الرئيسية أيضًا. إنّ النقر على إجراءات الإشعارات والأزرار التي تفتح لوحات جديدة لا يعمل في وضع قفل المهمة.
LOCK_TASK_FEATURE_SYSTEM_INFO تعمل هذه السياسة على تفعيل منطقة معلومات النظام في شريط الحالة التي تحتوي على مؤشرات مثل الاتصال والبطارية والصوت والاهتزاز.
LOCK_TASK_FEATURE_KEYGUARD تفعِّل هذه السياسة أي شاشة قفل قد تم ضبطها على الجهاز. لا تكون هذه الميزة مناسبة عادةً للأجهزة التي يستخدمها بشكل عام، مثل أكشاك المعلومات أو اللوحات الرقمية.
LOCK_TASK_FEATURE_NONE لإيقاف جميع ميزات واجهة مستخدم النظام المدرَجة أعلاه.

يمكن لوحدة التحكّم بسياسة الجهاز الاتصال بالرقم DevicePolicyManager.getLockTaskFeatures() للحصول على قائمة بالميزات المتاحة على الجهاز عند تفعيل وضع قفل المهمة. وعند الخروج من وضع القفل في الجهاز، تعود واجهة المستخدم إلى الحالة التي تفرضها سياسات الجهاز الحالية.

حظر النوافذ والعناصر المركّبة

عندما يتم تشغيل تطبيق في وضع قفل المهمة، يمكن للتطبيقات والخدمات الأخرى في الخلفية إنشاء نوافذ جديدة يعرضها Android أمام التطبيق في وضع قفل المهمة. تنشئ التطبيقات والخدمات هذه النوافذ لعرض الإشعارات المحمصة ومربعات الحوار والعناصر المركّبة للشخص الذي يستخدم الجهاز. ويمكن لوحدة التحكّم بسياسة الجهاز منع حدوث ذلك عن طريق إضافة التقييد الذي يفرضه DISALLOW_CREATE_WINDOWS على المستخدم. يوضح المثال التالي كيفية إجراء ذلك في معاودة الاتصال onLockTaskModeEntering():

Kotlin

// Called just after entering lock task mode.
override fun onLockTaskModeEntering(context: Context, intent: Intent) {
    val dpm = getManager(context)
    val admin = getWho(context)

    dpm.addUserRestriction(admin, UserManager.DISALLOW_CREATE_WINDOWS)
}

Java

// Called just after entering lock task mode.
public void onLockTaskModeEntering(Context context, Intent intent) {
  DevicePolicyManager dpm = getManager(context);
  ComponentName admin = getWho(context);

  dpm.addUserRestriction(admin, UserManager.DISALLOW_CREATE_WINDOWS);
}

يمكن لوحدة التحكّم بسياسة الجهاز إزالة القيود المفروضة على المستخدم عند خروج الجهاز من وضع القفل.

مراجع إضافية

لمعرفة المزيد من المعلومات عن الأجهزة المخصّصة، يمكنك قراءة المستندات التالية: