Este guia para desenvolvedores explica como dispositivos dedicados podem ser bloqueados em um único app ou conjunto de apps. Se você é um desenvolvedor de gerenciamento de mobilidade empresarial (EMM, na sigla em inglês) ou integrador de soluções, leia este guia para adicionar o modo de tarefa de bloqueio à sua solução.
Visão geral
O Android pode executar tarefas de maneira imersiva, semelhante à forma de quiosque, com o modo de bloqueio de tarefas. É possível usar o modo de bloqueio de tarefas se estiver desenvolvendo um aplicativo de quiosque ou uma tela de início para apresentar uma coleção de apps. Quando o sistema é executado no modo de bloqueio de tarefas, os usuários do dispositivo normalmente não podem receber notificações, acessar apps que não estejam na lista de permissões nem voltar à tela inicial, a menos que ela esteja na lista de permissões.
Somente apps na lista de permissões por um controlador de política de dispositivo (DPC) podem ser executados quando o sistema está no modo de bloqueio de tarefas. Os apps são incluídos na lista de permissões porque o usuário do dispositivo nem sempre pode sair do modo de bloqueio de tarefas.
A forma como você combina o app na lista de permissões para o modo de tarefa de bloqueio e o DPC na lista de permissões vai depender do problema que você quer resolver. Veja alguns exemplos:
- Um único pacote de apps que combina um quiosque para apresentar conteúdo e um miniDPC (para adicionar à lista de permissões o modo de bloqueio de tarefas).
- Um DPC que faz parte de uma solução de gerenciamento de mobilidade empresarial, iniciando os apps para dispositivos móveis do cliente no modo de bloqueio de tarefas.
Disponibilidade
O sistema pode ser executado no modo de bloqueio de tarefas no Android 5.0 ou mais recente. A Tabela 1 mostra quais versões do Android são compatíveis com a lista de permissões por usuário.
Versão do Android | Administrações de DPC | Notes |
---|---|---|
Android 5.0 (nível 21 da API) ou mais recente | Dispositivo totalmente gerenciado | |
Android 8.0 (API de nível 26) ou mais recente | Usuário secundário afiliado | O usuário secundário precisa estar afiliado ao usuário principal. Consulte a visão geral de vários usuários. |
Android 9.0 (API de nível 28) ou mais recente | Usuário secundário |
No Android 9.0 ou versões mais recentes, um DPC pode iniciar a atividade de qualquer app no modo de bloqueio de tarefas. Nas versões anteriores, o app já precisa ser compatível com a inicialização da própria atividade no modo de bloqueio de tarefas.
Colocar apps na lista de permissões
Um DPC precisa colocar os apps na lista de permissões antes que eles possam ser usados no modo de bloqueio de tarefas. Chame
DevicePolicyManager.setLockTaskPackages()
para
adicionar apps à lista de permissões para o modo de tarefa de bloqueio, conforme mostrado no exemplo a seguir:
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);
Para descobrir os apps anteriormente permitidos para o modo de bloqueio de tarefas, um DPC pode chamar
DevicePolicyManager.getLockTaskPackages()
. Outros
apps podem chamar
DevicePolicyManager.isLockTaskPermitted()
para confirmar
se um pacote de app oferece suporte ao modo de bloqueio de tarefas.
Iniciar modo de bloqueio de tarefas
No Android 9.0 (API de nível 28) ou versões mais recentes, você pode iniciar a atividade de outro app no
modo de bloqueio de tarefas. Se uma atividade já estiver sendo executada em primeiro ou
segundo plano, ela precisará ser reiniciada. Chame
ActivityOptions.setLockTaskEnabled()
e forneça essas
opções ao iniciar a atividade. O snippet a seguir mostra uma maneira de fazer isso:
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()); }
Nas versões do Android anteriores à 9.0, um app inicia as próprias atividades no modo de bloqueio de
tarefas chamando Activity.startLockTask()
. Para chamar esse
método, a atividade precisa estar em execução em primeiro plano. Consulte Conceitos do ciclo de vida
da atividade. Portanto, sugerimos chamar o método
onResume()
de uma Activity
ou
Fragment
. Veja como você pode ligar para 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. } }
Não inicie o modo de tarefa de bloqueio quando o dispositivo estiver bloqueado, porque o usuário pode não
conseguir desbloquear o dispositivo. Você pode chamar métodos KeyguardManager
para
descobrir se o dispositivo está bloqueado e usar um callback de ciclo de vida de Activity
(como onResume()
, que é chamado após o desbloqueio) para
iniciar o modo de bloqueio de tarefas.
Um app no modo de bloqueio de atividades pode iniciar novas atividades desde que a atividade não inicie uma nova tarefa, exceto tarefas que iniciem um app da lista de permissões. Para entender como as tarefas estão relacionadas às atividades, leia o guia Entender as tarefas e a backstack.
Como alternativa, é possível declarar no arquivo de manifesto
do app como uma atividade vai se comportar quando
o sistema estiver sendo executado no modo de bloqueio de tarefas. Para que o sistema execute automaticamente
a atividade no modo de bloqueio de tarefas, defina o atributo
android:lockTaskMode
como if_whitelisted
, conforme
mostrado no exemplo a seguir.
<activity
android:name=".MainActivity"
android:lockTaskMode="if_whitelisted">
<!-- ... -->
</activity>
Para saber mais sobre a declaração de opções no arquivo de manifesto do app, leia
a referência lockTaskMode
.
Parar o modo de bloqueio de tarefas
Um DPC pode interromper remotamente o modo de bloqueio de tarefas removendo o pacote de apps da
lista de permissões. Chame
DevicePolicyManager.setLockTaskPackages()
no
Android 6.0 (API de nível 23) ou mais recente e omita o nome do pacote da
matriz da lista de permissões. Quando você atualiza a lista de permissões, o app retorna à tarefa anterior
na pilha.
Se uma atividade chamava startLockTask()
, ela pode chamar
Activity.stopLockTask()
para interromper o modo de bloqueio de tarefas. Esse método
funciona apenas para a atividade que iniciou o modo de bloqueio de tarefas.
Callbacks do ciclo de vida
Pode ser útil saber quando um app (em execução no mesmo usuário)
entra e sai do modo de bloqueio de tarefas. Para receber callbacks, modifique os
métodos de callback abaixo na subclasse DeviceAdminReceiver
do DPC:
onLockTaskModeEntering()
- Chamado depois que um app entra no modo de bloqueio de tarefas. É possível conseguir o nome do pacote de um
app usando o argumento
pkg
. onLockTaskModeExiting()
- Chamado depois que um app sai do modo de bloqueio de tarefas. Esse callback não recebe informações sobre o app.
Se você iniciar outro app no modo de bloqueio de tarefas, será necessário monitorar o status
de execução no seu próprio app. Para conferir se o app atual está sendo executado no modo de bloqueio
de tarefas, use os métodos em ActivityManager
, conforme mostrado no
exemplo a seguir:
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 ... }
Personalizar a interface
Quando um app é executado no modo de tarefa de bloqueio, a interface do usuário (IU) do sistema muda destas maneiras:
- A barra de status fica em branco, com notificações e informações do sistema ocultas.
- Os botões "Página inicial" e "Visão geral" estão ocultos.
- Outros apps não podem iniciar novas atividades.
- Se definida, a tela de bloqueio será desativada.
No Android 9.0 ou versões mais recentes, quando o modo de bloqueio de tarefas está ativado, seu DPC pode ativar
determinados recursos de IU do sistema no dispositivo, o que é útil para desenvolvedores que criam uma tela de início
personalizada. Chame
DevicePolicyManager.setLockTaskFeatures()
conforme mostrado
no snippet a seguir:
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);
O sistema desativa todos os recursos que você não inclui no argumento flags
. Os
recursos de interface ativados persistem entre as inicializações no modo de bloqueio de tarefas. Se o dispositivo
já estiver no modo de tarefa de bloqueio, todas as mudanças feitas nos recursos da tarefa de bloqueio
serão mostradas imediatamente. A Tabela 2 descreve os recursos da IU que você pode personalizar.
Recurso de interface do sistema | Descrição |
---|---|
LOCK_TASK_FEATURE_HOME
|
Mostra o botão home. Ativar para telas de início personalizadas: tocar em um botão home ativado não faz nada, a menos que você adicione a tela de início padrão do Android à lista de permissões. |
LOCK_TASK_FEATURE_OVERVIEW
|
Mostra o botão "Visão geral". Um toque nesse botão abre a tela Recentes. Se você ativar esse botão, também vai precisar ativar o botão home. |
LOCK_TASK_FEATURE_GLOBAL_ACTIONS
|
Ativa a caixa de diálogo de ações globais que aparece ao manter o
botão liga/desliga pressionado. O único recurso ativado quando
setLockTaskFeatures()
não é chamado. Um usuário normalmente não consegue desligar o dispositivo quando você
desativa essa caixa de diálogo. |
LOCK_TASK_FEATURE_NOTIFICATIONS
|
Ativa as notificações para todos os apps. Isso mostra ícones de notificação na barra de status, notificações de alerta e aba de notificações expansível. Se você ativar esse botão, também vai precisar ativar o botão home. O toque em ações de notificação e em botões que abrem novos painéis não funciona no modo de bloqueio de tarefas. |
LOCK_TASK_FEATURE_SYSTEM_INFO
|
Ativa a área de informações do sistema da barra de status, que contém indicadores, como conectividade, bateria e opções de som e vibração. |
LOCK_TASK_FEATURE_KEYGUARD
|
Ativa qualquer tela de bloqueio que possa ser definida no dispositivo. Normalmente, não é adequado para dispositivos com usuários públicos, como quiosques de informações ou sinalização digital. |
LOCK_TASK_FEATURE_NONE
|
Desativa todos os recursos de interface do sistema listados acima. |
Um DPC pode chamar
DevicePolicyManager.getLockTaskFeatures()
para conferir
a lista de recursos disponíveis em um dispositivo quando o modo de bloqueio de tarefas está ativado. Quando
um dispositivo sai do modo de tarefa de bloqueio, a interface do usuário retorna ao estado determinado
pelas políticas do dispositivo.
Bloquear janelas e sobreposições
Quando um app é executado no modo de tarefa de bloqueio, outros apps e serviços em segundo plano podem
criar novas janelas que o Android exibe na frente do app no modo de bloqueio de tarefas.
Apps e serviços criam essas janelas para mostrar avisos, caixas de diálogo e sobreposições à
pessoa que usa o dispositivo. O DPC pode evitar isso adicionando a
restrição de usuário DISALLOW_CREATE_WINDOWS
.
O exemplo abaixo mostra como fazer isso no
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); }
O DPC pode remover a restrição de usuário quando o dispositivo sair do modo de bloqueio de tarefas.
Outros recursos
Para saber mais sobre dispositivos dedicados, leia os seguintes documentos:
- Manual de dispositivos dedicados com mais exemplos para restringir os dispositivos dedicados e melhorar a experiência do usuário.
- A Visão geral de dispositivos dedicados é uma visão geral de dispositivos dedicados.
- O artigo Gerenciar vários usuários explica como compartilhar dispositivos entre usuários.