Perfis de trabalho

A plataforma Android permite que os dispositivos tenham trabalho do Google (às vezes chamados de perfis gerenciados). Um perfil de trabalho é controlado por um administrador de TI, e os recursos disponíveis são definidos separadamente funcionalidade do perfil principal do usuário. Essa abordagem permite que as organizações controlem o ambiente em que apps e dados específicos da empresa são executados no dispositivo de um usuário, permitindo que os usuários usem apps e perfis pessoais.

Esta lição mostra como modificar seu aplicativo para que ele funcione de forma confiável em um dispositivo com um perfil de trabalho. Você não precisa fazer nada além das práticas recomendadas comuns de desenvolvimento de apps. No entanto, alguns desses melhores práticas de segurança se tornam especialmente importantes em dispositivos com perfis de trabalho. Isso documento destaca os problemas que você precisa conhecer.

Visão geral

Os usuários geralmente querem usar os dispositivos pessoais em ambientes corporativos. Isso situação pode apresentar um dilema às organizações. Se o usuário puder usar o próprio dispositivo, a organização tem que se preocupar que informações confidenciais (como funcionários e-mails e contatos) estão em um dispositivo que a organização não controla.

Para resolver essa situação, o Android 5.0 (API de nível 21) permite que as organizações configurar perfis de trabalho. Se um dispositivo tiver um perfil de trabalho, o perfil configurações ficam sob o controle do administrador de TI. A O administrador de TI pode escolher quais apps são permitidos no perfil e controlar apenas quais recursos do dispositivo estão disponíveis para o perfil.

Se um dispositivo tiver um perfil de trabalho, os apps vão ter implicações em execução no dispositivo, independentemente do perfil em que o aplicativo é executado:

  • Por padrão, a maioria dos intents não passa de um perfil para outro. Se um em execução no perfil dispara um intent, não há gerenciador para o intent em esse perfil, e a intenção não pode passar para o outro perfil devido a restrições de perfil, a solicitação falhará e o aplicativo poderá ser desligado de maneira inesperada.
  • O administrador de TI do perfil pode limitar os apps do sistema disponíveis do seu perfil de trabalho. Essa restrição também pode resultar na ausência de um manipulador para algumas intents comuns no perfil de trabalho.
  • Como os perfis pessoal e de trabalho têm áreas de armazenamento separadas, URI de arquivo válido em um perfil não é válido no outro. Qualquer um as intents disparadas em um perfil podem ser tratadas no outro (dependendo do perfil). configurações), por isso, não é seguro anexar URIs de arquivos às intents.

Evitar intents com falha

Em um dispositivo com um perfil de trabalho, há restrições quanto à escolha das intents é possível passar de um perfil para outro. Na maioria dos casos, quando uma intent é acionada, desativada, ela é tratada no mesmo perfil em que é acionada. Se não houver gerenciador para a intent nesse perfil, ela não será processada, e o aplicativo que acionou, ele pode ser desligado inesperadamente, mesmo se houver um gerenciador para o no outro perfil.

O administrador do perfil pode escolher quais intents serão podem passar de um perfil para outro. Como o administrador de TI toma essa decisão, não será possível para saber com antecedência quais intents podem ultrapassar esse limite. A O administrador de TI define essa política e pode alterá-la a qualquer momento.

Antes de o aplicativo iniciar uma atividade, é preciso verificar se há um e resolução adequada. Você pode verificar se há uma resolução aceitável chamando Intent.resolveActivity(). Se não houver de resolver a intent, o método retorna null: Se o método não retornar nulo, há pelo menos uma maneira de a intent, e é seguro desencadeá-la. Nesse caso, o da intent poderia ser resolvida porque há um gerenciador no perfil atual ou porque a intent está permitida para passar para um manipulador no outro perfil. Para mais informações sobre resolver intents, consulte Intents comuns.

Por exemplo, se o app precisar definir timers, ele precisará verificar se há um gerenciador válido para a intent ACTION_SET_TIMER. Se o app não conseguir resolver a intent, ele deve realizar uma ação adequada (como mostrar um erro ).

Kotlin

fun startTimer(message: String, seconds: Int) {

    // Build the "set timer" intent
    val timerIntent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(packageManager) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent)

    }
}

Java

public void startTimer(String message, int seconds) {

    // Build the "set timer" intent
    Intent timerIntent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(getPackageManager()) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent);

    }
}

Compartilhar arquivos entre perfis

Às vezes, um app precisa conceder a outros apps acesso aos seus próprios arquivos. Por exemplo, um app de galeria de imagens pode querer compartilhar as imagens com editores. Normalmente, há duas maneiras de compartilhar um arquivo: com um arquivo URI ou um URI de conteúdo.

O URI de um arquivo começa com o prefixo file:, seguido pelo caminho absoluto do arquivo no armazenamento do dispositivo. No entanto, como o o perfil de trabalho e o pessoal usam áreas de armazenamento separadas, um URI de arquivo válido em um perfil não é válido no outro. Essa situação significa que, se você anexar um URI de arquivo a uma intent, e a intent será tratada no outro perfil; o gerenciador não poderá acessar o arquivo.

Em vez disso, compartilhe arquivos com URIs de conteúdo. URIs de conteúdo identificar o arquivo de maneira mais segura e compartilhável. O URI de conteúdo contém o caminho do arquivo, mas também a autoridade que fornece o arquivo e um número de ID identificando o arquivo. É possível gerar um ID de conteúdo para qualquer arquivo usando uma FileProvider: Você pode compartilhar esse conteúdo com outros apps, mesmo no outro perfil. O destinatário pode usar o campo Content ID para ter acesso ao arquivo real.

Por exemplo, veja como conseguir o URI de conteúdo de um arquivo específico URI:

Kotlin

// Open File object from its file URI
val fileToShare = File(fileUriToShare)

val contentUriToShare: Uri = FileProvider.getUriForFile(
        context,
        "com.example.myapp.fileprovider",
        fileToShare
)

Java

// Open File object from its file URI
File fileToShare = new File(fileUriToShare);

Uri contentUriToShare = FileProvider.getUriForFile(getContext(),
        "com.example.myapp.fileprovider", fileToShare);

Quando você chama o método getUriForFile(), é preciso incluir a autoridade do provedor do arquivo (neste exemplo, "com.example.myapp.fileprovider"), que é especificado na <provider> do manifesto do app. Para mais informações sobre como compartilhar arquivos com URIs de conteúdo, consulte Compartilhamento Arquivos.

Ouvir notificações

Geralmente, um aplicativo oferece Subclasse NotificationListenerService para receber callbacks do sistema sobre alterações nas notificações; Dispositivos com os perfis de trabalho podem afetar o funcionamento do NotificationListenerService com seu app.

Em um perfil de trabalho

Não é possível usar o NotificationListenerService de um app em execução no perfil de trabalho. Quando seu app é executado em um perfil de trabalho, o ignora a NotificationListenerService do app. No entanto, os apps em execução no perfil pessoal podem ouvir notificações.

Em um perfil pessoal

Quando o app for executado no perfil pessoal, talvez você não receba notificações para apps em execução no perfil de trabalho. Por padrão, todos os apps de perfil pessoal receber callbacks, mas um administrador de TI pode adicionar um ou mais perfis pessoais à lista de permissões; aos apps que permitem ouvir mudanças nas notificações. Em seguida, o sistema bloqueia que não estão na lista de permissões. No Android 8.0 (nível 26 da API) ou mais recente, uma política do dispositivo (DPC) que gerencia um perfil de trabalho pode impedir que o app ouça às notificações do perfil de trabalho usando o DevicePolicyManager método setPermittedCrossProfileNotificationListeners(). O app ainda recebe callbacks sobre notificações postadas no perfil.

