การสร้างแอปที่รับรู้ถึงผู้ใช้หลายคน

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

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

สิ่งอำนวยความสะดวกนี้:

  • อนุรักษ์ทรัพยากร
  • อนุญาโตตุลาการทรัพยากรที่ใช้ร่วมกันอย่างน้อยหนึ่งรายการระหว่างผู้ใช้
  • ลดค่าใช้จ่ายของเครือข่ายโดยใช้การเชื่อมต่อเซิร์ฟเวอร์เดียว

ดูแผนภาพด้านล่างเพื่อดูภาพขั้นตอนการอนุญาตกับผู้ใช้หลายราย

การไหลของสิทธิ์ผู้ใช้หลายคน

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

การเปิดใช้งานองค์ประกอบเดี่ยว

หากต้องการระบุแอปเป็นซิงเกิลตัน ให้เพิ่ม 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 ใหม่ที่ได้รับการป้องกันเพื่อเริ่มบริการ กิจกรรม การออกอากาศกับผู้ใช้เฉพาะ:
    • 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. ลงทะเบียนเพื่อฟังผู้ใช้ที่ระบุหรือทั้งหมดและการเรียกกลับด้วย 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() เพื่อปิดใช้งานแอปทั้งหมด