פיתוח אפליקציות עם תמיכה בריבוי משתמשים

כשבמכשיר יש תמיכה במספר משתמשים, האפליקציות שלו צריכות להיות מודעות למשתמשים הייחודיים האלה.

באפליקציות מסוימות צריך שרכיבים מסוימים יפעלו כטונים בודדים ויכולים לקבל אותן בקשות מכל משתמש. כרגע רק אפליקציות מערכת יכולות להשתמש בתכונה הזו.

המתקן הזה:

  • משמרת משאבים
  • משמש כבורר של משאב אחד או יותר המשותפים בין משתמשים
  • מפחית את תקורת הרשת על ידי שימוש בחיבור שרת יחיד

בתרשים הבא מוצגת זרימה של הרשאות בין מספר משתמשים.

תהליך ההרשאה של משתמשים מרובים

איור 1. הרשאות של משתמשים מרובים

הפעלת רכיב יחידton

כדי לזהות אפליקציה כיחיד, צריך להוסיף את android:singleUser="true" לשירות, המקבל או הספק במניפסט של Android.

המערכת תיצור את הרכיב הזה בתהליך שפועל כמשתמש 0 בלבד. בקשות כלשהן להתחבר לספק או לשירות הזה, או לשדר לאותו משדר, כל משתמש ינותב לתהליך במשתמש 0. אם זה הרכיב היחיד באפליקציה, רק מופע אחד של האפליקציה יפעל.

הפעילויות בחבילה שלך עדיין יושקו בתהליך נפרד עבור כל משתמש, כשה-UID נמצא בטווח ה-UID של אותו משתמש (למשל 1010034).

אינטראקציה עם משתמשים

הגדר הרשאות

ההרשאות האלה נדרשות

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

שימוש בממשקי API

תוכלו להשתמש בממשקי ה-API הבאים כדי לעורר מודעות לאפליקציות למשתמשים מרובים.

  1. חילוץ הכינוי של המשתמש משיחות נכנסות של Binder:
    • int userHandle = UserHandle.getCallingUserId()
  2. להשתמש בממשקי API חדשים ומוגנים כדי להפעיל שירותים, פעילויות ושידורים user:
    • 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. יכול להיות שתצטרכו ליצור רכיבי proxy שרצים בתהליך המשתמש, לאחר מכן נכנסים לרכיב singleUser במשתמש 0.
  5. שליחת שאילתות למשתמשים ולכינויים שלהם באמצעות שירות המערכת החדש של UserManager:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle) – מספר לא ממוחזר שתואם לכינוי של המשתמש.
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() - החזרת האוסף של הפרופילים העצמיים והמנוהלים, אם יש.
  6. הרשמה לצורך האזנה למשתמשים ספציפיים או לכולם ולקריאות החוזרות (callback) של ממשקי API חדשים מופעלים 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() כדי להשבית את כל האפליקציה.