Testar a compatibilidade do aplicativo com os perfis de trabalho

Teste seu app em um ambiente de perfil de trabalho para detectar problemas que causariam falha no app em um dispositivo com e perfis de trabalho. Testar em um dispositivo de perfil de trabalho é uma boa de garantir que seu aplicativo processe intents corretamente, sem acionar intents que não podem ser processados, ou seja, não se anexa URIs que não funcionam entre perfis e, portanto,

Fornecemos um app de exemplo, o TestDPC, que você pode usar para configurar um perfil de trabalho em um dispositivo Android executado Android 5.0 (nível 21 da API) e versões mais recentes. Esse app oferece uma maneira simples de testar seu app em um ambiente de perfil de trabalho. Você também pode usar esse app para configure o perfil de trabalho da seguinte maneira:

  • Especificar quais apps padrão estão disponíveis no perfil
  • Configurar quais intents podem passar de um perfil para outro o outro

Se você instalar manualmente um app usando um cabo USB em um dispositivo com do perfil de trabalho, o app é instalado nas duas versões perfil. Depois de instalar o aplicativo, você pode testá-lo no seguintes condições:

  • Se uma intent normalmente seria processada por um aplicativo padrão (por exemplo, o app de câmera), tente desativar esse app padrão no perfil de trabalho e verifique se o app lida com isso corretamente.
  • Se você disparar uma intent esperando que ela seja processada por outro app, tente ativar e desativar a permissão dessa intent para passar de um perfil para outra. Verifique se o app se comporta corretamente em ambas as circunstâncias. Se o intent não permitida para cruzar entre perfis, verifique o comportamento do aplicativo tanto quando há um gerenciador adequado no perfil do aplicativo e quando não há. Por exemplo, se o app disparar uma intent relacionada a um mapa, tente cada uma das seguintes opções: cenários:
    • O dispositivo permite que intents de mapa passem de um perfil para outro e há um gerenciador adequado no outro perfil (o perfil em que o aplicativo não em execução)
    • O dispositivo não permite que intents de mapa cruzem entre perfis, mas há é um gerenciador adequado no perfil do aplicativo
    • O dispositivo não permite que intents de mapa cruzem entre perfis e há não há gerenciador adequado para intents de mapa no perfil do dispositivo.
  • Se você anexar conteúdo a uma intent, verifique se ela se comporta corretamente tanto quando é tratada no perfil do aplicativo e quando passa entre de perfil.

Testar em perfis de trabalho: dicas e truques

Existem alguns truques que podem ser úteis ao testar em uma dispositivo com perfil de trabalho.

  • Como observado, quando você transfere um app por sideload em um dispositivo do perfil de trabalho, instalado nos dois perfis. Se quiser, você pode excluir o app de um perfil e deixar na outra.
  • A maioria dos comandos do gerenciador de atividades está disponível no shell do Android Debug Bridge (adb) Oferecer suporte à flag --user, que permite especificar qual usuário vai ser executado Ao especificar um usuário, você pode escolher se quer executar como o usuário principal não gerenciado. ou perfil de trabalho. Para mais informações, consulte ADB comandos do shell.
  • Para encontrar os usuários ativos em um dispositivo, use o gerenciador de pacotes adb list users. O primeiro número na string de saída é o ID do usuário, que pode ser usado com a sinalização --user. Para mais mais informações, consulte ADB Shell, Comandos.

Por exemplo, para encontrar os usuários em um dispositivo, execute este comando:

$ adb shell pm list users
UserInfo{0:Drew:13} running
UserInfo{10:Work profile:30} running

Neste caso, o usuário primário ("Drew") tem o ID de usuário 0, e o tem o ID de usuário 10. Para executar um app no perfil de trabalho, usaria um comando como este:

$ adb shell am start --user 10 \
-n "com.example.myapp/com.example.myapp.testactivity" \
-a android.intent.action.MAIN -c android.intent.category.LAUNCHER