เมื่ออุปกรณ์รองรับผู้ใช้หลายคน แอปของอุปกรณ์จะต้องรับรู้ถึงผู้ใช้ที่แตกต่างกันเหล่านี้
แอปบางแอปจำเป็นต้องมีคอมโพเนนต์บางอย่างที่ทำงานแบบ Singleton และยอมรับคำขอจากผู้ใช้ทุกคนได้ ปัจจุบันมีเพียงแอประบบเท่านั้นที่ใช้ฟีเจอร์นี้ได้
สิ่งอำนวยความสะดวกนี้
- ประหยัดทรัพยากร
- ระงับทรัพยากรที่แชร์อย่างน้อย 1 รายการในหมู่ผู้ใช้
- ลดค่าใช้จ่ายเพิ่มเติมของเครือข่ายโดยใช้การเชื่อมต่อเซิร์ฟเวอร์เดียว
ดูภาพแผนภาพด้านล่างเพื่อดูภาพขั้นตอนของสิทธิ์ที่มีผู้ใช้หลายคน
รูปที่ 1 สิทธิ์ของผู้ใช้หลายคน
เปิดใช้คอมโพเนนต์แบบ Singleton
หากต้องการระบุว่าแอปเป็นแบบ Singleton ให้เพิ่ม android:singleUser="true"
ลงในบริการ ผู้รับ หรือผู้ให้บริการในไฟล์ Manifest ของ Android
ระบบจะสร้างอินสแตนซ์ของคอมโพเนนต์นั้นในกระบวนการที่ทำงานในฐานะผู้ใช้ 0 เท่านั้น คำขอเชื่อมต่อกับผู้ให้บริการหรือบริการนั้น หรือเพื่อออกอากาศไปยังผู้รับนั้นจากผู้ใช้รายใดก็ตามจะส่งไปยังกระบวนการในผู้ใช้ 0 หากคอมโพเนนต์นี้เป็นคอมโพเนนต์เดียวในแอป แอปจะทํางานเพียงอินสแตนซ์เดียว
กิจกรรมในแพ็กเกจจะยังคงเปิดขึ้นในกระบวนการแยกต่างหากสําหรับผู้ใช้แต่ละราย โดยมี UID อยู่ในช่วง UID ของผู้ใช้รายนั้น (เช่น 1010034)
โต้ตอบกับผู้ใช้
ตั้งค่าสิทธิ์
ต้องมีสิทธิ์ต่อไปนี้
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
ใช้ API
ใช้ API ต่อไปนี้เพื่อให้แอปรับรู้ผู้ใช้หลายคน
- ดึงข้อมูลแฮนเดิลผู้ใช้จากการเรียก Binder ที่เข้ามา
int userHandle = UserHandle.getCallingUserId()
- ใช้ Protected API ใหม่เพื่อเริ่มบริการ กิจกรรม การออกอากาศในผู้ใช้ที่เฉพาะเจาะจง โดยทำดังนี้
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
อาจเป็นผู้ใช้ที่ระบุชื่อจริงหรือแฮนเดิลพิเศษอย่างใดอย่างหนึ่งต่อไปนี้UserHandle.CURRENT
หรือUserHandle.ALL
CURRENT
บ่งบอกผู้ใช้ที่แสดงอยู่เบื้องหน้า ใช้ALL
เมื่อคุณต้องการส่งการออกอากาศไปยังผู้ใช้ทุกคน - สื่อสารกับคอมโพเนนต์ในแอปของคุณเอง โดยทำดังนี้
(INTERACT_ACROSS_USERS)
หรือกับคอมโพเนนต์ในแอปอื่นๆ โดยทำดังนี้(INTERACT_ACROSS_USERS_FULL)
- คุณอาจต้องสร้างคอมโพเนนต์พร็อกซีที่ทำงานในกระบวนการของผู้ใช้ จากนั้นจึงเข้าถึงคอมโพเนนต์
singleUser
ในผู้ใช้ 0 - ค้นหาผู้ใช้และแฮนเดิลของผู้ใช้ด้วยบริการของระบบ
UserManager
ใหม่ ดังนี้UserManager.getUsers()
UserManager.getUserInfo()
UserManager.supportsMultipleUsers()
UserManager.getUserSerialNumber(int userHandle)
- ตัวเลขที่ไม่รีไซเคิลซึ่งสอดคล้องกับแฮนเดิลของผู้ใช้UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
- แสดงรายการโปรไฟล์ของคุณเองและโปรไฟล์ที่มีการจัดการ (หากมี)
- ลงทะเบียนเพื่อฟังผู้ใช้บางรายหรือทั้งหมดและระบบเรียกกลับด้วย 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()
เพื่อปิดใช้ทั้งแอปได้ด้วย