Chế độ khoá tác vụ

Hướng dẫn dành cho nhà phát triển này giải thích cách khoá các thiết bị chuyên dụng với một thiết bị hoặc một nhóm ứng dụng. Nếu bạn là nhân viên quản lý di động dành cho doanh nghiệp (EMM) nhà phát triển hoặc nhà tích hợp giải pháp hãy đọc hướng dẫn này để thêm chế độ khoá tác vụ vào Cloud.

Tổng quan

Android có thể chạy các tác vụ theo cách chìm (immerse), kiểu kiosk được gọi là tác vụ khoá chế độ xem. Bạn có thể sử dụng chế độ khoá tác vụ nếu đang phát triển ứng dụng kiosk hoặc một trình chạy để trình bày một bộ sưu tập ứng dụng. Khi hệ thống chạy trong tác vụ khoá chế độ này, người dùng thiết bị thường không thể xem thông báo, truy cập vào không có trong danh sách cho phép các ứng dụng hoặc quay lại màn hình chính (trừ phi màn hình chính được đưa vào danh sách cho phép).

Chỉ những ứng dụng đã được trình kiểm soát chính sách thiết bị (DPC) đưa vào danh sách cho phép mới có thể chạy khi hệ thống ở chế độ khoá tác vụ. Các ứng dụng được đưa vào danh sách cho phép vì người đó sử dụng thiết bị không phải lúc nào cũng thoát khỏi chế độ khoá tác vụ.

Cách kết hợp ứng dụng này vào danh sách cho phép đối với chế độ khoá tác vụ và DPC trong danh sách cho phép sẽ tuỳ thuộc vào vấn đề bạn muốn giải quyết. Dưới đây là một số ví dụ:

  • Một gói ứng dụng kết hợp một kiosk (để trình bày nội dung) và một DPC thu nhỏ (để tự đưa vào danh sách cho phép đối với chế độ khoá tác vụ).
  • DPC là một phần của giải pháp quản lý di động dành cho doanh nghiệp, khởi chạy ứng dụng di động của khách hàng ở chế độ khoá tác vụ.

Phạm vi cung cấp

Hệ thống có thể chạy ở chế độ khoá tác vụ trong Android 5.0 trở lên. Bảng 1 cho thấy phiên bản Android nào hỗ trợ đưa ứng dụng vào danh sách cho phép theo người dùng.

Bảng 1. Hỗ trợ phiên bản Android cho chế độ quản trị DPC
Phiên bản Android Quản trị DPC Ghi chú
Android 5.0 (API cấp 21) trở lên Thiết bị được quản lý hoàn toàn
Android 8.0 (API cấp 26) trở lên Người dùng phụ được liên kết Người dùng phụ phải liên kết với người dùng chính. Xem nhiều người dùng.
Android 9.0 (API cấp 28) trở lên Người dùng phụ

Trong Android 9.0 trở lên, DPC có thể bắt đầu hoạt động của bất kỳ ứng dụng nào ở chế độ khoá tác vụ. Trong các phiên bản cũ, ứng dụng đó phải hỗ trợ việc bắt đầu hoạt động của chính mình trong chế độ khoá tác vụ.

Đưa ứng dụng vào danh sách cho phép

DPC phải đưa các ứng dụng vào danh sách cho phép trước khi có thể sử dụng ở chế độ khoá tác vụ. Gọi điện DevicePolicyManager.setLockTaskPackages() đến đưa ứng dụng vào danh sách cho phép đối với chế độ khoá tác vụ như minh hoạ trong mẫu sau:

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);

Để tìm ra các ứng dụng đã được thêm vào danh sách cho phép trước đó ở chế độ khoá tác vụ, DPC có thể gọi DevicePolicyManager.getLockTaskPackages(). Lý do khác các ứng dụng có thể gọi DevicePolicyManager.isLockTaskPermitted() để xác nhận gói ứng dụng hỗ trợ chế độ khoá tác vụ.

Bắt đầu chế độ khoá tác vụ

Trong Android 9.0 (API cấp 28) trở lên, bạn có thể bắt đầu hoạt động của một ứng dụng khác trong chế độ khoá tác vụ. Nếu một hoạt động đang chạy ở nền trước hoặc nền, bạn cần chạy lại hoạt động này. Gọi điện ActivityOptions.setLockTaskEnabled() và cung cấp các tham số này khi bắt đầu hoạt động. Đoạn mã sau đây cho bạn biết một cách thực hiện việc này:

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());
}

