鎖定任務模式

這份開發人員指南說明如何將專用裝置鎖定為單一裝置 或一組應用程式如果您是企業行動管理服務 (EMM) 開發人員或解決方案整合商請參閱本指南,將鎖定任務模式新增至 解決方案

總覽

Android 能以類似資訊站的方式執行任務,這種沉浸式的做法稱為鎖定任務 模式。如果您開發的是資訊站應用程式,可以使用鎖定任務模式 啟動器,以展示一系列應用程式。系統在鎖定任務中執行時 模式,裝置使用者通常無法查看通知,無法存取未加入許可清單 或返回主畫面 (除非該主畫面已加入許可清單)。

只有裝置政策控制器 (DPC) 已加入許可清單的應用程式才能執行 系統處於鎖定任務模式時應用程式已加入許可清單,因為使用者 使用裝置可能無法一律離開鎖定任務模式。

如何結合適用於鎖定任務模式的應用程式許可清單,以及將 DPC 加入許可清單的應用程式 視您想解決的問題而定。例如:

  • 結合資訊站 (用於呈現內容) 和迷你 DPC 的單一應用程式套件 (將自己加入鎖定任務模式的許可清單)。
  • 這項 DPC 是企業行動管理服務解決方案的一部分, 在鎖定任務模式下的客戶行動應用程式

適用地區

在 Android 5.0 以上版本中,系統可在鎖定任務模式下執行。表格 1 節目 哪些 Android 版本支援讓使用者將應用程式加入許可清單。

表 1.DPC 管理員模式適用的 Android 版本支援
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()。如何稱呼此項目 方法,活動必須在前景執行 (請參閱「活動生命週期」 建議 ActivityonResume() 方法,或 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 生命週期 回呼 (例如解鎖後呼叫的 onResume()) 啟動鎖定任務模式。

處於鎖定任務模式的應用程式,只要活動符合期間,就可開始新活動 系統不會啟動新工作,但會啟動已加入許可清單的應用程式的工作除外。目的地: 如要瞭解工作與活動的關係,請參閱「瞭解工作與 返回堆疊

或者,您也可以在應用程式資訊清單中進行宣告 檔案 系統正在鎖定任務模式下執行讓系統自動執行 將您的活動設為鎖定任務模式,請將 android:lockTaskMode 屬性設為 if_whitelisted,因為 如以下範例所示:

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

如要進一步瞭解如何在應用程式資訊清單檔案中宣告選項,請參閱 lockTaskMode 參照。

停止鎖定任務模式

DPC 可以從以下位置移除應用程式套件,從遠端停止鎖定工作模式: 加入許可清單。致電 DevicePolicyManager.setLockTaskPackages(),英寸 Android 6.0 (API 級別 23) 以上版本,並在 許可清單陣列。更新許可清單後,應用程式就會回到先前的 處理堆疊中的工作

如果活動先前稱為 startLockTask(),則該活動可以呼叫 Activity.stopLockTask() 可停止鎖定工作模式。這個方法 僅適用於啟動鎖定任務模式的活動。

生命週期回呼

如果想知道應用程式 (在同一使用者中執行) 的時機,DPC 可能會很有幫助 會進入及結束鎖定任務模式。如要接收回呼,請覆寫以下 DPC DeviceAdminReceiver 子類別中的回呼方法:

onLockTaskModeEntering()
應用程式進入鎖定工作模式後呼叫。您可以取得 來自 pkg 引數的應用程式。
onLockTaskModeExiting()
應用程式結束鎖定工作模式後呼叫。這個回撥電話未收到 應用程式的相關資訊

如果您將另一個應用程式啟動進入鎖定任務模式,您必須追蹤跑步 才能正確設定狀態檢查目前的應用程式是否在鎖定任務中執行 模式,請在 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) 會在 方法如下:

  • 狀態列是空白的,通知和系統資訊會隱藏。
  • 「首頁」和「總覽」按鈕已隱藏。
  • 其他應用程式將無法啟動新活動。
  • 螢幕鎖定 (如有設定) 會停用。

在 Android 9.0 以上版本中啟用鎖定任務模式時,DPC 可以啟用鎖定任務模式 才能在裝置上使用特定系統 UI 功能 啟動器。致電 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 顯示「首頁」按鈕。啟用自訂啟動器:輕觸啟用的選項 主畫面按鈕沒有動作 (除非將預設 Android 加入許可清單) 啟動器。
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 使用者限制。 以下範例說明如何在 Cloud Shell 中 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 可以在裝置結束鎖定任務模式時移除使用者限制。

其他資源

如要進一步瞭解專用裝置,請參閱下列文件: