การสร้างแอปแบบ Multi-Aware

เมื่ออุปกรณ์รองรับผู้ใช้หลายคน แอปของอุปกรณ์นั้นจะต้อง ในการรับรู้ถึงผู้ใช้ที่แตกต่างกันเหล่านี้

แอปบางแอปต้องมีคอมโพเนนต์บางอย่างที่ทำงานเป็นซิงเกิลตันและยอมรับได้ คำขอจากผู้ใช้ ขณะนี้มีเพียงแอประบบเท่านั้นที่ใช้ฟีเจอร์นี้ได้

สถานประกอบการนี้:

  • ประหยัดทรัพยากร
  • กำหนดทรัพยากรที่แชร์อย่างน้อย 1 รายการระหว่างผู้ใช้
  • ลดโอเวอร์เฮดของเครือข่ายโดยใช้การเชื่อมต่อเซิร์ฟเวอร์ครั้งเดียว

ดูแผนภาพด้านล่างที่แสดงขั้นตอนการให้สิทธิ์สำหรับผู้ใช้หลายคน

ขั้นตอนการให้สิทธิ์สำหรับผู้ใช้หลายคน

รูปที่ 1 สิทธิ์สำหรับผู้ใช้หลายคน

การเปิดใช้คอมโพเนนต์เดี่ยว

หากต้องการระบุว่าแอปใดเป็นรายการเดียว ให้เพิ่ม android:singleUser="true" ลงในบริการของคุณ ผู้รับหรือผู้ให้บริการในไฟล์ Manifest ของ Android

ระบบจะสร้างอินสแตนซ์คอมโพเนนต์นั้นในกระบวนการที่ทำงานในฐานะผู้ใช้ 0 เท่านั้น คำขอใดๆ เพื่อเชื่อมต่อกับผู้ให้บริการหรือบริการนั้น หรือประกาศไปยังผู้รับรายนั้น ผู้ใช้ทุกคนจะถูกกำหนดเส้นทางไปยังกระบวนการใน ผู้ใช้ 0 หากนี่เป็นคอมโพเนนต์เดียวในแอป จะมีการเรียกใช้แอปเพียง 1 อินสแตนซ์เท่านั้น

กิจกรรมในแพ็กเกจของคุณจะยังคงเปิดตัวในกระบวนการที่แยกต่างหากสำหรับ ผู้ใช้แต่ละราย โดยมี UID อยู่ในช่วง UID ของผู้ใช้รายนั้น (เช่น 1010034)

การโต้ตอบกับผู้ใช้

ตั้งค่าสิทธิ์

ต้องใช้สิทธิ์เหล่านี้

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

API ของการใช้งาน

ใช้ API ต่อไปนี้เพื่อทำให้แอปรู้จักผู้ใช้หลายคน

  1. ดึงข้อมูลแฮนเดิลผู้ใช้จากสาย Binder ที่เข้ามาใหม่
    • int userHandle = UserHandle.getCallingUserId()
  2. ใช้ API ใหม่ที่ได้รับการปกป้องเพื่อเริ่มบริการ กิจกรรม และการออกอากาศ ผู้ใช้:
    • 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. ลงทะเบียนเพื่อฟังผู้ใช้ที่ระบุหรือทั้งหมดและ 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() เพื่อปิดใช้ได้ด้วย ทั้งแอป