โหมดล็อกงาน

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

ภาพรวม

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

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

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

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

ความพร้อมใช้งาน

ระบบสามารถทำงานในโหมดล็อกงานใน Android 5.0 ขึ้นไป ตาราง 1 แสดง Android เวอร์ชันใดรองรับการเพิ่มแอปในรายการที่อนุญาตตามผู้ใช้

ตาราง 1 การรองรับเวอร์ชัน Android สำหรับโหมดผู้ดูแลระบบ DPC
เวอร์ชัน Android ผู้ดูแลระบบ DPC หมายเหตุ
Android 5.0 (API ระดับ 21) ขึ้นไป อุปกรณ์ที่มีการจัดการเต็มรูปแบบ
Android 8.0 (API ระดับ 26) ขึ้นไป ผู้ใช้รองที่เกี่ยวข้อง ผู้ใช้รองต้องเชื่อมโยงกับผู้ใช้หลัก โปรดดู ภาพรวมผู้ใช้หลายคน
Android 9.0 (API ระดับ 28) ขึ้นไป ผู้ใช้รอง

ใน Android 9.0 ขึ้นไป DPC จะเริ่มกิจกรรมของแอปเข้าสู่โหมดล็อกงานได้ ส่วนเวอร์ชันก่อนหน้านั้น แอปต้องรองรับการเริ่มกิจกรรมของตัวเองใน โหมดล็อกงาน

แอปในรายการที่อนุญาต

DPC ต้องอนุญาตแอปก่อนจึงจะใช้ในโหมดงานล็อกได้ โทร DevicePolicyManager.setLockTaskPackages() ถึง อนุญาตแอปสำหรับโหมดงานการล็อกดังที่แสดงในตัวอย่างต่อไปนี้

Kotlin

// Allowlist two apps.
private val KIOSK_PACKAGE = "com.example.kiosk"
private val PLAYER_PACKAGE = "com.example.player"
private val APP_PACKAGES = arrayOf(KIOSK_PACKAGE, PLAYER_PACKAGE)

// ...

val context = context
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
val adminName = getComponentName(context)
dpm.setLockTaskPackages(adminName, APP_PACKAGES)

Java

// Allowlist two apps.
private static final String KIOSK_PACKAGE = "com.example.kiosk";
private static final String PLAYER_PACKAGE = "com.example.player";
private static final String[] APP_PACKAGES = {KIOSK_PACKAGE, PLAYER_PACKAGE};

// ...

Context context = getContext();
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminName = getComponentName(context);
dpm.setLockTaskPackages(adminName, APP_PACKAGES);

หากต้องการค้นหาแอปในรายการที่อนุญาตสําหรับโหมดงานล็อกก่อนหน้านี้ DPC จะเรียกใช้แอปได้ DevicePolicyManager.getLockTaskPackages() อื่นๆ แอปสามารถเรียก DevicePolicyManager.isLockTaskPermitted() เพื่อยืนยัน แพ็กเกจแอปรองรับโหมดงานล็อก

เริ่มโหมดล็อกงาน

ใน Android 9.0 (API ระดับ 28) ขึ้นไป คุณจะเริ่มกิจกรรมของแอปอื่นได้ใน โหมดล็อกงาน หากมีกิจกรรมทำงานอยู่เบื้องหน้าอยู่แล้ว หรือ คุณต้องเปิดกิจกรรมอีกครั้ง โทร ActivityOptions.setLockTaskEnabled() และระบุ ตัวเลือกเมื่อเริ่มต้นกิจกรรม ตัวอย่างต่อไปนี้แสดงวิธีหนึ่งที่คุณสามารถ ทำสิ่งนี้

Kotlin

// Set an option to turn on lock task mode when starting the activity.
val options = ActivityOptions.makeBasic()
options.setLockTaskEnabled(true)

// Start our kiosk app's main activity with our lock task mode option.
val packageManager = context.packageManager
val launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE)
if (launchIntent != null) {
    context.startActivity(launchIntent, options.toBundle())
}

Java

// Set an option to turn on lock task mode when starting the activity.
ActivityOptions options = ActivityOptions.makeBasic();
options.setLockTaskEnabled(true);

// Start our kiosk app's main activity with our lock task mode option.
PackageManager packageManager = context.getPackageManager();
Intent launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE);
if (launchIntent != null) {
  context.startActivity(launchIntent, options.toBundle());
}

ใน Android เวอร์ชันก่อน 9.0 แอปจะเริ่มกิจกรรมของตนเองในงานล็อก โดยโทรหา Activity.startLockTask() หากต้องการเรียกใช้ กิจกรรมจะต้องทำงานอยู่ในเบื้องหน้า (โปรดดูส่วนวงจรกิจกรรม ) เราจึงขอแนะนำให้คุณเรียกใช้ เมธอด onResume() ของ Activity หรือ Fragment วิธีโทรหา startLockTask()

Kotlin

// In our Fragment subclass.
override fun onResume() {
    super.onResume()
    // First, confirm that this package is allowlisted to run in lock task mode.
    if (dpm.isLockTaskPermitted(context.packageName)) {
        activity.startLockTask()
    } else {
        // Because the package isn't allowlisted, calling startLockTask() here
        // would put the activity into screen pinning mode.
    }
}

Java

// In our Fragment subclass.
@Override
public void onResume() {
  super.onResume();

  // First, confirm that this package is allowlisted to run in lock task mode.
  if (dpm.isLockTaskPermitted(context.getPackageName())) {
    getActivity().startLockTask();
  } else {
    // Because the package isn't allowlisted, calling startLockTask() here
    // would put the activity into screen pinning mode.
  }
}

อย่าเริ่มโหมดล็อกงานเมื่ออุปกรณ์ล็อกอยู่เนื่องจากผู้ใช้อาจไม่เริ่ม สามารถปลดล็อกอุปกรณ์ได้ คุณสามารถเรียก KeyguardManager วิธีการเพื่อ ดูว่าอุปกรณ์ล็อกอยู่หรือไม่และใช้อายุการใช้งานของ Activity Callback (เช่น onResume() ซึ่งจะเรียกหลังจากปลดล็อก) ไปยัง เริ่มโหมดล็อกงาน

แอปในโหมดล็อกงานจะเริ่มกิจกรรมใหม่ได้ตราบใดที่กิจกรรมดังกล่าว จะไม่เริ่มงานใหม่ ยกเว้นงานที่เปิดแอปที่อยู่ในรายการที่อนุญาต ถึง ทำความเข้าใจว่างานเกี่ยวข้องกับกิจกรรมอย่างไร อ่านคู่มือ ทำความเข้าใจเกี่ยวกับงานและ Back Stack

หรือคุณจะประกาศในไฟล์ Manifest ของแอปก็ได้ ไฟล์ว่ากิจกรรมควรทำงานอย่างไร ระบบกำลังทำงานในโหมดล็อกงาน หากต้องการให้ระบบทำงานโดยอัตโนมัติ กิจกรรมของคุณในโหมดล็อกงาน ให้ตั้งค่า android:lockTaskMode ระบุแหล่งที่มาเป็น if_whitelisted เป็น ที่แสดงในตัวอย่างต่อไปนี้

<activity
    android:name=".MainActivity"
    android:lockTaskMode="if_whitelisted">
    <!-- ... -->
</activity>

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการประกาศตัวเลือกในไฟล์ Manifest ของแอปได้โดยอ่าน ข้อมูลอ้างอิง lockTaskMode

หยุดโหมดล็อกงาน

DPC สามารถหยุดโหมดล็อกงานจากระยะไกลได้โดยการนำแพ็กเกจแอปออกจาก จากรายการที่อนุญาต โทร DevicePolicyManager.setLockTaskPackages() ใน Android 6.0 (API ระดับ 23) ขึ้นไป และอย่าใส่ชื่อแพ็กเกจจาก รายการที่อนุญาต เมื่อคุณอัปเดตรายการที่อนุญาต แอปจะกลับไปยังรายการก่อนหน้า งานในสแต็กได้

หากก่อนหน้านี้มีกิจกรรมชื่อ startLockTask() กิจกรรมนั้นจะเรียกใช้ Activity.stopLockTask() เพื่อหยุดโหมดล็อกงาน วิธีนี้ ใช้ได้กับกิจกรรมที่เริ่มโหมดล็อกงานเท่านั้น

Callback ของวงจร

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

onLockTaskModeEntering()
มีการเรียกหลังจากที่แอปเข้าสู่โหมดล็อกงาน คุณสามารถรับชื่อแพ็กเกจของ จากอาร์กิวเมนต์ pkg
onLockTaskModeExiting()
เรียกใช้หลังจากแอปออกจากโหมดงานล็อก Callback นี้ไม่ได้รับ ข้อมูลเกี่ยวกับแอป

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

Kotlin

// Check if this app is in lock task mode. Screen pinning doesn't count.
var isLockTaskModeRunning = false

val activityManager = context
        .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    isLockTaskModeRunning =
            activityManager.lockTaskModeState ==
            ActivityManager.LOCK_TASK_MODE_LOCKED
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Deprecated in API level 23.
    isLockTaskModeRunning = activityManager.isInLockTaskMode
}

if (isLockTaskModeRunning) {
    // Show the exit button ...
}

Java

// Check if this app is in lock task mode. Screen pinning doesn't count.
boolean isLockTaskModeRunning = false;

ActivityManager activityManager = (ActivityManager)
    getContext().getSystemService(Context.ACTIVITY_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  isLockTaskModeRunning = activityManager.getLockTaskModeState()
      == ActivityManager.LOCK_TASK_MODE_LOCKED;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  // Deprecated in API level 23.
  isLockTaskModeRunning = activityManager.isInLockTaskMode();
}

if (isLockTaskModeRunning) {
  // Show the exit button ...
}

ปรับแต่ง UI

เมื่อแอปทำงานในโหมดล็อกงาน อินเทอร์เฟซผู้ใช้ (UI) ของระบบจะเปลี่ยนไปเป็น ด้วยวิธีต่อไปนี้

  • แถบสถานะจะว่างเปล่าโดยซ่อนการแจ้งเตือนและข้อมูลระบบไว้
  • ปุ่มหน้าแรกและปุ่มภาพรวมซ่อนอยู่
  • ส่วนแอปอื่นๆ เปิดกิจกรรมใหม่ไม่ได้
  • หน้าจอล็อก (หากตั้งค่าไว้) ปิดใช้อยู่

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

Kotlin

// Enable the Home and Overview buttons so that our custom launcher can respond
// using our custom activities. Implicitly disables all other features.
dpm.setLockTaskFeatures(
        adminName,
        DevicePolicyManager.LOCK_TASK_FEATURE_HOME or
              DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW)

Java

// Enable the Home and Overview buttons so that our custom launcher can respond
// using our custom activities. Implicitly disables all other features.
dpm.setLockTaskFeatures(adminName,
    DevicePolicyManager.LOCK_TASK_FEATURE_HOME |
          DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW);

ระบบจะปิดใช้ฟีเจอร์ที่ไม่มีในอาร์กิวเมนต์ flags ฟีเจอร์ UI ที่เปิดใช้จะยังคงอยู่ระหว่างการเปิดในโหมดงานล็อก หากอุปกรณ์ อยู่ในโหมดล็อกงานอยู่แล้ว การเปลี่ยนแปลงใดๆ ที่คุณทํากับฟีเจอร์งานล็อก แสดงทันที ตาราง 2 อธิบายฟีเจอร์ UI ที่คุณปรับแต่งได้

ตาราง 2 ฟีเจอร์ UI ของระบบที่ปรับแต่งได้ในโหมดงานล็อก
ฟีเจอร์ UI ของระบบ คำอธิบาย
LOCK_TASK_FEATURE_HOME แสดงปุ่มหน้าแรก เปิดใช้สำหรับ Launcher ที่กำหนดเอง โดยแตะ ปุ่มหน้าแรกไม่มีผลใดๆ เว้นแต่คุณจะอนุญาตค่าเริ่มต้นเป็น Android Launcher
LOCK_TASK_FEATURE_OVERVIEW แสดงปุ่มภาพรวม (การแตะปุ่มนี้จะเปิด หน้าจอล่าสุด) หากคุณ เปิดใช้งานปุ่มนี้ คุณต้องเปิดใช้งานปุ่มหน้าแรกด้วย
LOCK_TASK_FEATURE_GLOBAL_ACTIONS เปิดใช้งานกล่องโต้ตอบการทำงานส่วนกลางที่แสดงขึ้นเมื่อกด ปุ่มเปิด/ปิด ฟีเจอร์เดียวที่เปิดใช้เมื่อ setLockTaskFeatures() ยังไม่มีการโทร โดยทั่วไปผู้ใช้จะปิดอุปกรณ์ไม่ได้หากคุณ ปิดใช้กล่องโต้ตอบนี้
LOCK_TASK_FEATURE_NOTIFICATIONS เปิดการแจ้งเตือนสำหรับแอปทั้งหมด ซึ่งจะแสดงไอคอนการแจ้งเตือนใน แถบสถานะ การแจ้งเตือนล่วงหน้า และหน้าต่างแจ้งเตือนที่ขยายได้ หากคุณเปิดใช้ปุ่มนี้ คุณต้องเปิดใช้ปุ่มหน้าแรกด้วย การแตะ การดำเนินการและการแจ้งเตือนสำหรับปุ่มที่เปิดแผงใหม่จะไม่ทำงานในล็อก โหมดงาน
LOCK_TASK_FEATURE_SYSTEM_INFO เปิดใช้งานพื้นที่ข้อมูลระบบของแถบสถานะที่มีสัญญาณบอกสถานะ เป็นตัวเลือกการเชื่อมต่อ แบตเตอรี่ เสียงและการสั่น
LOCK_TASK_FEATURE_KEYGUARD เปิดใช้หน้าจอล็อกใดๆ ที่อาจตั้งค่าไว้ในอุปกรณ์ โดยปกติจะไม่ เหมาะสำหรับอุปกรณ์ที่ผู้ใช้สาธารณะ เช่น ตู้ประชาสัมพันธ์ ป้ายดิจิทัล
LOCK_TASK_FEATURE_NONE ปิดใช้ฟีเจอร์ UI ของระบบทั้งหมดที่แสดงข้างต้น

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

บล็อกหน้าต่างและการวางซ้อน

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

Kotlin

// Called just after entering lock task mode.
override fun onLockTaskModeEntering(context: Context, intent: Intent) {
    val dpm = getManager(context)
    val admin = getWho(context)

    dpm.addUserRestriction(admin, UserManager.DISALLOW_CREATE_WINDOWS)
}

Java

// Called just after entering lock task mode.
public void onLockTaskModeEntering(Context context, Intent intent) {
  DevicePolicyManager dpm = getManager(context);
  ComponentName admin = getWho(context);

  dpm.addUserRestriction(admin, UserManager.DISALLOW_CREATE_WINDOWS);
}

DPC จะนำข้อจำกัดของผู้ใช้ออกได้เมื่ออุปกรณ์ออกจากโหมดล็อกงาน

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

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