จัดการผู้ใช้หลายคน

คู่มือสำหรับนักพัฒนาซอฟต์แวร์นี้อธิบายวิธีที่เครื่องมือควบคุมนโยบายด้านอุปกรณ์ (DPC) จัดการผู้ใช้ Android หลายคนบนอุปกรณ์เฉพาะ

ภาพรวม

DPC ของคุณช่วยให้ผู้ใช้หลายคนแชร์อุปกรณ์ที่ใช้เพื่อวัตถุประสงค์เฉพาะเครื่องเดียวได้ DPC ของคุณ ที่ทำงานในอุปกรณ์ที่มีการจัดการครบวงจรสามารถสร้างและจัดการผู้ใช้ 2 ประเภทต่อไปนี้

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

ใช้ DPC ที่มีอยู่เพื่อจัดการอุปกรณ์เฉพาะและ DPC รอง ผู้ใช้ คอมโพเนนต์ผู้ดูแลระบบใน DPC จะตั้งตัวเองเป็นผู้ดูแลระบบสำหรับทีมรองใหม่ ผู้ใช้ที่คุณสร้าง

วันที่ ผู้ใช้หลักและผู้ใช้รอง 2 ราย
รูปที่ 1 ผู้ใช้หลักและรองที่จัดการโดยผู้ดูแลระบบจาก DPC เดิม

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

ตามปกติแล้ว การจัดการผู้ใช้หลายคนบนอุปกรณ์เฉพาะจำเป็นต้องใช้ Android 9.0 อย่างไรก็ตาม บางวิธีการที่ใช้ในคู่มือสำหรับนักพัฒนาซอฟต์แวร์นี้มีอยู่ใน Android เวอร์ชันก่อนหน้า

ผู้ใช้รอง

ผู้ใช้รองจะเชื่อมต่อ Wi-Fi และกำหนดค่าเครือข่ายใหม่ได้ อย่างไรก็ตาม ไม่สามารถแก้ไขหรือลบเครือข่าย แม้แต่เครือข่ายที่บุคคลดังกล่าวสร้างขึ้น

สร้างผู้ใช้

DPC สามารถสร้างผู้ใช้เพิ่มเติมในเบื้องหลังและจากนั้นจึงเปลี่ยนผู้ใช้ได้ มาเบื้องหน้า ขั้นตอนเกือบเหมือนกันสำหรับทั้งบัญชีรองและ ผู้ใช้ชั่วคราว โปรดทำตามขั้นตอนต่อไปนี้ในผู้ดูแลระบบของ อุปกรณ์ที่มีการจัดการและผู้ใช้รอง:

  1. โทร DevicePolicyManager.createAndManageUser() ในการสร้างผู้ใช้ชั่วคราว ให้ใส่ MAKE_USER_EPHEMERAL ในอาร์กิวเมนต์ Flag
  2. โทร DevicePolicyManager.startUserInBackground() ถึง ให้ผู้ใช้ทำงานในเบื้องหลัง ผู้ใช้เริ่มวิ่งแล้ว แต่คุณจะต้อง เพื่อตั้งค่าให้เสร็จสิ้นก่อนนำผู้ใช้ไปยังเบื้องหน้า และแสดงให้ ผู้ที่กำลังใช้อุปกรณ์อยู่
  3. ในผู้ดูแลระบบของผู้ใช้รอง ให้โทร DevicePolicyManager.setAffiliationIds() ถึง เชื่อมโยงผู้ใช้ใหม่กับผู้ใช้หลัก โปรดดู การประสานงาน DPC ด้านล่าง
  4. กลับไปที่ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจร DevicePolicyManager.switchUser() เพื่อสลับผู้ใช้ เบื้องหน้า

ตัวอย่างต่อไปนี้แสดงวิธีเพิ่มขั้นตอนที่ 1 ลงใน DPC

Kotlin

val dpm = getContext().getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager

// If possible, reuse an existing affiliation ID across the
// primary user and (later) the ephemeral user.
val identifiers = dpm.getAffiliationIds(adminName)
if (identifiers.isEmpty()) {
    identifiers.add(UUID.randomUUID().toString())
    dpm.setAffiliationIds(adminName, identifiers)
}

// Pass an affiliation ID to the ephemeral user in the admin extras.
val adminExtras = PersistableBundle()
adminExtras.putString(AFFILIATION_ID_KEY, identifiers.first())
// Include any other config for the new user here ...

