Tryb blokowania zadań

W tym przewodniku dla programistów wyjaśniamy, jak można zablokować dostęp do wybranych aplikacji na określonych urządzeniach. Jeśli jesteś deweloperem usług EMM lub integratorem rozwiązań, z tego przewodnika dowiesz się, jak dodać tryb blokowania zadań do swojego rozwiązania.

Przegląd

Android umożliwia uruchamianie zadań w rzeczywistym trybie blokowania (tzw. tryb zadań blokowania). Trybu blokowania zadań możesz użyć, gdy tworzysz aplikację kiosku lub program uruchamiający do prezentowania kolekcji aplikacji. Gdy system działa w trybie zadań blokady, użytkownicy urządzeń zazwyczaj nie widzą powiadomień, nie mają dostępu do aplikacji spoza listy dozwolonych ani nie mogą wrócić do ekranu głównego (chyba że ekran główny znajduje się na liście dozwolonych).

Gdy system jest w trybie zadań blokowania, mogą być uruchamiane tylko te aplikacje, które zostały dodane do listy dozwolonych przez kontroler zasad dotyczących urządzeń (DPC). Aplikacje są na liście dozwolonych, ponieważ użytkownik urządzenia nie zawsze może wyjść z trybu blokowania zadań.

Sposób łączenia aplikacji z listy dozwolonych na potrzeby trybu blokady zadań z dodawaniem DPC do listy dozwolonych zależy od problemu, który chcesz rozwiązać. Oto przykłady:

  • Pojedynczy pakiet aplikacji łączący kiosk (do prezentowania treści) i mini DPC (w celu umieszczenia go na liście dozwolonych w trybie blokowania zadań).
  • DPC, który jest częścią rozwiązania do zarządzania urządzeniami mobilnymi, który uruchamia aplikacje mobilne klienta w trybie blokady zadań.

Dostępność

System może działać w trybie blokady zadań na Androidzie 5.0 lub nowszym. Tabela 1 zawiera informacje o tym, które wersje Androida obsługują dodawanie aplikacji do listy dozwolonych według użytkownika.

Tabela 1 Obsługa wersji Androida w trybach administracyjnych DPC
Wersja Androida Administruje DPC Uwagi
Android 5.0 (poziom interfejsu API 21) lub nowszy Urządzenie w pełni zarządzane
Android 8.0 (poziom interfejsu API 26) lub nowszy Powiązany użytkownik dodatkowy Użytkownik dodatkowy musi być powiązany z użytkownikiem głównym. Zobacz omówienie wielu użytkowników.
Android 9.0 (poziom interfejsu API 28) lub nowszy Użytkownik dodatkowy

W Androidzie 9.0 i nowszych DPC może włączyć tryb blokowania zadań w dowolnej aplikacji. We wcześniejszych wersjach aplikacja musi już obsługiwać rozpoczynanie własnych działań w trybie blokady zadań.

Dodaj aplikacje do listy dozwolonych

DPC musi dodać aplikacje do listy dozwolonych, aby można było ich używać w trybie blokowania zadań. Wywołaj metodę DevicePolicyManager.setLockTaskPackages(), aby dodać aplikacje do listy dozwolonych w trybie blokady, jak pokazano w tym przykładzie:

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

Aby dowiedzieć się, które aplikacje zostały wcześniej umieszczone na liście dozwolonych w trybie blokady, DPC może wywołać metodę DevicePolicyManager.getLockTaskPackages(). Inne aplikacje mogą wywołać metodę DevicePolicyManager.isLockTaskPermitted(), aby sprawdzić, czy pakiet aplikacji obsługuje tryb zadań blokady.

Włącz tryb blokowania zadań

W Androidzie 9.0 (poziom interfejsu API 28) lub nowszym możesz rozpoczynać aktywność w innej aplikacji w trybie blokady. Jeśli aktywność jest już uruchomiona na pierwszym planie lub w tle, musisz ją ponownie uruchomić. Wywołaj metodę ActivityOptions.setLockTaskEnabled() i podaj te opcje przy rozpoczynaniu działania. Oto jeden ze sposobów, aby to zrobić:

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

Na urządzeniach z Androidem w wersjach starszych niż 9.0 aplikacja rozpoczyna własne działania w trybie blokady zadania, wywołując metodę Activity.startLockTask(). Aby można było wywołać tę metodę, działanie musi być uruchomione na pierwszym planie (patrz Pojęcia związane z cyklem życia aktywności), dlatego zalecamy wywołanie metody onResume() w obiekcie Activity lub Fragment. Oto jak możesz zadzwonić do firmy 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.
  }
}

Nie uruchamiaj trybu zadań blokowania, gdy urządzenie jest zablokowane, bo użytkownik może nie być w stanie go odblokować. Możesz wywołać metody KeyguardManager, aby sprawdzić, czy urządzenie jest zablokowane, i użyć wywołania zwrotnego cyklu życia Activity (np. onResume() wywoływanego po odblokowaniu) w celu uruchomienia trybu zadań blokowania.

Aplikacja w trybie blokady zadań może rozpoczynać nowe działania, o ile nie powoduje one uruchomienia nowego zadania – z wyjątkiem tych, które uruchamiają aplikację znajdującą się na liście dozwolonych. Aby zrozumieć, jak zadania są powiązane z działaniami, zapoznaj się z przewodnikiem Omówienie zadań i stosu wstecznego.

Możesz też zadeklarować w pliku manifestu aplikacji, jak powinna działać aktywność, gdy system działa w trybie blokady zadań. Aby system automatycznie uruchamiał Twoją aktywność w trybie blokady, ustaw atrybut android:lockTaskMode na if_whitelisted, jak w tym przykładzie:

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

Więcej informacji o deklarowaniu opcji w pliku manifestu aplikacji znajdziesz w dokumentacji lockTaskMode.

Zatrzymaj tryb blokowania zadań

DPC może zdalnie zatrzymać tryb zadań blokowania, usuwając pakiet aplikacji z listy dozwolonych. Wywołaj DevicePolicyManager.setLockTaskPackages() w Androidzie 6.0 (poziom interfejsu API 23) lub nowszym i pomiń nazwę pakietu w tablicy listy dozwolonych. Po zaktualizowaniu listy dozwolonych aplikacja wraca do poprzedniego zadania w stosie.

Jeśli aktywność nazywała się wcześniej startLockTask(), może ona wywołać metodę Activity.stopLockTask(), aby zatrzymać tryb zadania blokady. Ta metoda działa tylko w przypadku aktywności, która uruchomiła tryb blokowania zadań.

Wywołania zwrotne cyklu życia

DPC może potrzebować informacji o tym, kiedy aplikacja (działająca w ramach tego samego użytkownika) przechodzi w tryb blokowania zadań, a kiedy z niego wychodzi. Aby otrzymywać wywołania zwrotne, zastąp te metody w podklasie DeviceAdminReceiver DPC:

onLockTaskModeEntering()
Wywoływane po przejściu aplikacji w tryb blokowania zadania. Nazwę pakietu aplikacji możesz uzyskać z argumentu pkg.
onLockTaskModeExiting()
Wywoływane po wyjściu aplikacji z trybu zadań blokady. Nie otrzyma ono informacji o aplikacji.

Jeśli uruchomisz inną aplikację w trybie blokady zadań, musisz śledzić stan jej działania we własnej aplikacji. Aby sprawdzić, czy bieżąca aplikacja działa w trybie zadania blokady, użyj metod w ActivityManager, jak pokazano w tym przykładzie:

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

Dostosowywanie interfejsu

Gdy aplikacja działa w trybie blokady, interfejs systemu zmienia się w taki sposób:

  • Pasek stanu jest pusty, a powiadomienia i informacje o systemie są ukryte.
  • Przyciski Ekran główny i Przegląd są ukryte.
  • Inne aplikacje nie mogą uruchamiać nowych aktywności.
  • Ekran blokady (jeśli jest ustawiony) jest wyłączony.

W Androidzie 9.0 i nowszych, gdy włączony jest tryb blokowania zadań, DPC może włączyć na urządzeniu niektóre funkcje interfejsu systemu. Jest to przydatne dla programistów tworzących niestandardowe Menu z aplikacjami. Wywołaj metodę DevicePolicyManager.setLockTaskFeatures(), jak pokazano w tym fragmencie:

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

System wyłączy wszystkie funkcje, których nie ma w argumencie flags. Włączone funkcje interfejsu pozostają aktywne po uruchomieniu w trybie blokady zadań. Jeśli urządzenie jest już w trybie blokowania zadań, wszelkie zmiany w tych funkcjach są natychmiast widoczne. Tabela 2 zawiera opis funkcji interfejsu, które możesz dostosować.

Tabela 2 Możliwość dostosowania funkcji interfejsu systemowego w trybie blokady zadań
Funkcja interfejsu systemu Opis
LOCK_TASK_FEATURE_HOME Wyświetla przycisk strony głównej. Włącz dla niestandardowych programów uruchamiających – dotknięcie włączonego przycisku ekranu głównego nie spowoduje żadnego działania, chyba że dodasz domyślny program uruchamiający Androida do listy dozwolonych.
LOCK_TASK_FEATURE_OVERVIEW Wyświetla przycisk Przegląd (jego kliknięcie otwiera ekran Ostatnie). Jeśli włączysz ten przycisk, musisz też włączyć przycisk strony głównej.
LOCK_TASK_FEATURE_GLOBAL_ACTIONS Włącza globalne okno działań, które wyświetla się po przytrzymaniu przycisku zasilania. Jedyna funkcja, która jest włączona, gdy nie wywołano jeszcze metody setLockTaskFeatures(). Jeśli wyłączysz to okno, użytkownik zazwyczaj nie może wyłączyć urządzenia.
LOCK_TASK_FEATURE_NOTIFICATIONS Włącza powiadomienia ze wszystkich aplikacji. Pokazuje ikony powiadomień na pasku stanu, powiadomieniach HUD i rozwijanym obszarze powiadomień. Jeśli włączysz ten przycisk, musisz też włączyć przycisk strony głównej. Dotykanie funkcji powiadomień i przycisków, które otwierają nowe panele, nie działają w trybie blokowania zadań.
LOCK_TASK_FEATURE_SYSTEM_INFO Włącza obszar informacyjny na pasku stanu zawierający wskaźniki takie jak łączność, bateria, dźwięki i wibracje.
LOCK_TASK_FEATURE_KEYGUARD Włącza ekran blokady, który może być ustawiony na urządzeniu. Zwykle nie są one odpowiednie dla urządzeń używanych publicznie, takich jak kioski informacyjne czy cyfrowe treści informacyjno-reklamowe.
LOCK_TASK_FEATURE_NONE Wyłącza wszystkie wymienione powyżej funkcje interfejsu systemu.

DPC może wywołać metodę DevicePolicyManager.getLockTaskFeatures(), aby uzyskać listę funkcji dostępnych na urządzeniu, gdy włączony jest tryb zadań blokowania. Gdy urządzenie wyjdzie z trybu zadań blokowania, interfejs powróci do stanu określonego przez istniejące zasady dotyczące urządzeń.

Blokuj okna i nakładki

Gdy aplikacja działa w trybie blokady, inne aplikacje i usługi w tle mogą tworzyć nowe okna, które Android wyświetla przed aplikacją w trybie blokowania zadań. Aplikacje i usługi tworzą te okna, aby wyświetlać tosty, okna i nakładki reklamowe osobie korzystającej z urządzenia. DPC może im zapobiec, dodając ograniczenie dotyczące użytkownika DISALLOW_CREATE_WINDOWS. Poniższy przykład pokazuje, jak można to zrobić w wywołaniu zwrotnym 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 może usunąć te ograniczenia, gdy urządzenie wyjdzie z trybu zadań blokowania.

Dodatkowe materiały

Aby dowiedzieć się więcej o dedykowanych urządzeniach, przeczytaj te dokumenty: