إنشاء تطبيقات تستنِد إلى عدة مستخدمين

عندما يكون الجهاز متوافقًا مع عدة مستخدمين، يجب أن تكون تطبيقاته على دراية بهؤلاء المستخدمين المختلفين.

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

تعمل هذه المنشأة على:

  • الحفاظ على الموارد
  • التحكيم في مورد مشترك واحد أو أكثر بين المستخدمين
  • تقليل عبء الشبكة عن طريق استخدام اتصال خادم واحد

يمكنك مراجعة المخطّط البياني أدناه للاطّلاع على شرح لتدفق الأذونات لدى عدة مستخدمين.

مسار أذونات المستخدمين المتعددين

الشكل 1. أذونات مستخدمين متعددين

تفعيل مكوِّن مفردتون

لتحديد تطبيق واحد، أضِف android:singleUser="true" إلى خدمتك أو المتلقي أو المزود في بيان Android.

سينشئ النظام مثيلاً لهذا المكوِّن في العملية التي يُجريها المستخدم 0. فقط. أي طلبات للاتصال بمقدّم الخدمة أو هذه الخدمة أو للبث إلى ذلك المستلِم، من سيتمّ توجيه أيّ مستخدِم إلى العملية في المستخدِم 0. إذا كان هذا هو المكوّن الوحيد في تطبيقك، سيتم تشغيل نسخة واحدة فقط من تطبيقك.

سيتم إطلاق الأنشطة في حزمتك في عملية منفصلة كل مستخدم، مع وجود المعرّف الفريد في نطاق المعرف الفريد لهذا المستخدم (مثل 1010034).

التفاعل مع المستخدمين

تعيين الأذونات

هذه الأذونات مطلوبة

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

استخدام واجهات برمجة التطبيقات

يمكنك استخدام واجهات برمجة التطبيقات التالية لإعلام التطبيقات بتعدد المستخدمين.

  1. لاستخراج اسم المستخدم المعرِّف من طلبات Binder الواردة:
    • int userHandle = UserHandle.getCallingUserId()
  2. استخدِم واجهات برمجة تطبيقات جديدة ومحمية لبدء الخدمات والأنشطة والبث على جهاز مخصّص المستخدم:
    • Context.startActivityAsUser(Intent, UserHandle)
    • Context.bindServiceAsUser(Intent, …, UserHandle)
    • Context.sendBroadcastAsUser(Intent, … , UserHandle)
    • Context.startServiceAsUser(Intent, …, UserHandle)
    يمكن أن يكون UserHandle مستخدمًا فاضحًا أو أحد الأسماء المعرِّفة الخاصة: UserHandle.CURRENT أو UserHandle.ALL. تشير السمة CURRENT إلى للمستخدم الظاهر حاليًا في المقدّمة. يمكنك استخدام "ALL" عندما تريد ذلك. إرسال إعلان إلى جميع المستخدمين
  3. التواصل مع المكوّنات في تطبيقك: (INTERACT_ACROSS_USERS) أو باستخدام مكوّنات في تطبيقات أخرى: (INTERACT_ACROSS_USERS_FULL)
  4. قد تحتاج إلى إنشاء مكونات خادم وكيل يتم تشغيلها في عملية المستخدم ثم الوصول إلى المكون singleUser في المستخدم 0.
  5. يمكن إجراء طلبات بحث عن المستخدمين وأسماءهم المعرِّفة باستخدام خدمة النظام الجديدة "UserManager":
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle): رقم غير مُعاد تدويره ويتوافق مع الاسم المعرِّف للمستخدم
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() - تعرض مجموعة الملفات الشخصية المُدارة ذاتيًا، إن توفّرت.
  6. سجِّل للاستماع إلى مستخدمين محدّدين أو جميعهم، بالإضافة إلى طلبات معاودة الاتصال باستخدام واجهات برمجة التطبيقات الجديدة على ContentObserver وPackageMonitor وBroadcastReceiver توفر معلومات عن المستخدم الذي تسبب في معاودة الاتصال.

الخدمات في عدة مستخدمين أو ملفات شخصية

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

// Add on all entry points such as boot_completed or other manifest-listed receivers and providers
if (!UserManager.isSystemUser()) {
    // Disable the service
    ComponentName targetServiceName = new ComponentName(this, TargetService.class);
    context.getPackageManager().setComponentEnabledSetting(
        targetServiceName, COMPONENT_ENABLED_STATE_DISABLED, 0);
}

يمكن أن يستخدم المثال أيضًا PackageManager.setApplicationEnabledSetting() لإيقاف للتطبيق بالكامل.