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

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

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

هذه المنشأة:

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

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

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

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

تمكين مكون مفرد

لتعريف أحد التطبيقات باعتباره تطبيقًا فرديًا، أضف android:singleUser="true" إلى الخدمة أو جهاز الاستقبال أو المزود في بيان Android.

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

سيستمر إطلاق الأنشطة الموجودة في الحزمة الخاصة بك في عملية منفصلة لكل مستخدم، مع وجود UID في نطاق UID لهذا المستخدم (مثل 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() لتعطيل التطبيق بأكمله.