// Create the ephemeral user, using this component as the admin.
try {
    val ephemeralUser = dpm.createAndManageUser(
            adminName,
            "tmp_user",
            adminName,
            adminExtras,
            DevicePolicyManager.MAKE_USER_EPHEMERAL or
                    DevicePolicyManager.SKIP_SETUP_WIZARD)

} catch (e: UserManager.UserOperationException) {
    if (e.userOperationResult ==
            UserManager.USER_OPERATION_ERROR_MAX_USERS) {
        // Find a way to free up users...
    }
}

Java

DevicePolicyManager dpm = (DevicePolicyManager)
    getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);

// If possible, reuse an existing affiliation ID across the
// primary user and (later) the ephemeral user.
Set<String> identifiers = dpm.getAffiliationIds(adminName);
if (identifiers.isEmpty()) {
  identifiers.add(UUID.randomUUID().toString());
  dpm.setAffiliationIds(adminName, identifiers);
}

// Pass an affiliation ID to the ephemeral user in the admin extras.
PersistableBundle adminExtras = new PersistableBundle();
adminExtras.putString(AFFILIATION_ID_KEY, identifiers.iterator().next());
// Include any other config for the new user here ...

// Create the ephemeral user, using this component as the admin.
try {
  UserHandle ephemeralUser = dpm.createAndManageUser(
      adminName,
      "tmp_user",
      adminName,
      adminExtras,
      DevicePolicyManager.MAKE_USER_EPHEMERAL |
          DevicePolicyManager.SKIP_SETUP_WIZARD);

} catch (UserManager.UserOperationException e) {
  if (e.getUserOperationResult() ==
      UserManager.USER_OPERATION_ERROR_MAX_USERS) {
    // Find a way to free up users...
  }
}

เมื่อสร้างหรือเริ่มผู้ใช้ใหม่ คุณสามารถตรวจสอบสาเหตุของการทำงานล้มเหลว โดยตรวจจับข้อยกเว้น UserOperationException และโทร getUserOperationResult() เกินจำนวนผู้ใช้ ขีดจำกัดคือสาเหตุของความล้มเหลวที่พบได้บ่อย:

การสร้างผู้ใช้อาจใช้เวลาสักครู่ หากสร้างผู้ใช้บ่อยครั้ง คุณจะทำสิ่งต่อไปนี้ได้ ปรับปรุงประสบการณ์ของผู้ใช้ด้วยการเตรียมผู้ใช้ที่พร้อมใช้งานไว้ในเบื้องหลัง คุณอาจต้องสร้างสมดุลระหว่างข้อดีของผู้ใช้ที่พร้อมใช้งานกับ จำนวนผู้ใช้ที่อนุญาตในอุปกรณ์

กาแสดงตัวตน

หลังจากสร้างผู้ใช้ใหม่ คุณควรอ้างอิงผู้ใช้ด้วยหมายเลขซีเรียลแบบคงที่ หมายเลข ไม่เก็บ UserHandle เนื่องจากระบบจะรีไซเคิลรายการเหล่านี้ตามคุณ สร้างและลบผู้ใช้ ขอหมายเลขซีเรียลโดยการโทร UserManager.getSerialNumberForUser():

Kotlin

// After calling createAndManageUser() use a device-unique serial number
// (that isn’t recycled) to identify the new user.
secondaryUser?.let {
    val userManager = getContext().getSystemService(UserManager::class.java)
    val ephemeralUserId = userManager!!.getSerialNumberForUser(it)
    // Save the serial number to storage  ...
}

Java

// After calling createAndManageUser() use a device-unique serial number
// (that isn’t recycled) to identify the new user.
if (secondaryUser != null) {
  UserManager userManager = getContext().getSystemService(UserManager.class);
  long ephemeralUserId = userManager.getSerialNumberForUser(secondaryUser);
  // Save the serial number to storage  ...
}

การกำหนดค่าผู้ใช้

คุณสามารถกำหนดการตั้งค่าการตั้งค่ารองได้ โดยขึ้นอยู่กับความต้องการของผู้ใช้ ผู้ใช้ คุณรวมการแจ้งต่อไปนี้เมื่อเรียกใช้ createAndManageUser() ได้

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

ติดตามวงจรของผู้ใช้

DPC ของคุณ (หากเป็นผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจร) อาจมีประโยชน์ดังนี้ จะทราบเมื่อผู้ใช้รองเปลี่ยน หากต้องการเรียกใช้งานที่ตามมาหลังจากมีการเปลี่ยนแปลง ให้ลบล้าง เมธอด Callback ต่อไปนี้ในคลาสย่อย DeviceAdminReceiver ของ DPC

onUserStarted()
เรียกใช้หลังจากที่ระบบเริ่มใช้งานผู้ใช้ ผู้ใช้รายนี้อาจกำลังตั้งค่าหรือ ทำงานในเบื้องหลัง คุณจะรับผู้ใช้ได้จากstartedUser อาร์กิวเมนต์
onUserSwitched()
เรียกใช้หลังจากที่ระบบเปลี่ยนเป็นผู้ใช้รายอื่น คุณจะได้รับผู้ใช้ใหม่ ซึ่งกำลังทำงานอยู่ในเบื้องหน้าจากอาร์กิวเมนต์ switchedUser
onUserStopped()
เรียกใช้หลังจากที่ระบบหยุดผู้ใช้เนื่องจากผู้ใช้ออกจากระบบ เปลี่ยนไปใช้ ผู้ใช้ใหม่ (หากผู้ใช้ชั่วคราว) หรือ DPC ของคุณหยุดผู้ใช้ คุณสามารถ ผู้ใช้จากอาร์กิวเมนต์ stoppedUser
onUserAdded()
เรียกใช้เมื่อระบบเพิ่มผู้ใช้ใหม่ โดยปกติแล้ว ผู้ใช้รองจะไม่ ตั้งค่าอย่างสมบูรณ์เมื่อ DPC ได้รับการติดต่อกลับ คุณสามารถรับผู้ใช้จาก newUser
onUserRemoved()
เรียกใช้หลังจากที่ระบบลบผู้ใช้ เนื่องจากระบบได้ลบผู้ใช้ไปแล้ว คุณจะเข้าถึงผู้ใช้ที่ระบุด้วยอาร์กิวเมนต์ removedUser ไม่ได้

เพื่อให้ทราบเมื่อระบบนําผู้ใช้ไปยังเบื้องหน้าหรือส่งผู้ใช้ไปยัง แอปก็สามารถลงทะเบียนผู้รับสำหรับ ACTION_USER_FOREGROUND และ การออกอากาศ ACTION_USER_BACKGROUND

สำรวจผู้ใช้

หากต้องการรับผู้ใช้รองทั้งหมด ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรสามารถโทรหา DevicePolicyManager.getSecondaryUsers() ผลลัพธ์ รวมถึงผู้ใช้รองหรือผู้ใช้ชั่วคราวที่ผู้ดูแลระบบสร้างขึ้น และผลลัพธ์ก็ รวมถึงผู้ใช้รอง (หรือผู้ใช้ชั่วคราว) ผู้ที่ใช้อุปกรณ์ ที่สร้าง ผลการค้นหาไม่มีโปรไฟล์งานเพราะไม่มีโปรไฟล์งาน ผู้ใช้รอง ตัวอย่างต่อไปนี้แสดงวิธีการใช้งานดังกล่าว

Kotlin

// The device is stored for the night. Stop all running secondary users.
dpm.getSecondaryUsers(adminName).forEach {
    dpm.stopUser(adminName, it)
}

Java

// The device is stored for the night. Stop all running secondary users.
for (UserHandle user : dpm.getSecondaryUsers(adminName)) {
  dpm.stopUser(adminName, user);
}

วิธีอื่นๆ ที่คุณสามารถโทรหาเพื่อสอบถามสถานะของผู้ใช้รองได้มีดังนี้

DevicePolicyManager.isEphemeralUser()
เรียกใช้วิธีการนี้จากผู้ดูแลระบบของผู้ใช้รองเพื่อดูว่าเป็น ผู้ใช้ชั่วคราว
DevicePolicyManager.isAffiliatedUser()
เรียกใช้วิธีการนี้จากผู้ดูแลระบบของผู้ใช้รองเพื่อดูว่าผู้ใช้รายนี้เป็น มีความเกี่ยวข้องกับผู้ใช้หลัก หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการเชื่อมโยง โปรดดูที่ DPC การประสานงานด้านล่าง

การจัดการผู้ใช้

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

ออกจากระบบ

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

โดยค่าเริ่มต้น Android จะไม่แสดงปุ่มสิ้นสุดเซสชัน แต่จะแสดงให้ผู้ดูแลระบบ (ของ อุปกรณ์ที่มีการจัดการครบวงจร) จะเปิดใช้ได้ด้วยการโทร DevicePolicyManager.setLogoutEnabled() หากคุณจำเป็นต้องทำดังนี้ ยืนยันสถานะปัจจุบันของปุ่ม โทร DevicePolicyManager.isLogoutEnabled()

ผู้ดูแลระบบของผู้ใช้รองสามารถนำผู้ใช้ออกจากระบบและกลับเข้ามาใช้งานได้ทางโปรแกรม ให้แก่ผู้ใช้หลัก ขั้นแรก ตรวจสอบผู้ใช้รองและผู้ใช้หลัก แอฟฟิลิเอตแล้วโทร DevicePolicyManager.logoutUser() ถ้า ผู้ใช้ที่ออกจากระบบเป็นผู้ใช้ชั่วคราว ระบบจะหยุดและลบบัญชี ผู้ใช้

เปลี่ยนผู้ใช้

หากต้องการสลับไปยังผู้ใช้รองรายอื่น ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรสามารถ โทรหา DevicePolicyManager.switchUser() เพื่อความสะดวก คุณ สามารถส่ง null เพื่อเปลี่ยนเป็นผู้ใช้หลักได้

หยุดผู้ใช้

หากต้องการหยุดผู้ใช้รอง DPC ซึ่งเป็นเจ้าของอุปกรณ์ที่มีการจัดการครบวงจรจะเรียกใช้ DevicePolicyManager.stopUser() หากผู้ใช้ที่หยุดเป็นผู้ใช้ ผู้ใช้ชั่วคราว ผู้ใช้จะถูกหยุดและถูกลบออก

เราแนะนำให้หยุดไม่ให้ผู้ใช้ใช้งานเมื่อใดก็ตามที่เป็นไปได้เพื่อช่วยให้อุปกรณ์อยู่ต่ำกว่า จำนวนผู้ใช้สูงสุดที่ใช้งานอยู่

ลบผู้ใช้

หากต้องการลบผู้ใช้รองที่ DPC สามารถเรียกใช้รายการใดรายการหนึ่งต่อไปนี้อย่างถาวร DevicePolicyManager วิธี:

  • ผู้ดูแลระบบอุปกรณ์ที่มีการจัดการครบวงจรจะโทรหา removeUser() ได้
  • ผู้ดูแลระบบของผู้ใช้รองสามารถโทรหา wipeData() ได้

ระบบจะลบผู้ใช้ชั่วคราวเมื่อผู้ใช้ออกจากระบบ หยุดการทำงาน หรือสลับผู้ใช้ ที่อยู่ไกลออกไป

ปิดใช้ UI เริ่มต้น

หาก DPC มี UI สำหรับจัดการผู้ใช้ คุณจะปิดใช้ Android ในตัวได้ ที่มีผู้ใช้หลายคน โดยโทร DevicePolicyManager.setLogoutEnabled() และเพิ่ม ข้อจำกัด DISALLOW_USER_SWITCH ตามที่แสดงใน ตัวอย่างต่อไปนี้

Kotlin

// Explicitly disallow logging out using Android UI (disabled by default).
dpm.setLogoutEnabled(adminName, false)

// Disallow switching users in Android's UI. This DPC can still
// call switchUser() to manage users.
dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH)

Java

// Explicitly disallow logging out using Android UI (disabled by default).
dpm.setLogoutEnabled(adminName, false);

// Disallow switching users in Android's UI. This DPC can still
// call switchUser() to manage users.
dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH);

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

ข้อความของเซสชัน

เมื่อผู้ที่ใช้อุปกรณ์เปลี่ยนเป็นผู้ใช้ใหม่ Android จะแสดงแผงเพื่อ ไฮไลต์สวิตช์ Android จะแสดงข้อความต่อไปนี้

  • ข้อความเริ่มต้นเซสชันของผู้ใช้ที่แสดงเมื่ออุปกรณ์เปลี่ยนไปใช้ ผู้ใช้จากผู้ใช้หลัก
  • ข้อความเซสชันของผู้ใช้ปลายทางที่แสดงเมื่ออุปกรณ์กลับไปยังผู้ใช้หลัก จากผู้ใช้รอง

ระบบจะไม่แสดงข้อความเมื่อสลับระหว่างผู้ใช้รอง 2 ราย

และเนื่องจากข้อความอาจไม่เหมาะกับบางสถานการณ์ คุณจึงสามารถเปลี่ยน ข้อความในข้อความดังกล่าว เช่น หากโซลูชันของคุณใช้ผู้ใช้ชั่วคราว เซสชัน คุณสามารถดูข้อมูลนี้ในข้อความ เช่น การหยุดเบราว์เซอร์ เซสชันและ กำลังลบข้อมูลส่วนตัว...

ระบบจะแสดงข้อความเพียงไม่กี่วินาที เพื่อให้แต่ละข้อความ ควรเป็นวลีที่สั้นและชัดเจน หากต้องการปรับแต่งข้อความ ผู้ดูแลระบบสามารถโทรหา เมธอด DevicePolicyManager setStartUserSessionMessage() และ setEndUserSessionMessage() ดังที่แสดงใน ตัวอย่างต่อไปนี้

Kotlin

// Short, easy-to-read messages shown at the start and end of a session.
// In your app, store these strings in a localizable resource.
internal val START_USER_SESSION_MESSAGE = "Starting guest session…"
internal val END_USER_SESSION_MESSAGE = "Stopping & clearing data…"

// ...
dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE)
dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE)

Java

// Short, easy-to-read messages shown at the start and end of a session.
// In your app, store these strings in a localizable resource.
private static final String START_USER_SESSION_MESSAGE = "Starting guest session…";
private static final String END_USER_SESSION_MESSAGE = "Stopping & clearing data…";

// ...
dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE);
dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE);

ส่ง null เพื่อลบข้อความที่กำหนดเองและกลับสู่ค่าเริ่มต้นของ Android ข้อความ หากคุณต้องการตรวจสอบข้อความปัจจุบัน โปรดโทร getStartUserSessionMessage() หรือ getEndUserSessionMessage()

DPC ของคุณควรตั้งค่าข้อความที่แปลแล้ว สำหรับภาษาปัจจุบันของผู้ใช้ นอกจากนี้ คุณยังต้องอัปเดตข้อความเมื่อ การเปลี่ยนภาษาของผู้ใช้:

Kotlin

override fun onReceive(context: Context?, intent: Intent?) {
    // Added the <action android:name="android.intent.action.LOCALE_CHANGED" />
    // intent filter for our DeviceAdminReceiver subclass in the app manifest file.
    if (intent?.action === ACTION_LOCALE_CHANGED) {

        // Android's resources return a string suitable for the new locale.
        getManager(context).setStartUserSessionMessage(
                getWho(context),
                context?.getString(R.string.start_user_session_message))

        getManager(context).setEndUserSessionMessage(
                getWho(context),
                context?.getString(R.string.end_user_session_message))
    }
    super.onReceive(context, intent)
}

Java

public void onReceive(Context context, Intent intent) {
  // Added the <action android:name="android.intent.action.LOCALE_CHANGED" />
  // intent filter for our DeviceAdminReceiver subclass in the app manifest file.
  if (intent.getAction().equals(ACTION_LOCALE_CHANGED)) {

    // Android's resources return a string suitable for the new locale.
    getManager(context).setStartUserSessionMessage(
        getWho(context),
        context.getString(R.string.start_user_session_message));

    getManager(context).setEndUserSessionMessage(
        getWho(context),
        context.getString(R.string.end_user_session_message));
  }
  super.onReceive(context, intent);
}

การประสานงานของ DPC

การจัดการผู้ใช้รองมักจะต้องใช้ DPC 2 อินสแตนซ์ โดยรายการหนึ่งเป็นเจ้าของ อุปกรณ์ที่มีการจัดการครบวงจรในขณะที่อีกเครื่องเป็นเจ้าของผู้ใช้รอง เมื่อสร้าง ผู้ใช้ใหม่ ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรจะตั้งค่าอีกอินสแตนซ์หนึ่งของ ในฐานะผู้ดูแลระบบของผู้ใช้ใหม่

ผู้ใช้ที่เชื่อมโยง

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

ตั้งค่า

ตั้งค่าผู้ใช้รองใหม่ (จาก DPC ที่เป็นเจ้าของผู้ใช้รอง) ก่อน ให้ผู้คนได้ใช้ คุณสามารถตั้งค่านี้ได้จาก DeviceAdminReceiver.onEnabled() ติดต่อกลับ หากก่อนหน้านี้ ตั้งค่าบริการเสริมสำหรับผู้ดูแลระบบในการโทรไปยัง createAndManageUser() คุณจะสามารถ ค่าจากอาร์กิวเมนต์ intent ตัวอย่างต่อไปนี้แสดง DPC ที่สัมพันธ์กัน ผู้ใช้รองใหม่ใน Callback

Kotlin

override fun onEnabled(context: Context?, intent: Intent?) {
    super.onEnabled(context, intent)

    // Get the affiliation ID (our DPC previously put in the extras) and
    // set the ID for this new secondary user.
    intent?.getStringExtra(AFFILIATION_ID_KEY)?.let {
        val dpm = getManager(context)
        dpm.setAffiliationIds(getWho(context), setOf(it))
    }
    // Continue setup of the new secondary user ...
}

Java

public void onEnabled(Context context, Intent intent) {
  // Get the affiliation ID (our DPC previously put in the extras) and
  // set the ID for this new secondary user.
  String affiliationId = intent.getStringExtra(AFFILIATION_ID_KEY);
  if (affiliationId != null) {
    DevicePolicyManager dpm = getManager(context);
    dpm.setAffiliationIds(getWho(context),
        new HashSet<String>(Arrays.asList(affiliationId)));
  }
  // Continue setup of the new secondary user ...
}

RPC ระหว่าง DPC

แม้ว่าอินสแตนซ์ DPC 2 รายการจะทำงานภายใต้ผู้ใช้ที่แยกกัน แต่ DPC ที่เป็นเจ้าของอุปกรณ์ และผู้ใช้รองสามารถสื่อสารกันได้ เนื่องจากการเรียกใช้บริการของ DPC อื่นข้ามขอบเขตผู้ใช้ DPC จึงไม่สามารถ โทรหา bindService() แบบที่คุณ มักจะอยู่ใน Android วิธีเชื่อมโยงกับบริการที่กำลังทำงานใน ผู้ใช้รายอื่น โทร DevicePolicyManager.bindDeviceAdminServiceAsUser()

วันที่ ผู้ใช้หลักและผู้ใช้รองที่เชื่อมโยง 2 รายซึ่งเรียกใช้ RPC
รูปที่ 2 ผู้ดูแลระบบของผู้ใช้หลักและรองที่เชื่อมโยง วิธีการใช้บริการโทรศัพท์

DPC ของคุณสามารถเชื่อมโยงกับบริการที่เรียกใช้ในกลุ่มผู้ใช้ที่ส่งคืนโดย DevicePolicyManager.getBindDeviceAdminTargetUsers() ตัวอย่างต่อไปนี้แสดงผู้ดูแลระบบของการเชื่อมโยงผู้ใช้รองกับผู้ดูแลระบบ ของอุปกรณ์ที่มีการจัดการครบวงจรอย่าง

Kotlin

// From a secondary user, the list contains just the primary user.
dpm.getBindDeviceAdminTargetUsers(adminName).forEach {

    // Set up the callbacks for the service connection.
    val intent = Intent(mContext, FullyManagedDeviceService::class.java)
    val serviceconnection = object : ServiceConnection {
        override fun onServiceConnected(componentName: ComponentName,
                                        iBinder: IBinder) {
            // Call methods on service ...
        }
        override fun onServiceDisconnected(componentName: ComponentName) {
            // Clean up or reconnect if needed ...
        }
    }

    // Bind to the service as the primary user [it].
    val bindSuccessful = dpm.bindDeviceAdminServiceAsUser(adminName,
            intent,
            serviceconnection,
            Context.BIND_AUTO_CREATE,
            it)
}

Java

// From a secondary user, the list contains just the primary user.
List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(adminName);
if (targetUsers.isEmpty()) {
  // If the users aren't affiliated, the list doesn't contain any users.
  return;
}

// Set up the callbacks for the service connection.
Intent intent = new Intent(mContext, FullyManagedDeviceService.class);
ServiceConnection serviceconnection = new ServiceConnection() {
  @Override
  public void onServiceConnected(
      ComponentName componentName, IBinder iBinder) {
    // Call methods on service ...
  }

  @Override
  public void onServiceDisconnected(ComponentName componentName) {
    // Clean up or reconnect if needed ...
  }
};

// Bind to the service as the primary user.
UserHandle primaryUser = targetUsers.get(0);
boolean bindSuccessful = dpm.bindDeviceAdminServiceAsUser(
    adminName,
    intent,
    serviceconnection,
    Context.BIND_AUTO_CREATE,
    primaryUser);

แหล่งข้อมูลเพิ่มเติม

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับอุปกรณ์เฉพาะ โปรดอ่านเอกสารต่อไปนี้