Trong các phiên bản Android trước 9.0, một ứng dụng sẽ bắt đầu các hoạt động của riêng mình trong tác vụ khoá bằng cách gọi Activity.startLockTask(). Để gọi sự kiện này thì hoạt động phải đang chạy ở nền trước (xem phần Vòng đời hoạt động ), do đó, bạn nên gọi trong Phương thức onResume() của Activity hoặc Fragment Dưới đây là cách gọi 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.
  }
}

Đừng bắt đầu chế độ khoá tác vụ khi thiết bị đang bị khoá vì người dùng có thể không có thể mở khoá thiết bị. Bạn có thể gọi các phương thức KeyguardManager để tìm hiểu xem thiết bị có bị khoá hay không và sử dụng vòng đời Activity lệnh gọi lại (chẳng hạn như onResume() được gọi sau khi mở khoá) đến bắt đầu chế độ khoá tác vụ.

Ứng dụng ở chế độ khoá tác vụ có thể bắt đầu hoạt động mới miễn là hoạt động đó không bắt đầu nhiệm vụ mới, ngoại trừ các nhiệm vụ chạy một ứng dụng trong danh sách cho phép. Người nhận hiểu mối liên hệ giữa nhiệm vụ với các hoạt động, hãy đọc hướng dẫn Tìm hiểu về nhiệm vụ và Ngăn xếp lui.

Ngoài ra, bạn có thể khai báo trong tệp kê khai ứng dụng tệp cách một hoạt động sẽ hoạt động khi hệ thống đang chạy ở chế độ khoá tác vụ. Để hệ thống tự động chạy hoạt động của bạn ở chế độ khoá tác vụ, hãy đặt android:lockTaskMode cho if_whitelisted dưới dạng như trong ví dụ sau:

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

Bạn có thể đọc bài viết này để tìm hiểu thêm về cách khai báo các tuỳ chọn trong tệp kê khai ứng dụng tham chiếu lockTaskMode.

Dừng chế độ khoá tác vụ

DPC có thể dừng từ xa chế độ khoá tác vụ bằng cách xoá gói ứng dụng khỏi danh sách cho phép. Gọi điện DevicePolicyManager.setLockTaskPackages(), inch Android 6.0 (API cấp 23) trở lên và bỏ tên gói khỏi danh sách cho phép. Khi bạn cập nhật danh sách cho phép, ứng dụng sẽ quay về phiên bản trước tác vụ trong ngăn xếp.

Nếu một hoạt động trước đây có tên là startLockTask(), thì hoạt động đó có thể gọi Activity.stopLockTask() để dừng chế độ khoá tác vụ. Phương thức này chỉ hoạt động đối với hoạt động đã bắt đầu chế độ khoá tác vụ.

Phương thức gọi lại trong vòng đời

DPC của bạn có thể thấy hữu ích khi biết thời điểm một ứng dụng (chạy trong cùng một người dùng) chuyển vào và thoát khỏi chế độ khoá tác vụ. Để nhận lệnh gọi lại, hãy ghi đè các giá trị sau phương thức gọi lại trong lớp con DeviceAdminReceiver của DPC:

onLockTaskModeEntering()
Được gọi sau khi một ứng dụng chuyển sang chế độ khoá tác vụ. Bạn có thể lấy tên gói của ứng dụng của bạn qua đối số pkg.
onLockTaskModeExiting()
Được gọi sau khi một ứng dụng thoát khỏi chế độ khoá tác vụ. Lệnh gọi lại này không nhận được về ứng dụng.

Nếu chạy một ứng dụng khác ở chế độ khoá tác vụ, bạn cần theo dõi quá trình chạy trạng thái trong ứng dụng của chính bạn. Cách kiểm tra xem ứng dụng hiện tại có đang chạy trong tác vụ khoá hay không hãy sử dụng các phương thức trên ActivityManager như trong phần sau ví dụ:

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 ...
}

Tuỳ chỉnh giao diện người dùng

Khi một ứng dụng chạy ở chế độ khoá tác vụ, giao diện người dùng (UI) hệ thống sẽ thay đổi theo các cách sau:

  • Thanh trạng thái trống, thông báo và thông tin hệ thống bị ẩn.
  • Nút Màn hình chính và Tổng quan bị ẩn.
  • Các ứng dụng khác không thể chạy hoạt động mới.
  • Màn hình khoá (nếu có) đã tắt.

Trong Android 9.0 trở lên khi chế độ khoá tác vụ được bật, DPC của bạn có thể bật một số tính năng giao diện người dùng hệ thống nhất định trên thiết bị—hữu ích cho các nhà phát triển đang tạo một trình chạy. Gọi điện DevicePolicyManager.setLockTaskFeatures() như minh hoạ trong đoạn mã sau:

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);

Hệ thống sẽ tắt mọi tính năng mà bạn không đưa vào đối số flags. Chiến lược phát hành đĩa đơn các tính năng giao diện người dùng đã bật vẫn tồn tại giữa các lần chạy ở chế độ khoá tác vụ. Nếu thiết bị đã ở chế độ khoá tác vụ, mọi thay đổi bạn thực hiện đối với các tính năng khoá tác vụ hiển thị ngay lập tức. Bảng 2 mô tả các tính năng giao diện người dùng mà bạn có thể tuỳ chỉnh.

Bảng 2. Các tính năng có thể tuỳ chỉnh trên giao diện người dùng hệ thống ở chế độ khoá tác vụ
Tính năng giao diện người dùng hệ thống Mô tả
LOCK_TASK_FEATURE_HOME Hiển thị nút Trang chủ. Bật cho trình chạy tuỳ chỉnh—nhấn vào một trình chạy đã bật Nút Màn hình chính không có thao tác nào trừ phi bạn đưa thiết bị Android mặc định vào danh sách cho phép trình chạy.
LOCK_TASK_FEATURE_OVERVIEW Hiển thị nút Tổng quan (nhấn vào nút này sẽ mở màn hình Gần đây). Nếu bạn bật nút này, bạn cũng phải bật nút Trang chủ.
LOCK_TASK_FEATURE_GLOBAL_ACTIONS Bật hộp thoại tác vụ chung hiển thị khi nhấn và giữ nút nguồn. Tính năng duy nhất được bật khi setLockTaskFeatures() chưa được gọi. Người dùng thường không thể tắt nguồn thiết bị nếu bạn tắt hộp thoại này.
LOCK_TASK_FEATURE_NOTIFICATIONS Bật thông báo cho tất cả ứng dụng. Thao tác này hiển thị các biểu tượng thông báo trong thanh trạng thái, thông báo quan trọng và ngăn thông báo có thể mở rộng. Nếu bạn bật nút này, bạn cũng phải bật nút Trang chủ. Thao tác nhấn các nút và thao tác với thông báo để mở bảng điều khiển mới không hoạt động ở chế độ khoá chế độ tác vụ.
LOCK_TASK_FEATURE_SYSTEM_INFO Bật vùng thông tin hệ thống trên thanh trạng thái có chứa các chỉ báo như như các lựa chọn kết nối, pin, âm thanh và rung.
LOCK_TASK_FEATURE_KEYGUARD Bật mọi màn hình khoá có thể đã đặt trên thiết bị. Thường không phù hợp với các thiết bị có người dùng công khai như ki-ốt thông tin hoặc biển hiệu kỹ thuật số.
LOCK_TASK_FEATURE_NONE Tắt tất cả các tính năng giao diện người dùng hệ thống nêu trên.

DPC có thể gọi DevicePolicyManager.getLockTaskFeatures() để nhận danh sách các tính năng có trên thiết bị khi chế độ khoá tác vụ được bật. Thời gian thiết bị thoát khỏi chế độ khoá tác vụ, giao diện người dùng sẽ trở về trạng thái bắt buộc theo chính sách thiết bị hiện tại.

Chặn cửa sổ và lớp phủ

Khi một ứng dụng chạy ở chế độ khoá tác vụ, các ứng dụng khác và dịch vụ nền có thể tạo cửa sổ mới mà Android cho thấy trước ứng dụng ở chế độ khoá tác vụ. Các ứng dụng và dịch vụ tạo các cửa sổ này để hiện thông báo ngắn, hộp thoại và lớp phủ cho người đang sử dụng thiết bị. DPC của bạn có thể ngăn những điều này bằng cách thêm Giới hạn người dùng DISALLOW_CREATE_WINDOWS. Ví dụ sau cho thấy cách bạn có thể thực hiện điều này trong Lệnh gọi lại 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 của bạn có thể loại bỏ giới hạn người dùng khi thiết bị thoát khỏi chế độ khoá tác vụ.

Tài nguyên khác

Để tìm hiểu thêm về các thiết bị chuyên dụng, hãy đọc các tài liệu sau: