Bloccare la modalità attività

Questa guida per gli sviluppatori spiega come bloccare i dispositivi dedicati a una singola app o un insieme di app. Se sei uno sviluppatore di gestione della mobilità aziendale (EMM) o un integratore di soluzioni, leggi questa guida per aggiungere la modalità di blocco attività alla tua soluzione.

Panoramica

Android può eseguire le attività in una modalità immersiva, simile a un kiosk, chiamata modalità di blocco attività. Puoi utilizzare la modalità di blocco attività se stai sviluppando un'applicazione kiosk o Avvio app per presentare una raccolta di app. Quando il sistema è in esecuzione in modalità di blocco attività, in genere gli utenti dei dispositivi non possono vedere le notifiche, accedere alle app non incluse nella lista consentita o tornare alla schermata Home (a meno che questa non sia inclusa nella lista consentita).

Quando il sistema è in modalità di blocco attività, possono essere eseguite solo le app inserite nella lista consentita da un controller dei criteri dei dispositivi (DPC). Le app sono inserite nella lista consentita perché la persona che utilizza il dispositivo non può sempre uscire dalla modalità di blocco attività.

La modalità di combinazione dell'app inserita nella lista consentita per la modalità di blocco attività e il DPC inserito nella lista consentita dipenderà dal problema che vuoi risolvere. Ecco alcuni esempi:

  • Un unico pacchetto di app che combina un kiosk (per presentare contenuti) e un mini DPC (per l'inserimento nella lista consentita per la modalità di blocco attività).
  • Un DPC che fa parte di una soluzione di gestione della mobilità aziendale, con il lancio delle app mobile del cliente in modalità di blocco attività.

Disponibilità

Il sistema può essere eseguito in modalità di blocco attività in Android 5.0 o versioni successive. La tabella 1 mostra le versioni di Android che supportano l'inserimento delle app nella lista consentita per utente.

Tabella 1. Supporto della versione di Android per le modalità di amministrazione DPC
Versione di Android DPC amministra Notes
Android 5.0 (livello API 21) o versioni successive Dispositivo completamente gestito
Android 8.0 (livello API 26) o versioni successive Utente secondario affiliato L'utente secondario deve essere affiliato all'utente principale. Vedi la panoramica relativa a più utenti.
Android 9.0 (livello API 28) o versioni successive Utente secondario

In Android 9.0 o versioni successive, un DPC può avviare l'attività di qualsiasi app in modalità di blocco attività. Nelle versioni precedenti, l'app deve già supportare l'avvio della propria attività in modalità di blocco attività.

Inserisci app nella lista consentita

Un DPC deve inserire le app nella lista consentita prima che possano essere utilizzate in modalità di blocco attività. Chiama DevicePolicyManager.setLockTaskPackages() per inserire le app nella lista consentita per la modalità di blocco attività come mostrato nell'esempio seguente:

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

Per scoprire le app precedentemente inserite nella lista consentita per la modalità di blocco attività, un DPC può chiamare DevicePolicyManager.getLockTaskPackages(). Altre app possono chiamare DevicePolicyManager.isLockTaskPermitted() per verificare che un pacchetto dell'app supporti la modalità di blocco attività.

Avvia la modalità di blocco attività

In Android 9.0 (livello API 28) o versioni successive, puoi avviare l'attività di un'altra app in modalità di blocco attività. Se un'attività è già in esecuzione in primo piano o in background, è necessario riavviarla. Chiama ActivityOptions.setLockTaskEnabled() e fornisci queste opzioni quando avvii l'attività. Lo snippet seguente mostra un modo per eseguire questa operazione:

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

Nelle versioni di Android precedenti alla 9.0, un'app avvia le proprie attività in modalità di blocco attività chiamando Activity.startLockTask(). Per chiamare questo metodo, l'attività deve essere in esecuzione in primo piano (vedi Concetti del ciclo di vita dell'attività), quindi ti consigliamo di utilizzare il metodo onResume() di un Activity o Fragment. Ecco come chiamare 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.
  }
}

Non avviare la modalità di blocco attività quando il dispositivo è bloccato perché l'utente potrebbe non riuscire a sbloccarlo. Puoi chiamare i metodi KeyguardManager per scoprire se il dispositivo è bloccato e utilizzare un callback del ciclo di vita di Activity (ad esempio onResume() che viene richiamato dopo lo sblocco) per avviare la modalità di blocco attività.

Un'app in modalità di blocco attività può avviare nuove attività purché non ne avvii una nuova, ad eccezione di quelle che avviano un'app inclusa nella lista consentita. Per comprendere la correlazione tra le attività e le attività, leggi la guida Informazioni su Tasks e sullo stack precedente.

In alternativa, puoi dichiarare nel file manifest dell'app come deve comportarsi un'attività quando il sistema è in esecuzione in modalità di blocco attività. Per fare in modo che il sistema esegua automaticamente l'attività in modalità di blocco attività, imposta l'attributo android:lockTaskMode su if_whitelisted, come mostrato nell'esempio seguente:

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

Per saperne di più sulla dichiarazione delle opzioni nel file manifest dell'app, leggi il riferimento a lockTaskMode.

Interrompi la modalità di blocco attività

Un DPC può interrompere da remoto la modalità di blocco attività rimuovendo il pacchetto dell'app dalla lista consentita. Chiama DevicePolicyManager.setLockTaskPackages() in Android 6.0 (livello API 23) o versioni successive e ometti il nome del pacchetto dall'array della lista consentita. Quando aggiorni la lista consentita, l'app torna all'attività precedente nell'elenco.

Se un'attività precedentemente chiamata startLockTask() può chiamare Activity.stopLockTask() per interrompere la modalità di blocco attività. Questo metodo funziona solo per l'attività che ha avviato la modalità di blocco attività.

Callback del ciclo di vita

Il DPC potrebbe trovare utile sapere quando un'app (in esecuzione sullo stesso utente) entra ed esce dalla modalità di blocco attività. Per ricevere i callback, esegui l'override dei seguenti metodi di callback nella sottoclasse DeviceAdminReceiver del tuo DPC:

onLockTaskModeEntering()
Chiamata dopo che un'app è passata alla modalità di blocco attività. Puoi ottenere il nome del pacchetto di un'app dall'argomento pkg.
onLockTaskModeExiting()
Richiamato dopo che un'app esce dalla modalità di blocco attività. Questo callback non riceve informazioni sull'app.

Se avvii un'altra app in modalità di blocco attività, devi monitorare lo stato di esecuzione nella tua app. Per verificare se l'app corrente è in esecuzione in modalità di blocco attività, utilizza i metodi su ActivityManager come mostrato nell'esempio seguente:

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

Personalizzazione dell'interfaccia utente

Quando un'app viene eseguita in modalità di blocco attività, l'interfaccia utente (UI) del sistema cambia nei seguenti modi:

  • La barra di stato è vuota e le notifiche e le informazioni sul sistema sono nascoste.
  • I pulsanti Home e Panoramica sono nascosti.
  • Le altre app non possono avviare nuove attività.
  • La schermata di blocco (se impostata) è disattivata.

In Android 9.0 o versioni successive, se è attiva la modalità di blocco attività, il DPC può abilitare alcune funzionalità dell'interfaccia utente di sistema sul dispositivo, utili per gli sviluppatori che creano un Avvio app personalizzato. Chiama DevicePolicyManager.setLockTaskFeatures() come mostrato nel seguente snippet:

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

Il sistema disattiva tutte le funzionalità che non includi nell'argomento flags. Le funzionalità dell'interfaccia utente abilitate rimangono attive tra un avvio e l'altro in modalità di blocco attività. Se il dispositivo è già in modalità di blocco attività, le modifiche apportate alle funzionalità di blocco attività vengono mostrate immediatamente. La tabella 2 descrive le funzionalità dell'interfaccia utente che puoi personalizzare.

Tabella 2. Funzionalità personalizzabili dell'interfaccia utente di sistema in modalità di blocco attività
Funzionalità UI di sistema Descrizione
LOCK_TASK_FEATURE_HOME Mostra il pulsante Home. Abilita per Avvio applicazioni personalizzate: toccare un pulsante Home abilitato non ha alcuna azione, a meno che non inserisci l'Avvio app Android predefinito nella lista consentita.
LOCK_TASK_FEATURE_OVERVIEW Mostra il pulsante Panoramica (se tocchi questo pulsante, si apre la schermata Recenti). Se abiliti questo pulsante, devi abilitare anche il pulsante Home.
LOCK_TASK_FEATURE_GLOBAL_ACTIONS Consente di attivare la finestra di dialogo delle azioni globali che viene visualizzata quando si preme a lungo il tasto di accensione. L'unica funzionalità abilitata quando setLockTaskFeatures() non è stata chiamata. In genere, un utente non può spegnere il dispositivo se disattivi questa finestra di dialogo.
LOCK_TASK_FEATURE_NOTIFICATIONS Attiva le notifiche per tutte le app. Qui sono mostrate le icone di notifica nella barra di stato, nelle notifiche in evidenza e nell'area notifiche espandibile. Se attivi questo pulsante, devi attivare anche il pulsante Home. Il tocco delle azioni di notifica e dei pulsanti che aprono nuovi riquadri non funziona in modalità di blocco attività.
LOCK_TASK_FEATURE_SYSTEM_INFO Consente di attivare l'area di informazioni sul sistema della barra di stato che contiene indicatori come connettività, batteria e opzioni di suono e vibrazione.
LOCK_TASK_FEATURE_KEYGUARD Consente di attivare qualsiasi schermata di blocco che potrebbe essere impostata sul dispositivo. In genere non è adatto ai dispositivi con utenti pubblici, come i kiosk informativi o la segnaletica digitale.
LOCK_TASK_FEATURE_NONE Disattiva tutte le funzionalità dell'interfaccia utente di sistema elencate sopra.

Un DPC può chiamare DevicePolicyManager.getLockTaskFeatures() per ottenere l'elenco delle funzionalità disponibili su un dispositivo quando è attiva la modalità di blocco attività. Quando un dispositivo esce dalla modalità di blocco attività, l'interfaccia utente torna allo stato imposto dai criteri relativi ai dispositivi esistenti.

Bloccare finestre e overlay

Quando un'app viene eseguita in modalità di blocco attività, altre app e servizi in background possono creare nuove finestre che Android mostra davanti all'app in modalità di blocco attività. App e servizi creano queste finestre per mostrare toast, finestre di dialogo e overlay alla persona che utilizza il dispositivo. Il DPC può evitarli aggiungendo la limitazione utente di DISALLOW_CREATE_WINDOWS. L'esempio seguente mostra come eseguire questa operazione nel 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);
}

Il DPC può rimuovere la limitazione utente quando il dispositivo esce dalla modalità di blocco attività.

Risorse aggiuntive

Per scoprire di più sui dispositivi dedicati, leggi i seguenti documenti: