Microsoft Intune guia do desenvolvedor do App SDK para Android

Observação

Você pode primeiro ler a visão geral do SDK do Aplicativo do Intune, que aborda os recursos atuais do SDK e descreve como se preparar para a integração em cada plataforma com suporte.

Para baixar o SDK, consulte Download the SDK files.

Se você tiver problemas com a integração do SDK do Aplicativo do Intune em seus aplicativos, envie uma solicitação de assistência GitHub.

O Microsoft Intune app SDK para Android permite que você incorpore políticas de proteção de aplicativos do Intune (também conhecidas como políticas de APP ou MAM) em seu aplicativo Android nativo. Um aplicativo gerenciado pelo Intune é integrado ao SDK do Aplicativo do Intune. Os administradores do Intune podem implantar facilmente políticas de proteção de aplicativos em seu aplicativo gerenciado pelo Intune quando o Intune gerencia ativamente o aplicativo.

O que está no SDK

O SDK do Aplicativo do Intune consiste nos seguintes arquivos:

  • Microsoft.Intune.MAM.SDK.aar: os componentes do SDK, com exceção dos arquivos JAR da Biblioteca de Suporte.
  • Microsoft.Intune.MAM.SDK.DownlevelStubs.aar: Este AAR contém stubs para classes de sistema Android que estão presentes apenas em dispositivos mais novos, mas que são referenciados por métodos [em MAMActivity]. Dispositivos mais novos ignorarão essas classes de stub. Esse AAR só será necessário se o aplicativo executar a reflexão sobre as classes que derivam de , e a maioria dos aplicativos não precisar MAMActivity incluí-lo. O AAR contém regras proGuard para excluir todas as classes.
  • com.microsoft.intune.mam.build.jar: um plug-in gradle que ajuda na integração do SDK.
  • CHANGELOG.md: fornece um registro das alterações feitas em cada versão do SDK.
  • THIRDPARTYNOTICES.TXT: um aviso de atribuição que reconhece o código DES de terceiros e/ou que será compilado em seu aplicativo.

Requisitos

Versões do Android

O SDK dá suporte total à API Android 28 (Android 9.0) por meio da API Android 31 (Android 12.0). Para direcionar a API do Android 31, você deve usar o SDK do Aplicativo do Intune v8.0 ou posterior. As APIs 23 a 27 têm suporte limitado. O uso de MAM e Portal da Empresa não são suportados abaixo da API Android 23. Se seu aplicativo declarar um nível de API abaixo da API 23, o SDK do MAM não bloqueará o uso do aplicativo para usuários que não são direcionados pela política minSdkVersion do MAM.

AndroidX

A partir do SDK 8.0.0 do APP do Intune em diante, a Biblioteca de Suporte do Android herdada não é mais suportada. Espera-se que os aplicativos usem o AndroidX (diretamente ou por meio do Jetifier) se precisarem da funcionalidade da biblioteca de suporte.

Aplicativo do Portal da Empresa

O SDK do Aplicativo do Intune para Android depende da presença do aplicativo Portal da Empresa no dispositivo para habilitar políticas de proteção de aplicativos. O Portal da Empresa recupera políticas de proteção de aplicativos do serviço Intune. Quando o aplicativo é inicializado, ele carrega a política e o código para impor essa política do Portal da Empresa.

Observação

Quando o Portal da Empresa aplicativo não está no dispositivo, um aplicativo gerenciado pelo Intune se comporta da mesma forma que um aplicativo normal que não dá suporte a políticas de proteção de aplicativos do Intune.

Para a proteção do aplicativo __ sem registro no dispositivo, o usuário não é necessário para registrar o dispositivo usando o Portal da Empresa aplicativo.

Integração do SDK

Importante

O Intune lança regularmente atualizações para o SDK do Aplicativo do Intune. Verifique regularmente o SDK do Aplicativo do Intune para Android para atualizações e incorpore ao seu ciclo de lançamento de desenvolvimento de software para garantir que seus aplicativos deem suporte às configurações mais recentes da Política de Proteção de Aplicativos.

Aplicativos de exemplo

Exemplos de como integrar-se ao SDK do Aplicativo do Intune incluem:

Fazendo referência a bibliotecas de aplicativos do Intune

O SDK do Aplicativo do Intune é uma biblioteca padrão do Android sem dependências externas. Microsoft.Intune.MAM.SDK.aar contém as interfaces necessárias para uma habilitação de política de proteção de aplicativos e o código necessário para interoperar com o aplicativo Microsoft Intune Portal da Empresa.

Microsoft.Intune.MAM.SDK.aar deve ser especificado como uma referência de biblioteca Android. Para fazer isso, abra seu projeto de aplicativo no Android Studio e vá para Arquivo > Novo > Novo módulo e selecione Importar . JAR/. Pacote AAR. Em seguida, selecione nosso pacote de arquivo morto do Android Microsoft.Intune.MAM.SDK.aar para criar um módulo para o . Tipo de arquivo AAR. Clique com o botão direito do mouse no módulo ou módulos que contêm o código do aplicativo e vá para a guia Dependências do Módulo Configurações+ ícone Dependência do módulo > Selecione o > > > módulo AAR do SDK do MAM que você acabou de criar > OK . Isso garantirá que seu módulo seja compilado com o SDK MAM ao compilar seu projeto.

ProGuard

Se o ProGuard (ou qualquer outro mecanismo de redução/ofuscação) for usado como uma etapa de com build, o SDK terá regras de configuração adicionais que devem ser incluídas. Ao incluir o . AAR em sua com build, nossas regras são integradas automaticamente à etapa de proguard e os arquivos de classe necessários são mantidos.

A Biblioteca de Autenticação da Microsoft (MSAL) pode ter suas próprias restrições proGuard. Se seu aplicativo integra o MSAL, você deve seguir a documentação do MSAL sobre essas restrições.

Imposição de política

O SDK do Aplicativo do Intune é uma biblioteca Android que permite que seu aplicativo suporte e participe da imposição das políticas do Intune.

A maioria das políticas é imposta semi-automaticamente, mas determinadas políticas exigem participação explícita do seu aplicativo para impor. Independentemente de você executar a integração de origem ou usar ferramentas de com build para integração, as políticas que exigem participação explícita precisarão ser codificadas.

Para políticas que são impostas automaticamente, os aplicativos são necessários para substituir a herança de várias classes base do Android por herança de equivalentes MAM e substituir chamadas para determinadas classes de serviço do sistema Android por chamadas para equivalentes de MAM. As substituições específicas necessárias são detalhadas abaixo e podem ser executadas manualmente com a integração de origem ou executadas automaticamente por meio de ferramentas de composição.

Criar ferramentas

O SDK fornece ferramentas de composição (um plug-in para builds gradle e uma ferramenta de linha de comando para builds que não são gradle) que executam substituições equivalentes de MAM automaticamente. Essas ferramentas transformam os arquivos de classe gerados Java compilação e não modificam o código-fonte original.

As ferramentas executam somente substituições diretas. Eles não executam integrações SDK mais complexas, como Save-As Policy, Multi-Identity, Registro do App-WE,modificações do AndroidManifest ou configuração MSAL, portanto, elas devem ser concluídas antes que o aplicativo seja totalmente habilitado para o Intune. Revise cuidadosamente o restante desta documentação para ver se há pontos de integração relevantes para seu aplicativo.

Observação

É bom executar as ferramentas em um projeto que já realizou a integração parcial ou completa de origem do SDK do MAM por meio de substituições manuais. Seu projeto ainda deve listar o SDK do MAM como uma dependência.

Plug-in de com build gradle

Se seu aplicativo não for construído com gradle, pule para Integração com a Ferramenta de Linha de Comando.

O plug-in SDK do aplicativo é distribuído como parte do SDK como GradlePlugin/com.microsoft.intune.mam.build.jar. Para gradle conseguir encontrar o plug-in, ele deve ser adicionado ao classpath buildscript. O plug-in depende de Javassist, que também deve ser adicionado. Para adicioná-lo ao classpath, adicione o seguinte à raiz build.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "org.javassist:javassist:3.27.0-GA"
        classpath files("$PATH_TO_MAM_SDK/GradlePlugin/com.microsoft.intune.mam.build.jar")
    }
}

Em seguida, no build.gradle arquivo do seu projeto APK, basta aplicar o plug-in como

apply plugin: 'com.microsoft.intune.mam'

Por padrão, o plug-in operará project em dependências e bibliotecas externas. Desde o SDK 8.0, não é mais possível processar as bibliotecas seletivamente. Todos são processados. Compilação de teste não afetada. A configuração pode ser fornecida para listar

  • Projetos a excluir
  • Classes específicas para excluir do processamento
  • Variantes a excluir do processamento. Eles podem se referir a um nome de variante completo ou a um único sabor. Por exemplo,
    • se seu aplicativo tiver tipos de com build e debug release com os sabores { , } savory e { , } você poderia sweet vanilla chocolate especificar
    • savory para excluir todas as variantes com o sabor de açafrão ou savoryVanillaRelease excluir apenas essa variante exata.

Exemplo de build.gradle parcial


apply plugin: 'com.microsoft.intune.mam'

dependencies {
    implementation project(':product:FooLib')
    implementation project(':product:foo-project')
    implementation "com.microsoft.bar:baz:1.0.0"

    // Include the MAM SDK
    implementation files("$PATH_TO_MAM_SDK/Microsoft.Intune.MAM.SDK.aar")
}
intunemam {
    excludeProjects = [':product:FooLib']
    excludeClasses = ['com.contoso.SplashActivity']
    excludeVariants=['savory']
}

Isso teria os seguintes efeitos:

  • :product:FooLib não é reescrito porque está incluído em excludeProjects
  • :product:foo-project é reescrito, exceto com.contoso.SplashActivity pelo qual é ignorado porque ele está em excludeClasses
  • com.microsoft.bar:baz.1.0.0 é reescrito porque todas as bibliotecas externas estão incluídas para processamento.

Relatórios

O plug-in de com build pode gerar um relatório html das alterações feitas. Para solicitar a geração deste relatório, report = true especifique no bloco intunemam de configuração. Se gerado, o relatório será gravado outputs/logs no diretório de com build.

intunemam {
    report = true
}

Verificação

O plug-in de com build pode executar verificação adicional para procurar possíveis erros nas classes de processamento. Para solicitar isso, verify = true especifique no bloco intunemam de configuração. Observe que isso pode adicionar vários segundos ao tempo decordo pela tarefa do plug-in.

intunemam {
    verify = true
}

Builds incrementais

Para habilitar o suporte para a criação incremental, incremental = true especifique no bloco intunemam de configuração. Esse é um recurso experimental destinado a aumentar o desempenho da com build visando processar apenas os arquivos de entrada que foram alterados. A configuração padrão é false .

intunemam {
    incremental = true
}

Dependências

O plug-in de gradle tem uma dependência de Javassist, que deve estar disponível para a resolução de dependência de Gradle (conforme descrito acima). O Javassist é usado somente no momento da com build ao executar o plug-in. Nenhum código Javassist será adicionado ao seu aplicativo.

Observação

Você deve estar usando a versão 3.6.1 ou mais recente do plug-in do Android Gradle e gradle 5.6.4 ou mais recente.

Ao consumir o MAM SDK 8.0.0+, você deve garantir que o seguinte seja definido em sua configuração gradle:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

Ferramenta de com build de linha de comando

Se sua com build usar Gradle, pule para a próxima seção.

A ferramenta de com build de linha de comando está disponível na BuildTool pasta do drop SDK. Ele executa a mesma função que o plug-in Gradle detalhado acima, mas pode ser integrado a sistemas de com build personalizados ou não-Gradle. Como é mais genérico, é mais complexo invocar, portanto, o plug-in Gradle deve ser usado quando for possível fazer isso.

Usando a Command-Line Tool

A ferramenta de linha de comando pode ser invocada usando os scripts auxiliares fornecidos localizados no BuildTool\bin diretório.

A ferramenta espera os seguintes parâmetros.

Parâmetro Obrigatório Descrição
--input Sim Uma lista delimitada por pontos e vírgulas de arquivos de jar e diretórios de arquivos de classe a ser modificados. Isso deve incluir todos os jars/diretórios que você pretende reescrever.
--output Sim Uma lista delimitada por dois pontos dos arquivos de jar e diretórios para armazenar as classes modificadas. Deve haver uma entrada de saída por entrada de entrada e elas devem ser listadas em ordem.
--classpath Sim O classpath de com build. Isso pode conter ambos os jarros e diretórios de classe.
--processed Não Uma lista delimitada por pontos e vírgulas de arquivos de jar e diretórios contendo classes que já foram processadas por uma invocação anterior da ferramenta de com build.
--excludeClasses Não Uma lista delimitada por dois pontos e vírgulas que contém os nomes das classes que devem ser excluídas da reescrita.
--report Não Diretório para escrever um relatório HTML sobre classes modificadas para. Se não for especificado, nenhum relatório será gravado.

A opção --processed opcional é usada para habilitar builds incrementais. O conjunto de arquivos/diretórios listados aqui deve ser desarticulado com as listas de entrada e classpath.

Observação

Em sistemas unix-like e vírgulas é um separador de comando. Para evitar que o shell separação de comandos, certifique-se de escapar de cada e vírgula com ' ou quebrar o parâmetro ' completo entre aspas.

Invocação Command-Line Ferramenta de Exemplo

> BuildTool\bin\BuildTool.bat --input build\product-foo-project;libs\bar.jar --output mam-build\product-foo-project;mam-build\libs\bar.jar --classpath build\zap.jar;libs\Microsoft.Intune.MAM.SDK\classes.jar;%ANDROID_SDK_ROOT%\platforms\android-27\android.jar --excludeClasses com.contoso.SplashActivity

Isso teria os seguintes efeitos:

  • o product-foo-project diretório é reescrito para mam-build\product-foo-project
  • bar.jar é reescrito para mam-build\libs\bar.jar
  • zap.jar não é reescrito porque ele só está listado em --classpath
  • A com.contoso.SplashActivity classe não é reescrito mesmo se ela estiver em --input

Observação

No momento, a ferramenta de com build não dá suporte a arquivos aar. Se o sistema de com build ainda não extrai ao lidar com arquivos aar, você precisará fazer isso antes de invocar classes.jar a ferramenta de com build.

Substituições de classe e método

Observação

Os aplicativos devem integrar-se à ferramenta de composição do SDK, que executará todas essas substituições automaticamente (exceto para substituições de manifesto

As classes base do Android devem ser substituídas por seus respectivos equivalentes MAM para habilitar o gerenciamento do Intune. As classes SDK vivem entre a classe base do Android e a própria versão derivada do aplicativo dessa classe. Por exemplo, uma atividade de aplicativo pode acabar com uma hierarquia de herança que se parece com: Activity > MAMActivity > AppSpecificActivity . A camada MAM filtra chamadas para operações do sistema para fornecer ao aplicativo uma visão gerenciada do mundo.

Além das classes base, algumas classes que seu aplicativo pode usar sem derivar (por exemplo, ) também têm equivalentes MAM necessários, e algumas chamadas de método também devem ser MediaPlayer substituídas. Os detalhes precisos são dados abaixo.

Observação

Se o aplicativo estiver se integrando à ferramenta de composição do SDK, as seguintes substituições de classe e método serão executadas automaticamente.

Classe base do Android Substituição do SDK do Aplicativo do Intune
android.app.Activity MAMActivity
android.app.ActivityGroup MAMActivityGroup
android.app.AliasActivity MAMAliasActivity
android.app.Application MAMApplication
android.app.Dialog MAMDialog
android.app.AlertDialog.Builder MAMAlertDialogBuilder
android.app.DialogFragment MAMDialogFragment
android.app.ExpandableListActivity MAMExpandableListActivity
android.app.Fragment MAMFragment
android.app.IntentService MAMIntentService
android.app.LauncherActivity MAMLauncherActivity
android.app.ListActivity MAMListActivity
android.app.ListFragment MAMListFragment
android.app.NativeActivity MAMNativeActivity
android.app.PendingIntent MAMPendingIntent (consulte Pending Intent)
android.app.Service MAMService
android.app.TabActivity MAMTabActivity
android.app.TaskStackBuilder MAMTaskStackBuilder
android.app.backup.BackupAgent MAMBackupAgent
android.app.backup.BackupAgentHelper MAMBackupAgentHelper
android.app.backup.FileBackupHelper MAMFileBackupHelper
android.app.backup.SharePreferencesBackupHelper MAMSharedPreferencesBackupHelper
android.content.BroadcastReceiver MAMBroadcastReceiver
android.content.ContentProvider MAMContentProvider
android.os.Binder MAMBinder (Somente necessário se o Binder não for gerado a partir de uma interface AIDL (Linguagem de Definição de Interface do Android)
android.media.MediaPlayer MAMMediaPlayer
android.media.MediaMetadataRetriever MAMMediaMetadataRetriever
android.media.MediaRecorder MAMMediaRecorder
android.provider.DocumentsProvider MAMDocumentsProvider
android.preference.PreferenceActivity MAMPreferenceActivity
android.support.multidex.MultiDexApplication MAMMultiDexApplication
android.widget.PopupWindow MAMPopupMenu
android.widget.PopupWindow MAMPopupWindow
android.widget.ListPopupWindow MAMListPopupWindow
android.widget.TextView MAMTextView
android.widget.AutoCompleteTextView MAMAutoCompleteTextView
android.widget.CheckedTextView MAMCheckedTextView
android.widget.EditText MAMEditText
android.inputmethodservice.ExtractEditText MAMExtractEditText
android.widget.MultiAutoCompleteTextView MAMMultiAutoCompleteTextView
android.view.ViewGroup MAMViewGroup

Observação

Mesmo que seu aplicativo não precise de sua própria classe Application derivada, consulte MAMApplication abaixo

Métodos renomeados

Em muitos casos, um método disponível na classe Android foi marcado como final na classe de substituição do MAM. Nesse caso, a classe de substituição do MAM fornece um método nomeado da mesma forma (geralmente sufixo com ) que você MAM deve substituir. Por exemplo, ao derivar de MAMActivity, em vez de substituir e chamar onCreate() , deve substituir e chamar super.onCreate() Activity onMAMCreate() super.onMAMCreate() . O Java compilador deve impor as restrições finais para evitar a substituição acidental do método original em vez do equivalente MAM.

MAMApplication

Se seu aplicativo criar uma subclasse android.app.Application de , o plug-in de com build transformará sua classe de aplicativo. Se o aplicativo não fizer uma subclasse, você deverá definir como o android.app.Application atributo na marca AndroidManifest.xml do seu "com.microsoft.intune.mam.client.app.MAMApplication" "android:name" <application> usuário.

PendingIntent

Em vez PendingIntent.get* de , você deve usar o MAMPendingIntent.get* método. Depois disso, você pode usar o resultado PendingIntent como de costume.

Serviços de Sistema Empacotado

Para algumas classes de serviço do sistema, é necessário chamar um método estático em uma classe de wrapper MAM em vez de invocar diretamente o método desejado na instância de serviço. Por exemplo, uma chamada para getSystemService(ClipboardManager.class).getPrimaryClip() deve se tornar uma chamada para MAMClipboardManager.getPrimaryClip(getSystemService(ClipboardManager.class) . Não é recomendável fazer essas substituições manualmente. Em vez disso, deixe o BuildPlugin fazer isso.

Classe Android Substituição do SDK do Aplicativo do Intune
android.content.ClipboardManager MAMClipboard
android.content.ContentProviderClient MAMContentProviderClientManagement
android.content.ContentResolver MAMContentResolverManagement
android.content.pm.PackageManager MAMPackageManagement
android.app.DownloadManager MAMDownloadManagement
android.print.PrintManager MAMPrintManagement
android.support.v4.print.PrintHelper MAMPrintHelperManagement
android.view.View MAMViewManagement
android.view.Window MAMWindowManagement
android.view.DragEvent MAMDragEventManagement
android.app.NotificationManager MAMNotificationManagement
android.support.v4.app.NotificationManagerCompat MAMNotificationCompatManagement
android.app.blob.BlobStoreManager MAMBlobStoreManager
android.app.blob.BlobStoreManager.Session MAMBlobStoreManager.Session

Algumas classes têm a maioria de seus métodos empacotado, por exemplo, , , e enquanto outras classes têm apenas um ou dois métodos ClipboardManager ContentProviderClient empacotado, por ContentResolver PackageManager DownloadManager PrintManager exemplo, , , , PrintHelper , e View DragEvent NotificationManager NotificationManagerCompat . Consulte APIs expostas pelas classes equivalentes do MAM para o método exato se você não usar o BuildPlugin.

Substituições de manifesto

Pode ser necessário executar algumas das substituições de classe acima no manifesto, bem como no Java código. Observação especial:

  • Referências de manifesto a android.support.v4.content.FileProvider serem substituídas por com.microsoft.intune.mam.client.support.v4.content.MAMFileProvider .

Bibliotecas AndroidX

Com o Android P, o Google anuncia um novo conjunto (renomeado) de bibliotecas de suporte chamada AndroidX, e a versão 28 é a última grande versão das bibliotecas android.support existentes.

Ao contrário das versões de suporte para android, não fornecemos variantes MAM das bibliotecas AndroidX. Em vez disso, o AndroidX é tratado como qualquer outra biblioteca externa e reescrito. Para builds gradle, isso é feito automaticamente. As invocações da ferramenta de linhas de comando devem listar explicitamente todos os arquivos de jar.

Solução de problemas de migração androidx

Ao migrar seu aplicativo integrado ao SDK para o AndroidX, você pode encontrar um erro como o seguinte:

incompatible types: android.support.v7.app.ActionBar cannot be converted to androidx.appcompat.app.ActionBar

Esses erros podem ocorrer porque seu aplicativo faz referência às classes de suporte do MAM. As classes de suporte do MAM quebram as classes de suporte do Android que foram movidas no AndroidX. Para combater esses erros, substitua todas as referências de classe de suporte do MAM por seus equivalentes AndroidX. Isso pode ser feito removendo primeiro as dependências da biblioteca de suporte do MAM dos arquivos de com build do Gradle. As linhas em questão terão a seguinte aparência:

implementation "com.microsoft.intune.mam:android-sdk-support-v4:$intune_mam_version"
implementation "com.microsoft.intune.mam:android-sdk-support-v7:$intune_mam_version"

Em seguida, corrige os erros de tempo de compilação resultantes substituindo todas as referências a classes MAM nos pacotes e por com.microsoft.intune.mam.client.support.v7 com.microsoft.intune.mam.client.support.v4 seus equivalentes AndroidX. Por exemplo, as referências a MAMAppCompatActivity serem alteradas para AndroidX. AppCompatActivity Conforme discutido acima, o plug-in/ferramenta de compilação do MAM reescreverá automaticamente as classes nas bibliotecas AndroidX com os equivalentes MAM apropriados em tempo de compilação.

Registrar em log

O registro em log deve ser inicializado mais cedo para obter o maior valor de dados registrados. Application.onMAMCreate() normalmente é o melhor local para inicializar o registro em log.

Para receber logs de MAM em seu aplicativo, crie um manipulador de Java e adicione-o ao MAMLogHandlerWrapper. Isso invocará publish() o manipulador de aplicativos para cada mensagem de log.

/**
 * Global log handler that enables fine grained PII filtering within MAM logs.  
 *
 * To start using this you should build your own log handler and add it via
 * MAMComponents.get(MAMLogHandlerWrapper.class).addHandler(myHandler, false);  
 *
 * You may also remove the handler entirely via
 * MAMComponents.get(MAMLogHandlerWrapper.class).removeHandler(myHandler);
 */
public interface MAMLogHandlerWrapper {
    /**
     * Add a handler, PII can be toggled.
     *
     * @param handler handler to add.
     * @param wantsPII if PII is desired in the logs.    
     */
    void addHandler(final Handler handler, final boolean wantsPII);

    /**
     * Remove a handler.
     *
     * @param handler handler to remove.
     */
    void removeHandler(final Handler handler);
}

Informações de diagnóstico

Os aplicativos podem invocar o método que inicia uma atividade exibindo a interface do usuário para coletar Portal da Empresa logs e exibir MAMPolicyManager.showDiagnostics(context) diagnósticos de MAM. Esse é um recurso opcional que pode ajudar na depuração.

Quando Portal da Empresa não estiver instalado no dispositivo, uma caixa de diálogo será solicitado a informar ao usuário que essas informações não estão disponíveis no momento. Quando os aplicativos são gerenciados pela política do MAM, as configurações de política de MAM detalhadas serão exibidas.

Modo Estrito MAM

O Modo Estrito do MAM fornece um mecanismo para detectar "odores" no uso de aplicativos de APIs de MAM ou APIs de plataforma restritas ao MAM. Ela é livremente padronada após StrictMode do Android e executa um conjunto de verificações que levantam erros quando falham. Não se destina a ser deixado habilitado em builds de produção, mas você é fortemente incentivado a usá-lo em builds de desenvolvimento, depuração e/ou dogfood internos do seu aplicativo.

Para habilitar, chame

MAMStrictMode.enable();

no início da inicialização do aplicativo (por Application.onCreate exemplo, ).

Quando uma verificação do Modo Estrito do MAM falhar, tente determinar se é um problema real que pode ser corrigido em seu aplicativo ou um falso positivo. Se você acredita que é um falso positivo ou não tem certeza, avise a equipe do MAM do Intune. Isso nos permitirá garantir que concordemos com a determinação de falso positivo e para tentar melhorar a detecção para versões futuras. Para suprimir falsos positivos, desabilite a verificação de falha (mais informações abaixo).

Tratamento de violações

Quando uma verificação falha, ela executa um MAMStrictViolationHandler. O manipulador padrão lança um Error , que é esperado para quebrar o aplicativo. Isso é para tornar as falhas o mais barulhento possível e se encaixa com a intenção de que o modo estrito não deve ser habilitado em builds de produção.

Se seu aplicativo quiser lidar com violações de forma diferente, ele pode fornecer seu próprio manipulador chamando:

MAMStrictMode.global().setHandler(handler);

onde handler implementa MAMStrictViolationHandler .

Suprimindo verificações

Se uma verificação falhar em uma situação em que seu aplicativo não está fazendo nada incorreto, informe-a conforme mencionado acima. Em alguns momentos, no entanto, pode ser necessário desabilitar a verificação encontrando um falso positivo, pelo menos enquanto aguarda um SDK atualizado. A verificação que falhou será mostrada no erro gerado pelo manipulador padrão ou será passada para um manipulador personalizado se definido.

A supressão pode ser feita globalmente, mas é preferível desabilitar temporariamente por thread no site de chamada específico. Os exemplos a seguir mostram várias maneiras de desabilitar MAMStrictCheck.IDENTITY_NO_SUCH_FILE MAMStrictCheck (gerado se uma tentativa for feita para proteger um arquivo que não existe).

Per-Thread Supressão Temporária

Esse é o mecanismo de supressão preferencial.

try (StrictScopedDisable disable = MAMStrictMode.thread().disableScoped(MAMStrictCheck.IDENTITY_NO_SUCH_FILE)) {
    // Perform the operation which raised a violation here
}
// The check is no longer disabled once the block exits

Per-Thread Supressão Permanente

MAMStrictMode.thread().disable(MAMStrictCheck.IDENTITY_NO_SUCH_FILE);

Supressão global (em todo o processo)

MAMStrictMode.global().disable(MAMStrictCheck.IDENTITY_NO_SUCH_FILE);

Habilitar recursos que exigem participação do aplicativo

Há algumas políticas de proteção de aplicativos que o SDK não pode impor por conta própria:

  • Impor restrições ao salvar arquivos no armazenamento local ou na nuvem.
  • Impor restrições à abertura de arquivos do armazenamento local ou na nuvem.
  • Impor restrições ao conteúdo em notificações.

Seu aplicativo deve usar os métodos na interface AppPolicy para perguntar se essas ações são permitidas. Para testar se é permitido salvar ou abrir um arquivo/documento, use getIsSaveToLocationAllowed e getIsOpenFromLocationAllowed. Para determinar restrições ao conteúdo da notificação, use getNotificationRestriction . Exemplos expandidos para todos esses cenários são dados posteriormente nesta seção.

Observe que os métodos no AppPolicy que não pertencem às políticas acima fornecem informações que seu aplicativo pode usar para apresentar uma melhor experiência do usuário, mas não são necessários para a aplicação da política. Por exemplo, AppPolicy expõe informações sobre políticas de PIN e captura de tela, mas elas são impostas automaticamente.

Para recuperar uma AppPolicy instância, use um dos [métodos MAMPolicyManager.]

Observação

MAMPolicyManager sempre retornará uma Política de Aplicativo não nulo, mesmo se o dispositivo ou aplicativo não estiver sob uma política de gerenciamento do Intune.

Exemplo: Determinar se o PIN é necessário para o aplicativo

Se o aplicativo tiver sua própria experiência de usuário pin, talvez você queira desabilitá-lo se o administrador de TI tiver configurado o SDK para solicitar um PIN de aplicativo. Para determinar se o administrador de IT implantou a política de PIN do aplicativo para este aplicativo, para o usuário final atual, chame o seguinte método:


MAMPolicyManager.getPolicy(currentActivity).getIsPinRequired();

Exemplo: Determinar o usuário principal do Intune

Além das APIs expostas no AppPolicy, o nome principal do usuário (UPN) também é exposto pela API getPrimaryUser()SaveLocation definida dentro da interface MAMUserInfo. Para obter o UPN, chame o seguinte:

MAMComponents.get(MAMUserInfo.class).getPrimaryUser();

Exemplo: transferência de dados entre aplicativos e locais de armazenamento de dispositivo ou nuvem

Muitos aplicativos implementam recursos que permitem que o usuário final salve dados ou abra dados do armazenamento de arquivos local ou serviços de armazenamento em nuvem. O SDK do Aplicativo do Intune permite que os administradores de IT se protejam contra a entrada e o vazamento de dados aplicando restrições de política conforme eles se enquadram em sua organização.

A participação do aplicativo é necessária para habilitar o recurso. Se seu aplicativo permitir salvar em locais pessoais ou na nuvem diretamente do aplicativo ou permitir que os dados sejam abertos diretamente no aplicativo, você deverá implementar o recurso respectivo para garantir que o administrador de TI possa controlar se é permitido salvar/abrir de um local.

Salvar no armazenamento de dispositivo ou nuvem

A API abaixo permite que o aplicativo saiba se salvar em um armazenamento pessoal é permitido pela política atual do administrador do Intune.

Para determinar se a política é imposta, faça a seguinte chamada:

MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(
SaveLocation service, String username);

O service parâmetro deve ser um dos seguintes valores SaveLocation:

  • SaveLocation.ONEDRIVE_FOR_BUSINESS
  • SaveLocation.SHAREPOINT
  • SaveLocation.LOCAL
  • SaveLocation.ACCOUNT_DOCUMENT
  • SaveLocation.OTHER

Para determinar se ou deve ser passado para ver locais desconhecidos ou não ACCOUNT_DOCUMENT na lista para obter mais OTHER getIsSaveToLocationAllowed informações.

Para o username parâmetro, consulte Username for data transfer para obter mais informações.

O método anterior de determinar se a política de um usuário permitia que eles salvam dados em vários locais estava dentro getIsSaveToPersonalAllowed() da mesma classe AppPolicy. Esta função agora está preterida e não deve ser usada, a invocação a seguir é equivalente a getIsSaveToPersonalAllowed() :

MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(SaveLocation.LOCAL, null);

Abrindo dados de um local de armazenamento local ou em nuvem

A API abaixo permite que o aplicativo saiba se a abertura de um armazenamento pessoal é permitida pela política atual do administrador do Intune.

Para determinar se a política é imposta, faça a seguinte chamada:

MAMPolicyManager.getPolicy(currentActivity).getIsOpenFromLocationAllowed(
OpenLocation location, String username);

O location parâmetro deve ser um dos seguintes valores OpenLocation:

  • OpenLocation.ONEDRIVE_FOR_BUSINESS
  • OpenLocation.SHAREPOINT
  • OpenLocation.CAMERA
  • OpenLocation.LOCAL
  • OpenLocation.ACCOUNT_DOCUMENT
  • OpenLocation.OTHER

O OpenLocation.CAMERA local deve ser passado quando o aplicativo estiver abrindo dados da câmera. O OpenLocation.LOCAL local deve ser passado quando o aplicativo estiver abrindo dados do armazenamento externo no dispositivo local. O local deve ser passado quando o aplicativo estiver abrindo dados que pertencem a uma AAD OpenLocation.ACCOUNT_DOCUMENT conta assinada no aplicativo.

Para determinar se ou deve ser passado para ver locais desconhecidos ou não ACCOUNT_DOCUMENT na lista para obter mais OTHER getIsOpenFromLocationAllowed informações.

Para o username parâmetro, consulte Username for data transfer para obter mais informações.

Locais desconhecidos ou não listados

Quando o local desejado não estiver listado nas enumerações ou for desconhecido, há duas opções para o parâmetro SaveLocation OpenLocation e service / location ACCOUNT_DOCUMENT OTHER . ACCOUNT_DOCUMENTdeve ser usado quando os dados pertencem a uma conta AAD assinada no aplicativo, mas não é ou deve ser usada quando esse não ONEDRIVE_FOR_BUSINESS SHAREPOINT for o OTHER caso.

É importante esclarecer a distinção entre a conta gerenciada e uma conta que compartilha o UPN da conta gerenciada. Por exemplo, uma conta gerenciada com UPN "user@contoso.com" assinada no OneDrive não é a mesma que uma conta com UPN "user@contoso.com" Dropbox. Se um serviço desconhecido ou não na lista for acessado entrando na conta gerenciada (por exemplo, "user@contoso.com" OneDrive), ele deverá ser representado pelo ACCOUNT_DOCUMENT local. Se o serviço desconhecido ou não estiver na lista entrar por meio de outra conta (por exemplo, "user@contoso.com" Dropbox), ele não está acessando o local com uma conta gerenciada e deve ser representado pelo OTHER local.

Nome de usuário para transferência de dados

Ao verificar a política de salvar, o deve ser username o UPN/nome de usuário/email associado ao serviço de nuvem que está sendo salvo ( não necessariamente o mesmo que o usuário que possui o documento que está sendo salvo). SaveLocation.LOCAL não é um serviço de nuvem e deve ser sempre usado com um parâmetro null de nome de usuário.

Ao verificar a política aberta, deve ser o UPN/nome de usuário/email associado ao arquivo ou serviço de nuvem que username está sendo aberto. OpenLocation.LOCAL não é um local de serviço de nuvem, mas pode ser marcado com uma identidade para indicar a propriedade. Ao abrir um arquivo do armazenamento local, o proprietário do arquivo deve sempre ser considerado, pois a política de economia do proprietário do arquivo pode ou não permitir que outros usuários abram o arquivo. Para arquivos marcados por identidade, username deve ser a identidade do proprietário do arquivo. Para arquivos sem uma marca de identidade, username deve ser nulo.

Observação

Por conveniência, fornecemos um método SDK AppPolicy.isOpenFromLocalStorageAllowed que leva um parâmetro para um arquivo no armazenamento File local. Os termos da política de imposição são funcionalmente idênticos à chamada, exceto que ele lida com a análise do proprietário do arquivo AppPolicy.isOpenFromLocationAllowed(OpenLocation.LOCAL, username) username do File .

OpenLocation.CAMERA não é um local de serviço de nuvem e assim deve ser sempre usado com um parâmetro null de nome de usuário.

Os seguintes locais sempre esperarão um nome de usuário que contenha um mapeamento entre o UPN AAD e o nome de usuário do serviço de nuvem: ONEDRIVE_FOR_BUSINESS , SHAREPOINT e ACCOUNT_DOCUMENT .

Se um mapeamento entre AAD UPN e o nome de usuário do serviço de nuvem não existir ou o nome de usuário não for conhecido, use null .

Compartilhamento de caixa de diálogo bloqueada

O SDK fornece uma caixa de diálogo para notificar o usuário de que uma ação de transferência de dados foi bloqueada pela política do MAM.

A caixa de diálogo deve ser exibida para o usuário quando a chamada de API [isSaveToAllowedForLocation] ou [isOpenFromAllowedForLocation] resulta na ação salvar/abrir sendo bloqueada. A caixa de diálogo exibe uma mensagem genérica e retornará ao Activity chamado quando ignorado.

Para exibir a caixa de diálogo, faça a seguinte chamada:

MAMUIHelper.showSharingBlockedDialog(currentActivity)

Permitir compartilhamento de arquivos

Se não for permitido salvar em locais de armazenamento público, seu aplicativo ainda deverá permitir que o usuário veja arquivos baixando-os no armazenamento privado do aplicativo e, em seguida, abrindo-os com o selador do sistema.

Exemplo: Determinar se as notificações com dados da organização precisam ser restritas

Se o aplicativo exibir notificações, você deverá verificar a política de restrição de notificação para o usuário associado à notificação antes de mostrar a notificação. Para determinar se a política é imposta, faça a seguinte chamada.

NotificationRestriction notificationRestriction =
    MAMPolicyManager.getPolicyForIdentity(notificationIdentity).getNotificationRestriction();

Se a restrição for , o aplicativo não deverá mostrar nenhuma BLOCKED notificação para o usuário associado a essa política. Se BLOCK_ORG_DATA , o aplicativo deve mostrar uma notificação modificada que não contenha dados da organização. Se UNRESTRICTED , todas as notificações são permitidas.

Se não for invocado, o SDK do MAM fará um esforço melhor para restringir notificações automaticamente para getNotificationRestriction aplicativos de identidade única. Se o bloqueio automático estiver habilitado e estiver definido, a notificação BLOCK_ORG_DATA não será mostrada. Para obter um controle mais fino, verifique o valor e getNotificationRestriction modifique as notificações do aplicativo adequadamente.

Ignorar restrições de início condicional

Em cenários muito raros, pode ser necessário que as restrições de início condicional sejam ignoradas para uma atividade específica. Por exemplo, um aplicativo de discagem pode querer permitir que uma chamada de entrada seja atendida sem que o usuário tenha que inserir seu PIN primeiro. Para um aplicativo com várias identidades (consulte Multi-Identity abaixo), isso pode ser feito definindo a identidade associada à Atividade como uma identidade não controlada. Para permitir um desvio semelhante de restrições de início condicional em um aplicativo de identidade única, um Activity pode ser registrado para bypass com o MAMPolicyManager.

MAMPolicyManager.bypassConditionalLaunchChecks(this);

Esse método deve ser chamado antes de ser chamado, para ignorar efetivamente onMAMCreate() as verificações de início condicional. Por exemplo, ele pode ser chamado do construtor de Atividade ou de uma substituição para attachBaseContext() . Se você optar por substituir , lembre-se de chamar a superclasse ou podem ocorrer attachBaseContext() attachBaseContext() vazamentos de dados.

Observação

Como esse método permite o bypass de verificações de política de início condicional, ele só deve ser usado após a consulta com a Microsoft para confirmar que não há outra maneira com suporte para atingir o comportamento desejado do aplicativo.

Registrar-se para notificações do SDK

Visão geral

O SDK do Aplicativo do Intune permite que seu aplicativo controle o comportamento de determinadas políticas, como apagar seletiva, quando elas são implantadas pelo administrador de IT. Quando um administrador de IT implanta essa política, o serviço do Intune envia uma notificação para o SDK.

Seu aplicativo deve se registrar para notificações do SDK criando um MAMNotificationReceiver e registrando-o com MAMNotificationReceiverRegistry. Isso é feito fornecendo o receptor e o tipo de notificação desejado em , como App.onCreate ilustra o exemplo a seguir:

@Override
public void onCreate() {
  super.onCreate();
  MAMComponents.get(MAMNotificationReceiverRegistry.class)
    .registerReceiver(
      new ToastNotificationReceiver(),
      MAMNotificationType.WIPE_USER_DATA);
}

MAMNotificationReceiver

A interface MAMNotificationReceiver simplesmente recebe notificações do serviço Intune. Algumas notificações são manipuladas diretamente pelo SDK, enquanto outras exigem a participação do aplicativo. Um aplicativo deve retornar true ou false de uma notificação. Ele sempre deve retornar true, a menos que alguma ação que tenha tentado tomar como resultado da falha na notificação.

  • Essa falha pode ser relatada ao serviço do Intune. Um exemplo de cenário a ser reportado é se o aplicativo falhar ao apagar dados do usuário depois que o administrador de IT iniciar uma limpeza.

Observação

É seguro bloquear porque seu MAMNotificationReceiver.onReceive retorno de chamada não está sendo executado no thread da interface do usuário.

Tipos de notificações

As seguintes notificações MAMNotificationType são enviadas para o aplicativo e algumas delas podem exigir a participação do aplicativo:

  • WIPE_USER_DATA: essa notificação é enviada em um MAMUserNotification. Quando essa notificação é recebida, o aplicativo deve excluir todos os dados associados à identidade gerenciada (de MAMUserNotification.getUserIdentity() ). A notificação pode ocorrer por diversos motivos, incluindo quando seu aplicativo chama unregisterAccountForMAM, quando um administrador de IT inicia uma limpeza ou quando as políticas de acesso condicional exigidas pelo administrador não são atendidas. Se o aplicativo não se registrar para essa notificação, o comportamento de apagamento padrão será executado. O comportamento padrão excluirá todos os arquivos de um aplicativo de identidade única ou todos os arquivos marcados com a identidade gerenciada para um aplicativo de várias identidades. Essa notificação nunca será enviada no thread da interface do usuário.

  • WIPE_USER_AUXILIARY_DATA: os aplicativos podem se registrar para essa notificação se eles quiserem que o SDK do Aplicativo do Intune execute o comportamento de limpeza seletiva padrão, mas ainda gostaria de remover alguns dados auxiliares quando a limpeza ocorrer. Essa notificação não está disponível para aplicativos de identidade única. Ela só será enviada para aplicativos de várias identidades. Essa notificação nunca será enviada no thread da interface do usuário.

  • REFRESH_POLICY: essa notificação é enviada em um MAMUserNotification. Quando essa notificação é recebida, todas as decisões de política do Intune armazenadas em cache pelo aplicativo devem ser invalidadas e atualizadas. Se o aplicativo não armazenar suposições de política, ele não precisará se registrar para essa notificação. Não há garantias sobre em qual thread essa notificação será enviada.

  • REFRESH_APP_CONFIG: essa notificação é enviada em um MAMUserNotification. Quando essa notificação é recebida, todos os dados de Configuração de Aplicativo em cache devem ser invalidados e atualizados. Não há garantias sobre em qual thread essa notificação será enviada.

  • MANAGEMENT_REMOVED: essa notificação é enviada em um MAMUserNotification e informa ao aplicativo que ele está prestes a ficar sem gestão. Depois de não gerenciado, ele não poderá mais ler arquivos criptografados, ler dados criptografados com MAMDataProtectionManager, interagir com a área de transferência criptografada ou participar do ecossistema de aplicativo gerenciado. Confira mais detalhes abaixo. Essa notificação nunca será enviada no thread da interface do usuário.

  • MAM_ENROLLMENT_RESULT: essa notificação é enviada em um MAMEnrollmentNotification para informar ao aplicativo que uma tentativa de registro APP-WE foi concluída e fornecer o status dessa tentativa. Não há garantias sobre em qual thread essa notificação será enviada.

  • COMPLIANCE_STATUS: essa notificação é enviada em um MAMComplianceNotification para informar o aplicativo sobre o resultado de uma tentativa de correção de conformidade. Não há garantias sobre em qual thread essa notificação será enviada.

Observação

Um aplicativo nunca deve se registrar para as WIPE_USER_DATA WIPE_USER_AUXILIARY_DATA notificações e.

MANAGEMENT_REMOVED

A notificação indica que um usuário gerenciado por política anteriormente não será mais MANAGEMENT_REMOVED gerenciado pela política do MAM do Intune. Isso não exige a limpeza de dados do usuário ou a assinatura do usuário (se um apagamento fosse necessário, uma WIPE_USER_DATA notificação seria enviada). Muitos aplicativos podem não precisar lidar com essa notificação, no entanto, os aplicativos que usam MAMDataProtectionManager devem tomar nota especial dessa notificação.

Quando o MAM chamar o receptor do MANAGEMENT_REMOVED aplicativo, o seguinte será verdadeiro:

  • O MAM já descriptografou arquivos criptografados anteriormente (mas não buffers de dados protegidos) pertencentes ao aplicativo. Os arquivos em locais públicos no sdcard que não pertencem diretamente ao aplicativo (por exemplo, as pastas Documentos ou Download) não são descriptografados.
  • Novos arquivos ou buffers de dados protegidos criados pelo método receptor (ou qualquer outro código que seja executado após o início do receptor) não serão criptografados.
  • O aplicativo ainda tem acesso a chaves de criptografia, para que operações como buffers de dados de descriptografia tenham êxito.

Depois que o receptor do aplicativo retornar, ele não terá mais acesso a chaves de criptografia.

Configurar a Biblioteca de Autenticação da Microsoft (MSAL)

Observação

Azure Active Directory Biblioteca de Autenticação (ADAL) está preterida. Para obter mais informações, [consulte Update your applications to use Microsoft Authentication Library (MSAL)]. Para migrar seu aplicativo do ADAL para o MSAL, consulte [Migrate Android ADAL to MSAL] e [Differences between ADAL and MSAL].

Primeiro, leia as diretrizes de integração MSAL encontradas no repositório [MSAL em GitHub]. Para obter mais informações, consulte [Overview of Microsoft Authentication Library (MSAL)] and the MSAL Wiki.

Devido à precarização do ADALs, os aplicativos devem se integrar ao MSAL. No entanto, o SDK ainda depende do ADAL para seus cenários de autenticação e início condicional. Os valores de configuração necessários são comunicados ao SDK por AndroidManifest meio de metadados.

Para garantir que a política de autenticação do Intune possa ser aplicada corretamente, adicione o seguinte ao nó do aplicativo em AndroidManifest.xml . Algumas dessas configurações só serão necessárias (consulte configurações MSAL comuns abaixo) se o aplicativo usar o MSAL para autenticação em geral; nesse caso, você precisará dos valores específicos que seu aplicativo usa para se registrar com AAD. Isso é feito para garantir que o usuário final não seja solicitado a autenticação duas vezes, devido AAD reconhecer dois valores de registro separados: um do aplicativo e um do SDK.

<meta-data
    android:name="com.microsoft.intune.mam.aad.Authority"
    android:value="https://AAD authority/" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.ClientID"
    android:value="your-client-ID-GUID" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.NonBrokerRedirectURI"
    android:value="your-redirect-URI" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.SkipBroker"
    android:value="[true | false]" />

Metadados MSAL

  • Autoridade é a autoridade AAD em uso. Se esse valor estiver ausente, o ambiente AAD público será usado.

    Observação

    Não de definir esse campo se seu aplicativo estiver ciente da nuvem soberana.

  • ClientID é o AAD ClientID (também conhecido como ID do aplicativo) a ser usado. Você deve usar o ClientID do seu próprio aplicativo se ele estiver registrado no Azure AD ou aproveitar o Registro Padrão se ele não integrar o MSAL.

  • NonBrokerRedirectURI é o [AAD URI] de redirecionamento a ser usado em casos sem agente. Se nenhum for especificado, será usado um valor urn:ietf:wg:oauth:2.0:oob padrão. Esse padrão é adequado para a maioria dos aplicativos.

    • O NonBrokerRedirectURI só é usado quando SkipBroker é "true".
  • SkipBroker é usado para substituir o comportamento de participação padrão do SSO MSAL. SkipBroker só deve ser especificado para aplicativos que especificam um ClientID e não suportam autenticação intermediada/SSO em todo o dispositivo. Nesse caso, ele deve ser definido como "true". A maioria dos aplicativos não deve definir o parâmetro SkipBroker.

    • Um ClientID deve ser especificado no manifesto para especificar um valor SkipBroker.

    • Quando um ClientID é especificado, o valor padrão é "false".

    • Quando SkipBroker for "true", o NonBrokerRedirectURI será usado. Os aplicativos que não integram o MSAL (e, portanto, não têm ClientID) também serão padrão para "true".

Configurações comuns do MSAL

A seguir estão as maneiras comuns de um aplicativo ser configurado com o MSAL. Encontre a configuração do seu aplicativo e certifique-se de definir os parâmetros de metadados MSAL (explicados acima) como os valores necessários. Em todos os casos, a Autoridade pode ser especificada se desejado para ambientes não padrão. Se não for especificado, a autoridade de AAD pública será usada.

1. O aplicativo não integra o MSAL ou o ADAL

Os metadados MSAL/ADAL não devem estar presentes no manifesto.

2. O aplicativo integra o MSAL

Parâmetro MSAL necessário Valor
ClientID ClientID do aplicativo (gerado pelo Azure AD quando o aplicativo é registrado)

A autoridade pode ser especificada, se necessário.

Você deve registrar seu aplicativo no Azure AD e dar ao aplicativo acesso ao serviço de política de proteção de aplicativo:

  • Consulte [Registrar seu aplicativo com Azure Active Directory] para obter informações sobre como registrar um aplicativo no Azure AD.
  • Certifique-se de que as etapas para dar permissões ao aplicativo Android para o serviço app protection policy (APP) sejam seguidas. Use as instruções no guia "Começar com o SDK do Aplicativo do Intune" em "Dê acesso ao aplicativo ao serviço de proteção de aplicativo do [Intune (opcional)"].

Consulte também os requisitos para Acesso Condicional abaixo.

3. O aplicativo integra o MSAL, mas não dá suporte à autenticação intermediada/SSO em todo o dispositivo

Parâmetro MSAL necessário Valor
ClientID ClientID do aplicativo (gerado pelo Azure AD quando o aplicativo é registrado)
SkipBroker Verdadeiro

Autoridade e NonBrokerRedirectURI podem ser especificados, se necessário.

Política de proteção de aplicativo sem registro de dispositivo

Visão Geral

A política de proteção de aplicativos do Intune sem registro de dispositivo, também conhecida como APP-WE ou MAM-WE, permite que os aplicativos sejam gerenciados pelo Intune sem a necessidade de o dispositivo ser inscrito no MDM do Intune. APP-WE funciona com ou sem registro de dispositivo. A Portal da Empresa ainda é necessária para ser instalada no dispositivo, mas o usuário não precisa entrar no Portal da Empresa e registrar o dispositivo.

Observação

Todos os aplicativos são necessários para dar suporte à política de proteção de aplicativos sem registro no dispositivo.

Fluxo de trabalho

Quando um aplicativo cria uma nova conta de usuário, ele deve registrar a conta de gerenciamento com o SDK do Aplicativo intune. O SDK tratará dos detalhes de registrar o aplicativo no serviço APP-WE; se necessário, ele repetirá todas as inscrições em intervalos de tempo apropriados se ocorrerem falhas.

O aplicativo também pode consultar o SDK do Aplicativo do Intune para saber o status de um usuário registrado para determinar se o usuário deve ser impedido de acessar conteúdo corporativo. Várias contas podem ser registradas para gerenciamento, mas atualmente apenas uma conta pode ser registrada ativamente no serviço APP-WE por vez. Isso significa que apenas uma conta no aplicativo pode receber a política de proteção de aplicativos por vez.

O aplicativo é necessário para fornecer um retorno de chamada para adquirir o token de acesso apropriado da Biblioteca de Autenticação da Microsoft (MSAL) ou da Biblioteca de Autenticação Azure Active Directory (ADAL) em nome do SDK. Presume-se que o aplicativo já usa MSAL ou ADAL para autenticação do usuário e para adquirir seus próprios tokens de acesso.

Quando o aplicativo remove completamente uma conta, ele deve desemitir essa conta para indicar que o aplicativo não deve mais aplicar política para esse usuário. Se o usuário foi inscrito no serviço MAM, o usuário será desemrollado e o aplicativo será apagado.

Visão geral dos requisitos do aplicativo

Para implementar a integração APP-WE, seu aplicativo deve registrar a conta de usuário com o SDK do MAM:

  1. O aplicativo deve implementar e registrar uma instância da interface [MAMServiceAuthenticationCallback]. A instância de retorno de chamada deve ser registrada no onCreate() método (ou onMAMCreate() ) da subclasse Application.

  2. Quando uma conta de usuário é criada e o usuário faz o contato com o MSAL com êxito, o aplicativo deve chamar registerAccountForMAM.

  3. Quando uma conta de usuário é removida, o aplicativo deve chamar unregisterAccountForMAM para remover a conta do gerenciamento do Intune.

    Observação

    A chamada pode iniciar uma limpeza para remover completamente os dados corporativos do usuário.

MAMEnrollmentManager

Todas as APIs de autenticação e registro necessárias podem ser encontradas na interface MAMEnrollmentManager. Uma referência ao MAMEnrollmentManager pode ser obtida da seguinte forma:

MAMEnrollmentManager mgr = MAMComponents.get(MAMEnrollmentManager.class);

// make use of mgr

A MAMEnrollmentManager instância retornada garante que não seja nula. Os métodos API se enquadram em duas categorias: autenticação e registro de conta.

Autenticação de conta

Esta seção descreve os métodos da API de autenticação e MAMEnrollmentManager como usá-los.

interface MAMServiceAuthenticationCallback {
    String acquireToken(String upn, String aadId, String resourceId);
}
void registerAuthenticationCallback(MAMServiceAuthenticationCallback callback);
void updateToken(String upn, String aadId, String resourceId, String token);
  1. O aplicativo deve implementar a interface [MAMServiceAuthenticationCallback] para permitir que o SDK solicite um token AAD para o usuário e a ID de recurso determinados. A instância de retorno de chamada deve ser fornecida ao MAMEnrollmentManager chamar seu método registerAuthenticationCallback. Um token pode ser necessário no início do ciclo de vida do aplicativo para recuperações de registro ou check-ins de atualização da política de proteção de aplicativos, portanto, o retorno de chamada deve ser registrado no método (ou ) da subclasse Aplicativo do onCreate() onMAMCreate() aplicativo.

  2. O método acquireToken deve adquirir o token de acesso para a ID de recurso solicitada para o usuário determinado. Se ele não puder adquirir o token solicitado, ele deverá retornar null.

    Observação

    Certifique-se de que seu aplicativo utilize os parâmetros e passados para para resourceId que o token correto seja aadId acquireToken() adquirido. O resourceId deve ser usado para gerar os escopos adequados e o deve ser usado para passar a conta aadId correta.

    class MAMAuthCallback implements MAMServiceAuthenticationCallback {
        public String acquireToken(String upn, String aadId, String resourceId) {
            final String[] scopes = {resourceId + "/.default"};
    
            final IAccount account = getAccount(aadId);
            if (account == null) {
                callback.onError(
                        new MsalUiRequiredException(MsalUiRequiredException.NO_ACCOUNT_FOUND, "no account found for " + aadId));
                return;
            }
    
            AcquireTokenSilentParameters params =
                new AcquireTokenSilentParameters.Builder()
                        .forAccount(account)
                        .fromAuthority(account.getAuthority())
                        .withScopes(Arrays.asList(scopes))
                        .withCallback(callback)
                        .build();
    
            return mMsalClientApplication.acquireTokenSilent(params);
        }
    
        private static IAccount getAccount(String aadId) throws InterruptedException, MsalException {
          IAccount account = null;
    
          if (mMsalClientApplication instanceof IMultipleAccountPublicClientApplication) {
              IMultipleAccountPublicClientApplication multiAccountPCA =
                      (IMultipleAccountPublicClientApplication) mMsalClientApplication;
    
              account = multiAccountPCA.getAccount(aadId);
          } else {
              ISingleAccountPublicClientApplication singleAccountPCA =
                      (ISingleAccountPublicClientApplication) mMsalClientApplication;
    
              ICurrentAccountResult accountResult = singleAccountPCA.getCurrentAccount();
              if (accountResult != null) {
                  account = accountResult.getCurrentAccount();
                  // make sure this is the correct user
                  if (account != null && !account.getId().equals(aadId))
                      account = null;
              }
          }
          return account;
      }
    }
    
  3. Caso o aplicativo não consiga fornecer um token quando o SDK chama , por exemplo, se a autenticação silenciosa falhar e for um momento inconveniente para mostrar uma interface do usuário, o aplicativo poderá fornecer um token posteriormente chamando o método acquireToken() updateToken. A mesma UPN, AAD ID e ID de recurso que foram solicitadas pela chamada anterior devem ser passadas para , juntamente com o token que foi finalmente acquireToken() updateToken() adquirido. O aplicativo deve chamar esse método assim que possível após retornar null do retorno de chamada fornecido.

    Observação

    Não chame updateToken() de dentro de sua implementação de acquireToken() . updateToken() deve ser usado no caso em que acquireToken() não é possível adquirir um token.

    Observação

    O SDK chamará acquireToken() periodicamente para obter o token, portanto, a chamada updateToken() não é estritamente necessária. No entanto, é altamente recomendável, pois pode ajudar os registro e os check-ins de política de proteção de aplicativos concluídos em tempo hábil.

Registro de Conta

Esta seção descreve os métodos de API de registro de conta no MAMEnrollmentManager e como usá-los.

void registerAccountForMAM(String upn, String aadId, String tenantId);
void registerAccountForMAM(String upn, String aadId, String tenantId, String authority);
void unregisterAccountForMAM(String upn);
Result getRegisteredAccountStatus(String upn);
  1. Para registrar uma conta de gerenciamento, o aplicativo deve chamar registerAccountForMAM() . Uma conta de usuário é identificada por seu UPN e sua AAD ID de usuário. A ID do locatário também é necessária para associar dados de registro ao locatário AAD usuário. A autoridade do usuário também pode ser fornecida para permitir o registro em nuvens soberanas específicas; para obter mais informações, consulte Registro de Nuvem Soberana. O SDK pode tentar registrar o aplicativo para o usuário determinado no serviço MAM; se o registro falhar, ele repetirá periodicamente o registro até que a conta não seja registro. O período de repetir normalmente será de 12 a 24 horas. O SDK fornece o status das tentativas de registro de forma assíncrona por meio de notificações.

  2. Como AAD autenticação é necessária, a melhor hora para registrar a conta de usuário é depois que o usuário entrou no aplicativo e é autenticado com êxito usando o MSAL. A ID de AAD do usuário e a ID do locatário são retornadas da chamada de autenticação MSAL como parte do [IAccount] relacionado ao [IAuthenticationResult] .

    • A conta vem do IAuthenticationResult.getAccount() método e contém as informações de usuário pertinentes.
    • A ID do locatário vem do IAccount.getTenantId() método.
    • A AAD ID do usuário vem do IAccount.getId() método.
  3. Para desobilizar uma conta do gerenciamento do Intune, o aplicativo deve chamar unregisterAccountForMAM() . Se a conta tiver sido inscrita com êxito e for gerenciada, o SDK desemrollará a conta e apagará seus dados. As recuperações periódicas de registro da conta serão interrompidas. O SDK fornece o status da solicitação de desemrollment de forma assíncrona por meio da notificação.

Registro de nuvem soberana

Aplicativos que estão [cientes de nuvem soberana] devem fornecer o authority para registerAccountForMAM() .

Diretrizes MSAL

Para OMSAL, multiple_clouds_supported true desem conjunto como no arquivo de [configuração MSAL].

{
  "multiple_clouds_supported": true,
}

Diretrizes ADAL

Observação

O suporte para registro de nuvem soberana requer a versão 1.14.0 (ou superior) da biblioteca ADAL.

Para a ADAL, passe instance_aware=true para como um parâmetro seguido de invocar o acquireToken extraQueryParameters getAuthority() AuthenticationCallback AuthenticationResult .

mAuthContext.acquireToken(this, RESOURCE_ID, CLIENT_ID, REDIRECT_URI, PromptBehavior.FORCE_PROMPT, "instance_aware=true",
        new AuthenticationCallback<AuthenticationResult>() {
            @Override
            public void onError(final Exception exc) {
                // authentication failed
            }

            @Override
            public void onSuccess(final AuthenticationResult result) {
                mAuthority = result.getAuthority();
                // handle other parts of the result
            }
        });

Observação

Não de definir o com.microsoft.intune.mam.aad.Authority item de meta-dados no AndroidManifest.xml.

Observação

Verifique se a autoridade está corretamente definida em seu MAMServiceAuthenticationCallback::acquireToken() método.

Nuvens soberanas atualmente suportadas

  1. Nuvem governamental dos EUA do Azure
  2. Microsoft Azure operado pela 21Vianet (Azure China)

Notas de implementação importantes

Autenticação

  • Quando o aplicativo chama [registerAccountForMAM], ele pode receber um retorno de chamada em sua interface [MAMServiceAuthenticationCallback] pouco depois, em um thread diferente. Idealmente, o aplicativo adquiriu seu próprio token de AAD antes de registrar a conta para acelerar a aquisição do token solicitado. Se o aplicativo retornar um token válido do retorno de chamada, o registro prosseguirá e o aplicativo receberá o resultado final por meio de uma notificação.

  • Se o aplicativo não retornar um token AAD válido, o resultado final da tentativa de registro será AUTHORIZATION_NEEDED . Se o aplicativo receber esse Resultado por meio de notificação, é altamente recomendável agilizar o processo de registro adquirindo o token para o usuário e o recurso solicitado anteriormente de acquireToken e chamando o método updateToken para iniciar o processo de registro novamente.

  • O aplicativo registrado também será chamado para adquirir um token para check-ins de atualização de política de proteção de MAMServiceAuthenticationCallback aplicativos periódicos. Se o aplicativo não puder fornecer um token quando solicitado, ele não receberá uma notificação, mas tentará adquirir um token e uma chamada na próxima hora conveniente para acelerar o processo de updateToken() check-in. Se um token não for fornecido, o retorno de chamada ainda será chamado na próxima tentativa de check-in.

  • O suporte para nuvens soberanas requer o fornecimento da autoridade.

Registro

  • Para sua conveniência, os métodos de registro são idempotentes; por exemplo, [registerAccountForMAM] só registrará uma conta e tentará registrar o aplicativo se a conta ainda não estiver registrada, e o unregisterAccountForMAM só deso registrará uma conta se estiver registrada no momento. Chamadas subsequentes não são ops, portanto, não há nenhum dano ao chamar esses métodos mais de uma vez. Além disso, a correspondência entre chamadas a esses métodos e notificações de resultados não é garantida: ou seja, se for chamada para uma identidade já registrada, a notificação poderá não ser enviada novamente para essa registerAccountForMAM() identidade. É possível que as notificações sejam enviadas que não correspondam a chamadas a esses métodos, já que o SDK pode tentar periodicamente os registro em segundo plano e os cancelamentos podem ser disparados por solicitações de limpeza recebidas do serviço Do Intune.

  • Os métodos de registro podem ser chamados para qualquer número de identidades diferentes, mas atualmente apenas uma conta de usuário pode se registrar com êxito. Se várias contas de usuário licenciadas para o Intune e direcionadas pela política de proteção de aplicativos são registradas ao mesmo tempo, não há garantia de qual delas vencerá a corrida.

  • Por fim, você pode consultar o MAMEnrollmentManager para ver se uma conta específica está registrada e obter seu status atual usando o método getRegisteredAccountStatus. Se a conta fornecida não estiver registrada, este método retornará null. Se a conta estiver registrada, esse método retornará o status da conta como um dos membros da enumeração MAMEnrollmentManager.Result.

Códigos de resultado e status

Quando uma conta é registrada pela primeira vez, ela começa no estado, indicando que a tentativa inicial de registro do PENDING serviço MAM está incompleta. Após a conclusão da tentativa de registro, uma notificação será enviada com um dos códigos de resultado na tabela abaixo. Além disso, o método getRegisteredAccountStatus retornará o status da conta para que o aplicativo possa sempre determinar se o acesso ao conteúdo corporativo está bloqueado para esse usuário. Se a tentativa de registro falhar, o status da conta poderá mudar ao longo do tempo à medida que o SDK recupera o registro em segundo plano.

Código de resultado Explicação
AUTHORIZATION_NEEDED Esse resultado indica que um token não foi fornecido pela instância registrada do aplicativo [MAMServiceAuthenticationCallback] ou o token fornecido era inválido. O aplicativo deve adquirir um token válido e uma chamada updateToken, se possível.
NOT_LICENSED O usuário não está licenciado para o Intune ou a tentativa de entrar em contato com o serviço MAM do Intune falhou. O aplicativo deve continuar em um estado nãomanageado (normal) e o usuário não deve ser bloqueado. As inscrições serão recuperadas periodicamente caso o usuário se torne licenciado no futuro.
ENROLLMENT_SUCCEEDED A tentativa de registro foi bem-sucedida ou o usuário já está inscrito. No caso de um registro bem-sucedido, as notificações e REFRESH_POLICY REFRESH_APP_CONFIG correspondentes são enviadas antes dessa notificação. O acesso aos dados corporativos deve ser permitido.
ENROLLMENT_FAILED A tentativa de registro falhou. Mais detalhes podem ser encontrados nos logs do dispositivo. O aplicativo não deve permitir o acesso a dados corporativos neste estado, já que foi determinado anteriormente que o usuário está licenciado para o Intune. Todos os aplicativos devem garantir que o acesso a dados corporativos não seja autorizado, até ENROLLMENT_SUCCEEDED que seja obtido pelo seu aplicativo.
WRONG_USER Somente um usuário por dispositivo pode registrar um aplicativo com o serviço MAM. Esse resultado indica que o usuário para o qual esse resultado foi entregue (o segundo usuário) é direcionado com a política do MAM, mas um usuário diferente já está inscrito. Como a política de MAM não pode ser imposta para o segundo usuário, seu aplicativo não deve permitir o acesso aos dados desse usuário (possivelmente removendo o usuário do seu aplicativo) a menos que/até que o registro desse usuário seja bem-sucedido posteriormente. Ao mesmo tempo em que entrega esse resultado, o WRONG_USER MAM solicitará a opção de remover a conta existente. Se o usuário humano responder afirmativamente, será possível registrar o segundo usuário um pouco mais tarde. Enquanto o segundo usuário permanecer registrado, o MAM repetirá o registro periodicamente.
UNENROLLMENT_SUCCEEDED Unenrollment foi bem-sucedido.
UNENROLLMENT_FAILED A solicitação de desemrollment falhou. Mais detalhes podem ser encontrados nos logs do dispositivo. Em geral, isso não ocorrerá enquanto o aplicativo passar um UPN válido (nem nulo nem vazio). Não há correção direta e confiável que o aplicativo possa tomar. Se esse valor for recebido ao não fazer o registro de um UPN válido, informe-o como um bug para a equipe do MAM do Intune.
PENDING A tentativa de registro inicial do usuário está em andamento. O aplicativo pode bloquear o acesso aos dados corporativos até que o resultado do registro seja conhecido, mas não é necessário fazer isso.
COMPANY_PORTAL_REQUIRED O usuário é licenciado para o Intune, mas o aplicativo não pode ser inscrito até que o aplicativo Portal da Empresa seja instalado no dispositivo. O SDK do Aplicativo do Intune tentará bloquear o acesso ao aplicativo para o usuário determinado e o direcionará para instalar o aplicativo Portal da Empresa (consulte abaixo para obter detalhes).

Portal da Empresa de solicitação de substituição de prompt (opcional)

Se o Resultado for recebido, o SDK bloqueará o uso de atividades que usam a identidade para a COMPANY_PORTAL_REQUIRED qual o registro foi solicitado. Em vez disso, o SDK fará com que essas atividades exibem um prompt para baixar o Portal da Empresa. Se você quiser impedir esse comportamento em seu aplicativo, as atividades poderão implementar MAMActivity.onMAMCompanyPortalRequired.

Esse método é chamado antes que o SDK exibe sua interface do usuário de bloqueio padrão. Se o aplicativo mudar a identidade da atividade ou não registrar o usuário que tentou se registrar, o SDK não bloqueará a atividade. Nessa situação, o aplicativo deve evitar vazamento de dados corporativos. Somente aplicativos de várias identidades (discutidos posteriormente) poderão alterar a identidade da atividade.

Se você não herdar explicitamente [o MAMActivity] (porque a ferramenta de com build fará essa alteração), mas ainda precisar lidar com essa notificação, você poderá implementar MAMActivityBlockingListener.

Notificações

Se o aplicativo se registrar para notificações do tipo MAM_ENROLLMENT_RESULT, um MAMEnrollmentNotification será enviado para informar ao aplicativo que a solicitação de registro foi concluída. O MAMEnrollmentNotification será recebido por meio da interface MAMNotificationReceiver conforme descrito na seção Registrar para notificações do SDK.

public interface MAMEnrollmentNotification extends MAMUserNotification {
    MAMEnrollmentManager.Result getEnrollmentResult();
}

O método getEnrollmentResult retorna o resultado da solicitação de registro. Como se estende , a identidade do usuário para o qual o registro MAMEnrollmentNotification foi tentado também está MAMUserNotification disponível. O aplicativo deve implementar a interface para receber essas notificações, detalhadas na seção Registrar para notificações MAMNotificationReceiver do SDK.

O status da conta de usuário registrada pode mudar quando uma notificação de registro é recebida, mas não muda em todos os casos (por exemplo, se a notificação for recebida após um resultado mais informativo, como , o resultado mais informativo será mantido como o status da AUTHORIZATION_NEEDED WRONG_USER conta). Depois que a conta for inscrita com êxito, o status permanecerá como até que a conta seja ENROLLMENT_SUCCEEDED desemrollada ou apagada.

Acesso Condicional

O Acesso Condicional (CA) é um recurso Azure Active Directory que pode ser usado para controlar o acesso a AAD recursos. Os administradores do Intune podem definir regras de AC que permitem o acesso de recursos apenas a partir de dispositivos ou aplicativos gerenciados pelo Intune. Para garantir que seu aplicativo possa acessar recursos quando apropriado, é necessário seguir as etapas abaixo. Se seu aplicativo não adquirir AAD tokens de acesso ou acessar apenas recursos que não podem ser protegidos por CA, você poderá ignorar essas etapas.

  1. Registrar o aplicativo com o Azure Active Directory. Isso gerará uma ID do Cliente para seu aplicativo.
  2. Siga as etapas para [usar o MSAL] e Configurar o MSAL para usar um agente.
  3. De definir os parâmetros de metadados de manifesto de acordo com as configurações MSAL comuns para o MSAL do App Integra, consulte acima.

AC de Proteção de Aplicativos

Visão geral

Com a AC de Proteção de Aplicativos (Acesso Condicional), o acesso aos recursos é condicionalizado no aplicativo de Políticas de Proteção de Aplicativos do Intune. AAD isso exigindo que o aplicativo seja inscrito e gerenciado pelo APP antes de conceder um token para acessar um recurso protegido pela AC.

Observação

O suporte para a CA de Proteção de Aplicativos requer a versão 1.0.0 (ou superior) da biblioteca MSAL.

Lidar com a não conformidade com o MSAL

Ao adquirir um token para um usuário, a biblioteca MSAL pode retornar ou lançar um para indicar a não MsalIntuneAppProtectionPolicyRequiredException conformidade com o gerenciamento de APLICATIVOs. Parâmetros adicionais podem ser extraídos da exceção para uso na correção da conformidade (consulte MAMComplianceManager). Depois que a correção for bem-sucedida, o aplicativo poderá tentar novamente a aquisição do token por meio do MSAL.

MAMComplianceManager

A interface MAMComplianceManager é usada quando o erro exigido pela política é recebido do MSAL. Ele contém o método remediateCompliance que deve ser chamado para tentar colocar o aplicativo em um estado em conformidade. Uma referência ao MAMComplianceManager pode ser obtida da seguinte forma:

MAMComplianceManager mgr = MAMComponents.get(MAMComplianceManager.class);

// make use of mgr

A MAMComplianceManager instância retornada garante que não seja nula.

package com.microsoft.intune.mam.policy;

public interface MAMComplianceManager {
    void remediateCompliance(String upn, String aadId, String tenantId, String authority, boolean showUX);
}

O método é chamado para tentar colocar o aplicativo sob gerenciamento para atender às condições AAD remediateCompliance() conceder o token solicitado. Os quatro primeiros parâmetros podem ser extraídos da exceção recebida pelo método MSAL AuthenticationCallback.onError() (consulte exemplo de código abaixo). O parâmetro final é um booleano que controla se um UX é mostrado durante a tentativa de conformidade. Esta é uma interface de estilo de progresso de bloqueio simples fornecida como padrão para aplicativos que não precisam mostrar o UX personalizado durante essa operação. Ele só será bloqueado enquanto a correção de conformidade estiver em andamento e não exibirá o resultado final. O aplicativo deve registrar um receptor de notificação para lidar com o sucesso ou a falha da tentativa de correção de conformidade (consulte abaixo).

O remediateCompliance() método pode fazer um registro do MAM como parte do estabelecimento de conformidade. O aplicativo pode receber uma notificação de registro se tiver registrado um receptor de notificação para notificações de registro. O aplicativo registrado [MAMServiceAuthenticationCallback] terá seu método acquireToken chamado para obter um token para o registro do MAM. acquireToken() será chamado antes que o aplicativo tenha adquirido seu próprio token, portanto, qualquer tarefa de contabilidade ou criação de conta que o aplicativo faz após uma aquisição de token bem-sucedida pode não ter sido feita ainda. O retorno de chamada deve ser capaz de adquirir um token nesse caso. Se você não puder retornar um token de , a acquireToken() tentativa de correção de conformidade falhará. Se você chamar updateToken posteriormente com um token válido para o recurso solicitado, a correção de conformidade será recuperada imediatamente com o token determinado.

Observação

A aquisição de token silencioso ainda será possível porque o usuário já terá sido orientado a instalar o agente e registrar o dispositivo antes que a exceção acquireToken() MsalIntuneAppProtectionPolicyRequiredException seja recebida. Isso faz com que o agente tenha um token de atualização válido em seu cache, permitindo que a aquisição silenciosa do token solicitado seja bem-sucedida.

Aqui está um exemplo de recebimento do erro exigido pela política no método e a chamada do AuthenticationCallback.onError() MAMComplianceManager para lidar com o erro.

public void onError(@Nullable MsalException exc) {
    if (exc instanceof MsalIntuneAppProtectionPolicyRequiredException) {

        final MsalIntuneAppProtectionPolicyRequiredException policyRequiredException =
            (MsalIntuneAppProtectionPolicyRequiredException) ex;

        final String upn = policyRequiredException.getAccountUpn();
        final String aadId = policyRequiredException.getAccountUserId();
        final String tenantId = policyRequiredException.getTenantId();
        final String authority = policyRequiredException.getAuthorityURL();

        MAMComplianceManager complianceManager = MAMComponents.get(MAMComplianceManager.class);
        complianceManager.remediateCompliance(upn, aadId, tenantId, authority, showUX);
    }
}

Notificações de Status

Se o aplicativo se registrar para notificações do tipo COMPLIANCE_STATUS, um MAMComplianceNotification será enviado para informar ao aplicativo o status final da tentativa de correção de conformidade. O MAMComplianceNotification será recebido por meio da interface MAMNotificationReceiver conforme descrito na seção Registrar para notificações do SDK.

public interface MAMComplianceNotification extends MAMUserNotification {
    MAMCAComplianceStatus getComplianceStatus();
    String getComplianceErrorTitle();
    String getComplianceErrorMessage();
}

O método retorna o resultado da tentativa de correção de conformidade como um valor getComplianceStatus() do número MAMCAComplianceStatus.

Código de status Explicação
UNKNOWN O status é desconhecido. Isso pode indicar um motivo de falha não antecipado. Informações adicionais podem ser encontradas nos Portal da Empresa logs.
COMPATÍVEL A correção de conformidade foi bem-sucedida e o aplicativo agora está em conformidade com a política. A aquisição de token MSAL deve ser recuperada.
NOT_COMPLIANT A tentativa de correção da conformidade falhou. O aplicativo não está em conformidade e a aquisição de token MSAL não deve ser recuperada até que a condição de erro seja corrigida. Informações de erro adicionais são enviadas com o MAMComplianceNotification.
SERVICE_FAILURE Houve uma falha ao tentar recuperar dados de conformidade do Serviço do Intune. Informações adicionais podem ser encontradas nos Portal da Empresa logs.
NETWORK_FAILURE Houve um erro ao se conectar ao Serviço do Intune. O aplicativo deve tentar sua aquisição de token novamente quando a conexão de rede for restaurada.
CLIENT_ERROR A tentativa de correção da conformidade falhou por algum motivo relacionado ao cliente. Por exemplo, nenhum token ou usuário errado. Informações de erro adicionais são enviadas com o MAMComplianceNotification.
PENDENTE A tentativa de correção da conformidade falhou porque a resposta de status ainda não tinha sido recebida do serviço quando o limite de tempo foi excedido. O aplicativo deve tentar sua aquisição de token novamente mais tarde.
COMPANY_PORTAL_REQUIRED O Portal da Empresa deve ser instalado no dispositivo para que a correção de conformidade seja bem-sucedida. Se o Portal da Empresa já estiver instalado no dispositivo, o aplicativo precisará ser reiniciado. Nesse caso, uma caixa de diálogo será mostrada solicitando que o usuário reinicie o aplicativo.

Se o status de conformidade for , o aplicativo deverá reacionar sua aquisição MAMCAComplianceStatus.COMPLIANT de token original (para seu próprio recurso). Se a tentativa de correção de conformidade falhar, os métodos e retornarão cadeias de caracteres localizadas que o aplicativo poderá exibir para o usuário final se getComplianceErrorTitle() getComplianceErrorMessage() ele escolher. A maioria dos casos de erro não é remediada pelo aplicativo, portanto, para o caso geral, talvez seja melhor falhar na criação ou no logon da conta e permitir que o usuário tente novamente mais tarde. Se uma falha for persistente, os logs do MAM podem ajudar a determinar a causa. O usuário final pode enviar os logs. Para obter mais informações, consulte Upload e logs de email.

Como se estende , a identidade do usuário para o qual a correção foi MAMComplianceNotification MAMUserNotification tentada também está disponível.

Aqui está um exemplo de registro de um receptor usando uma classe anônima para implementar a interface MAMNotificationReceiver:

final MAMNotificationReceiverRegistry notificationRegistry = MAMComponents.get(MAMNotificationReceiverRegistry.class);
// create a receiver
final MAMNotificationReceiver receiver = new MAMNotificationReceiver() {
    public boolean onReceive(MAMNotification notification) {
        if (notification.getType() == MAMNotificationType.COMPLIANCE_STATUS) {
            MAMComplianceNotification complianceNotification = (MAMComplianceNotification) notification;
            
            // take appropriate action based on complianceNotification.getComplianceStatus()
            
            // unregister this receiver if no longer needed
            notificationRegistry.unregisterReceiver(this, MAMNotificationType.COMPLIANCE_STATUS);
        }
        return true;
    }
};
// register the receiver
notificationRegistry.registerReceiver(receiver, MAMNotificationType.COMPLIANCE_STATUS);

Observação

O receptor de notificação deve ser registrado antes de chamar para evitar uma condição de corrida que remediateCompliance() possa resultar na falta da notificação.

Declarando suporte para a AC do aplicativo

Depois que o aplicativo estiver pronto para lidar com a correção da AC do Aplicativo, você poderá dizer à Microsoft Identity que seu aplicativo está pronto para a AC do aplicativo. Para fazer isso em seu aplicativo MSAL, crie seu Cliente Público usando os Recursos do Cliente de "protapp"

{
      "client_id" : "4b0db8c2-9f26-4417-8bde-3f0e3656f8e0",
      "authorization_user_agent" : "DEFAULT",
      "redirect_uri" : "msauth://com.microsoft.identity.client.sample.local/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
      "multiple_clouds_supported":true,
      "broker_redirect_uri_registered": true,
      "account_mode": "MULTIPLE",
      "client_capabilities": "protapp",
      "authorities" : [
        {
          "type": "AAD",
          "audience": {
            "type": "AzureADandPersonalMicrosoftAccount"
          }
        }
      ]
    }

Notas de implementação

Observação

O método do MAMServiceAuthenticationCallback.acquireToken() aplicativo deve passar false para sinalizador forceRefresh para acquireTokenSilentAsync() .

AcquireTokenSilentParameters acquireTokenSilentParameters =
        builder.withScopes(Arrays.asList(scopes))
               .forceRefresh(false)
               .build();

acquireTokenSilentAsync(acquireTokenSilentParameters);

Observação

Se você quiser mostrar um UX de bloqueio personalizado durante a tentativa de correção, passe false para o parâmetro showUX para remediateCompliance() . Você deve garantir que você mostre seu UX e registre seu ouvinte de notificação primeiro antes de chamar remediateCompliance() . Isso impedirá uma condição de corrida em que a notificação poderá ser perdida se remediateCompliance() falhar rapidamente. Por exemplo, o método ou de uma subclasse Atividade é o local ideal para registrar o ouvinte de onCreate() onMAMCreate() notificação e, em seguida, chamar remediateCompliance() . Os parâmetros para remediateCompliance() podem ser passados para o seuux como extras de intenção. Quando a notificação de status de conformidade é recebida, você pode exibir o resultado ou simplesmente concluir a atividade.

Observação

remediateCompliance() registrará a conta e tentará o registro. Depois que o token principal é adquirido, a chamada não registerAccountForMAM() é necessária, mas não há nenhum dano em fazê-lo. Por outro lado, se o aplicativo não conseguir adquirir seu token e desejar remover a conta de usuário, ele deverá chamar para remover a conta e evitar novas recuperações de registro unregisterAccountForMAM() em segundo plano.

Protegendo dados de backup

Você pode ler mais sobre as opções de backup e restauração do Android no guia da API android e as alterações introduzidas no Android S/12 aqui: Altere para backup e restauração.

Backup automático para aplicativos

A partir do Android M, o Android começou a oferecer backups completos automáticos Google Drive para aplicativos, independentemente da API de destino do aplicativo.

O Intune permite que você utilize todos os recursos de Backup Automático disponíveis no Android, incluindo a capacidade de definir regras personalizadas em XML, com orientações específicas de integração do Intune para garantir que a proteção de dados seja aplicada.

Valores de manifesto

Por padrão, android:allowBackup é definido como true conforme descrito em habilitar e desabilitar o backup.

Se seu aplicativo não exigir a funcionalidade completa de backup e restauração, de acordo android:allowBackup com false. Nesse caso, nenhuma ação é necessária e os dados "corporativos" permanecerão dentro do aplicativo.

Se seu aplicativo exigir a funcionalidade de backup e restauração completos, de acordo com android:allowBackup true e execute as seguintes etapas adicionais:

  1. Se seu aplicativo não usar seu próprio personalizado, use o BackupAgent MAMBackupAgent padrão para permitir backups completos automáticos compatíveis com a política do Intune. Coloque o seguinte no manifesto do aplicativo:

    <application
    ...
      android:fullBackupOnly="true"
      android:backupAgent="com.microsoft.intune.mam.client.app.backup.MAMDefaultBackupAgent"
      ...>
      </application>
    
  2. [Opcional] Se você implementou um personalizado opcional, você precisa ter certeza de usar BackupAgent MAMBackupAgent ou MAMBackupAgentHelper. Consulte as seções a seguir. Considere alternar para usar o MAMDefaultBackupAgentdo Intune , descrito na etapa 1, que fornece um back-up fácil no Android M e acima.

  3. Quando você decidir qual tipo de backup completo seu aplicativo deve receber (não filtrado, filtrado ou nenhum), você precisará definir o atributo como true, false ou um recurso XML em seu android:fullBackupContent aplicativo.

  4. Em seguida, você deve copiar o valor para a marca de metadados e para aplicativos que suportam o novo formato de configuração XML adicionado na API 31, para a marca de android:fullBackupContent com.microsoft.intune.mam.FullBackupContent com.microsoft.intune.mam.DataExtractionRules metadados.

    • Exemplo 1: Se você quiser que seu aplicativo tenha backups completos sem exclusões, deverão definir os atributos e marcas de metadados como true:

      <application
        ...
        android:fullBackupContent="true"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="true" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:value="true" />
      
    • Exemplo 2: Se você quiser que seu aplicativo use seu personalizado e não completo, em conformidade com a política do BackupAgent Intune, backups automáticos, defina os atributos e marcas de metadados como false:

      <application
        ...
        android:fullBackupContent="false"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="false" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:value="false" />
      
    • Exemplo 3: Se você quiser que seu aplicativo tenha backups completos de acordo com suas regras personalizadas definidas em um arquivo XML, de definir o atributo e a marca de metadados como o mesmo recurso XML:

      <application
        ...
        android:fullBackupContent="@xml/my_full_backup_content_scheme"
        android:dataExtractionRules="@xml/my_data_extraction_rules_scheme"
        ...>
      </application>
      ...
      <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:resource="@xml/my_full_backup_content_scheme" />
      <meta-data android:name="com.microsoft.intune.mam.DataExtractionRules" android:resource="@xml/my_data_extraction_rules_scheme" />
      

Backup de chave/valor

A opção Backup de Chave/Valor está disponível para todas as APIs 8+ e carrega dados do aplicativo para o Serviço de Backup do Android. A quantidade de dados por usuário do aplicativo é limitada a 5 MB. Se você usar o Backup de Chave/Valor, deverá usar [um BackupAgentHelper] ou [um BackupAgent].

BackupAgentHelper

BackupAgentHelper é mais fácil de implementar do [que BackupAgent em] termos de funcionalidade nativa do Android e integração do MAM do Intune. BackupAgentHelper permite que o desenvolvedor registre arquivos inteiros e preferências compartilhadas em um e (respectivamente) que são adicionados ao FileBackupHelper SharedPreferencesBackupHelper BackupAgentHelper após a criação. Siga as etapas abaixo para usar um BackupAgentHelper com o Intune MAM:

  1. Para utilizar o backup de várias identidades com um , siga o BackupAgentHelper guia do Android para Estender BackupAgentHelper.

  2. Faça sua classe estender o equivalente MAM de BackupAgentHelper, FileBackupHelper e SharedPreferencesBackupHelper.

Classe Android Equivalente do MAM
BackupAgentHelper MAMBackupAgentHelper
FileBackupHelper MAMFileBackupHelper
SharedPreferencesBackupHelper MAMSharedPreferencesBackupHelper

Seguir essas diretrizes levará a um backup e restauração com várias identidades bem-sucedidas.

BackupAgent

Um BackupAgent permite que você seja muito mais explícito sobre quais dados são backup. Como o desenvolvedor é bastante responsável pela implementação, há mais etapas necessárias para garantir a proteção de dados apropriada do Intune. Como a maior parte do trabalho é empurrada para você, o desenvolvedor, a integração do Intune é um pouco mais envolvida.

Integrar o MAM:

  1. Leia cuidadosamente o guia do Android para Backup de Chave/Valor e especificamente Estendendo o BackupAgent para garantir que sua implementação do BackupAgent siga as diretrizes do Android.

  2. Fazer sua classe estender MAMBackupAgent.

Backup de várias identidades:

  1. Antes de iniciar o backup, verifique se os arquivos ou buffers de dados que você planeja fazer backup são de fato permitidos pelo administrador de TI para fazer backup em cenários de várias identidades. Fornecemos a função isBackupAllowed em MAMFileProtectionManager e MAMDataProtectionManager para determinar isso. Se o arquivo ou o buffer de dados não tiver permissão para fazer backup, você não deverá continuar incluindo-o em seu backup.

  2. Em algum momento durante o backup, se você quiser fazer backup das identidades dos arquivos que fez check-in na etapa 1, você deve chamar com os arquivos dos quais você planeja backupMAMFileIdentity(BackupDataOutput data, File … files) extrair dados. Isso criará automaticamente novas entidades de backup e as gravará BackupDataOutput para você. Essas entidades serão consumidas automaticamente após a restauração.

Restauração de várias identidades:

O guia backup de dados especifica um algoritmo geral para restaurar os dados do aplicativo e fornece um exemplo de código na seção Extending BackupAgent. Para ter uma restauração bem-sucedida de várias identidades, você deve seguir a estrutura geral fornecida neste exemplo de código com atenção especial para o seguinte:

  1. Você deve utilizar um while(data.readNextHeader()) loop * para passar pelas entidades de backup.

  2. Você deve chamar data.skipEntityData() * se * não corresponder à chave que você escreveu em data.getKey() onBackup . Sem executar esta etapa, suas restaurações podem não ter êxito.

  3. Evite retornar ao consumir entidades de backup na construção *, pois as entidades que escrevemos while(data.readNextHeader()) automaticamente serão perdidas.

  • Onde data está o nome da variável local para o MAMBackupDataInput que é passado para seu aplicativo após a restauração.

Multi-Identity (opcional)

Visão geral

Por padrão, o SDK do Aplicativo do Intune aplicará a política ao aplicativo como um todo. Multi-identity é um recurso opcional de proteção de aplicativo do Intune que pode ser habilitado para permitir que a política seja aplicada em um nível por identidade. Isso requer uma participação significativamente maior do aplicativo do que outros recursos de proteção de aplicativos.

Observação

A falta da participação correta do aplicativo pode resultar em vazamentos de dados e outros problemas de segurança.

Depois que o usuário registra o dispositivo ou o aplicativo, o SDK registra essa identidade e a considera a identidade gerenciada principal do Intune. Outros usuários no aplicativo serão tratados como sem gestão, com configurações de política irrestritas.

Observação

Atualmente, apenas uma identidade gerenciada do Intune é suportada por dispositivo.

Uma identidade é definida como uma cadeia de caracteres. As identidades não identificam maiúsculas de minúsculas e as solicitações ao SDK para uma identidade podem não retornar o mesmo invólucro que foi originalmente usado ao definir a identidade.

O aplicativo deve informar o SDK quando pretende alterar a identidade ativa. Em alguns casos, o SDK também notificará o aplicativo quando uma alteração de identidade for necessária. Na maioria dos casos, no entanto, o MAM não pode saber quais dados estão sendo exibidos na interface do usuário ou usados em um thread em um determinado momento e depende do aplicativo para definir a identidade correta para evitar vazamento de dados. Nas seções a seguir, alguns cenários específicos que exigem a ação do aplicativo serão chamados.

Habilitando Várias Identidades

Por padrão, todos os aplicativos são considerados aplicativos de identidade única. Você pode declarar que um aplicativo está ciente de várias identidades colocando os metadados a seguir AndroidManifest.xml.

  <meta-data
    android:name="com.microsoft.intune.mam.MAMMultiIdentity"
    android:value="true" />

Definindo a identidade

Os desenvolvedores podem definir a identidade do usuário do aplicativo nos seguintes níveis em prioridade decrescente:

  1. Nível de thread
  2. Context``Activity(geralmente) level
  3. Nível do processo

Um conjunto de identidade no nível do thread sobressede um conjunto de identidade no nível, que sobressalte um conjunto de identidade Context no nível do processo. Um conjunto de identidade em um Context só é usado em cenários associados apropriados. As operações de IO de arquivo, por exemplo, não têm Context um . Mais comumente, os aplicativos definirão a Context identidade em Activity um . Um aplicativo não deve exibir dados para uma identidade gerenciada, a menos que a identidade esteja definida para essa Activity mesma identidade. Em geral, a identidade no nível do processo só será útil se o aplicativo funcionar apenas com um único usuário por vez em todos os threads. Muitos aplicativos podem não precisar fazer uso dele.

Se seu aplicativo usa o contexto para adquirir serviços do sistema, verifique se a identidade de thread ou processo foi definida ou se você definiu a identidade da interface do usuário no contexto do Application Application seu aplicativo.

Se seu aplicativo usa um contexto para iniciar as intenções, use resolvedores de conteúdo ou aproveite outros serviços do sistema, certifique-se de definir Service a identidade no Service contexto.

Para lidar com casos especiais ao atualizar a identidade da interface do usuário com setUIPolicyIdentity ou [switchMAMIdentity,]ambos os métodos podem ser passados para um conjunto de valores IdentitySwitchOption.

  • IGNORE_INTENT: Use se solicitar uma opção de identidade que deve ignorar a intenção associada à atividade atual. Por exemplo:

    1. Seu aplicativo recebe uma intenção de uma identidade gerenciada que contém um documento gerenciado e seu aplicativo exibe o documento.
    2. O usuário alterna para sua identidade pessoal, portanto, seu aplicativo solicita uma opção de identidade da interface do usuário. Na identidade pessoal, seu aplicativo não está mais exibindo o documento, portanto, você usa IGNORE_INTENT ao solicitar a opção de identidade.
  • DATA_FROM_INTENT: Use se solicitar uma opção de identidade quando os dados da intenção serão exibidos na atividade. O oposto de IGNORE_INTENT . Isso fará com que a política de recebimento da nova identidade trate a intenção como dados de entrada.

    Por exemplo: seu aplicativo recebe uma intenção que contém metadados que os correlaciona a uma conta específica. Seu aplicativo solicita uma opção de identidade, mas exibirá dados da intenção original.

Se nenhum dos dois estiver definido, o comportamento padrão está em algum lugar entre eles para compatibilidade histórica. O MAM assumirá que a intenção mais recente ainda está sendo usada no aplicativo como com , no entanto, um intervalo de condições especiais, incluindo a intenção de ter sido enviada de dentro do mesmo aplicativo ou do launcher do sistema, ignorará a verificação de entrada de DATA_FROM_INTENT dados.

Observação

Como o é usado para operações de interface do usuário, o SDK usa a identidade da interface do usuário da atividade CLIPBOARD_SERVICE em primeiro plano para ClipboardManager operações.

Os métodos a seguir no MAMPolicyManager podem ser usados para definir a identidade e recuperar os valores de identidade definidos anteriormente.

public static void setUIPolicyIdentity(final Context context, final String identity, final MAMSetUIIdentityCallback mamSetUIIdentityCallback,
final EnumSet<IdentitySwitchOption> options);

public static String getUIPolicyIdentity(final Context context);

public static MAMIdentitySwitchResult setProcessIdentity(final String identity);

public static String getProcessIdentity();

public static MAMIdentitySwitchResult setCurrentThreadIdentity(final String identity);

public static String getCurrentThreadIdentity();

/**
 * Get the current app policy. This does NOT take the UI (Context) identity into account.
 * If the current operation has any context (e.g. an Activity) associated with it, use the overload below.
 */
public static AppPolicy getCurrentThreadPolicy();

/**
 * Get the current app policy. This DOES take the UI (Context) identity into account.
 * If the current operation has any context (e.g. an Activity) associated with it, use this function.
 */
public static AppPolicy getPolicy(final Context context);


public static AppPolicy getPolicyForIdentity(final String identity);

public static boolean getIsIdentityManaged(final String identity);

Observação

Você pode limpar a identidade do aplicativo definindo-o como nulo.

A cadeia de caracteres vazia pode ser usada como uma identidade que nunca terá política de proteção de aplicativo.

Resultados

Todos os métodos usados para definir os valores de resultado do relatório de identidade de volta por meio de MAMIdentitySwitchResult. Há quatro valores que podem ser retornados:

Valor de retorno Cenário
SUCCEEDED A alteração de identidade foi bem-sucedida.
NOT_ALLOWED A alteração de identidade não é permitida. Isso ocorrerá se uma tentativa for feita para definir a identidade da interface do usuário ( ) quando uma identidade diferente é Context definida no thread atual.
CANCELLED O usuário cancelou a alteração de identidade, geralmente pressionando o botão voltar em um PIN ou prompt de autenticação.
FAILED A alteração de identidade falhou por um motivo não especificado.

O aplicativo deve garantir que uma opção de identidade seja bem-sucedida antes de exibir ou usar dados corporativos. Atualmente, as opções de identidade de processo e thread sempre terão êxito para um aplicativo habilitado para várias identidades, no entanto, reservamos o direito de adicionar condições de falha. A opção de identidade da interface do usuário pode falhar em argumentos inválidos, se ela entra em conflito com a identidade do thread ou se o usuário cancela os requisitos de início condicional (por exemplo, pressiona o botão voltar na tela PIN). O comportamento padrão para uma opção de identidade de interface do usuário com falha em uma atividade é concluir a atividade (consulte onSwitchMAMIdentityComplete abaixo).

No caso de definir uma Context identidade por meio de [setUIPolicyIdentity,]o resultado é relatado de forma assíncrona. Se for um , o SDK não sabe se a alteração de identidade foi bem-sucedida até que o início condicional seja executado, o que pode exigir que o usuário insira um PIN ou credenciais Context Activity corporativas. O aplicativo pode implementar um MAMSetUIIdentityCallback para receber esse resultado ou pode passar nulo para o objeto de retorno de chamada. Observe que, se uma chamada for feita enquanto o resultado de uma chamada anterior para no mesmo contexto ainda não tiver sido entregue, o novo retorno de chamada sobressaltou o antigo e o retorno de chamada original nunca receberá setUIPolicyIdentity setUIPolicyIdentity um resultado.

Você também pode definir a identidade de uma atividade diretamente por meio de um método em MAMActivity em vez de chamar MAMPolicyManager.setUIPolicyIdentity . Use o seguinte método para fazer isso:

     public final void switchMAMIdentity(final String newIdentity, final EnumSet<IdentitySwitchOption> options);

Você também pode substituir um método se quiser que o aplicativo seja notificado do resultado das tentativas de alterar a MAMActivity identidade dessa atividade.

    public void onSwitchMAMIdentityComplete(final MAMIdentitySwitchResult result);

Se você não substituir (ou chamar o método), uma opção de identidade com falha em uma atividade resultará onSwitchMAMIdentityComplete na atividade que está sendo super concluída. Se você substituir o método, você deve ter cuidado para que os dados corporativos não são exibidos após uma opção de identidade com falha.

Observação

Alternar a identidade pode exigir recriar a atividade. Nesse caso, o onSwitchMAMIdentityComplete retorno de chamada será entregue à nova instância da atividade.

Alterações implícitas de identidade

Além da capacidade do aplicativo de definir a identidade, um thread ou uma identidade de contexto pode mudar com base na entrada de dados de outro aplicativo gerenciado pelo Intune que tenha política de proteção de aplicativos.

Exemplos

  1. Se uma atividade for lançada a partir de um enviado por outro aplicativo MAM, a identidade da atividade será definida com base na identidade efetiva no outro aplicativo no ponto em que o foi Intent Intent enviado.

  2. Para serviços, a identidade do thread será definida da mesma forma para a duração de uma onStart ou onBind chamada. As chamadas para Binder a retornada onBind também definirão temporariamente a identidade do thread.

  3. Chamadas para um ContentProvider definirão igualmente a identidade do thread por sua duração.

Além disso, a interação do usuário com uma atividade pode causar uma opção de identidade implícita.

Exemplo: Um usuário cancelando um prompt de autorização durante resultará em uma mudança Resume implícita para uma identidade vazia.

O aplicativo recebe uma oportunidade para ser ciente dessas alterações e, se necessário, o aplicativo pode proibi-las. MAMService e MAMContentProvider expõem o seguinte método que as subclasses podem substituir:

public void onMAMIdentitySwitchRequired(final String identity,
        final AppIdentitySwitchResultCallback callback);

Na MAMActivity classe, um parâmetro adicional está presente no método:

public void onMAMIdentitySwitchRequired(final String identity,
        final AppIdentitySwitchReason reason,
        final AppIdentitySwitchResultCallback callback);
  • O AppIdentitySwitchReason captura a origem da opção implícita e pode aceitar os valores CREATE , e RESUME_CANCELLED NEW_INTENT . O motivo é usado quando a retomada da atividade faz com que PIN, autenticação ou outra interface do usuário de conformidade sejam exibidos e o usuário tenta cancelar essa interface do usuário, geralmente, embora o uso do botão RESUME_CANCELLED voltar.

    • O AppIdentitySwitchResultCallback é o seguinte:

      public interface AppIdentitySwitchResultCallback {
          /**
            * @param result
            *            whether the identity switch can proceed.
            */
          void reportIdentitySwitchResult(AppIdentitySwitchResult result);
        }
      

      Onde AppIdentitySwitchResult é SUCCESS ou FAILURE .

O método é chamado para todas as alterações implícitas de identidade, exceto aquelas feitas por onMAMIdentitySwitchRequired meio de um Binder retornado de MAMService.onMAMBind . As implementações padrão de onMAMIdentitySwitchRequired chamada imediata:

  • callback.reportIdentitySwitchResult(FAILURE) quando o motivo é RESUME_CANCELLED .

  • callback.reportIdentitySwitchResult(SUCCESS) em todos os outros casos.

    Não é esperado que a maioria dos aplicativos precise bloquear ou atrasar uma opção de identidade de uma maneira diferente, mas se um aplicativo precisar fazer isso, os seguintes pontos devem ser considerados:

    • Se uma opção de identidade for bloqueada, o resultado será o mesmo que se as configurações de compartilhamento tivessem proibido a entrada Receive de dados.

    • Se um Serviço estiver sendo executado no thread principal, deverá ser chamado de forma síncrona ou o thread da interface do usuário reportIdentitySwitchResult para de responder.

    • Para Activity criação, onMAMIdentitySwitchRequired será chamado antes onMAMCreate de . Se o aplicativo deve mostrar a interface do usuário para determinar se a opção de identidade deve ser exibida usando uma atividade diferente.

    • Em um , quando uma opção para a identidade vazia é solicitada com o motivo como , o aplicativo deve modificar a atividade retomada para exibir dados consistentes com essa opção Activity RESUME_CANCELLED de identidade. Se isso não for possível, o aplicativo deverá recusar a opção e o usuário será solicitado novamente a cumprir a política para a identidade de retomada (por exemplo, sendo apresentado com a tela de entrada pin do aplicativo).

      Observação

      Um aplicativo com várias identidades sempre receberá dados de entrada de aplicativos gerenciados e não gerenciados. É responsabilidade do aplicativo tratar dados de identidades gerenciadas de maneira gerenciada.

    Se uma identidade solicitada for gerenciada (use MAMPolicyManager.getIsIdentityManaged para verificar), mas o aplicativo não poderá usar essa conta (por exemplo, porque contas, como contas de email, devem ser configuradas primeiro no aplicativo), a opção de identidade deve ser recusada.

Criar considerações sobre plug-in/tool

Se você não herdar explicitamente [MAMActivity,] MAMServiceou MAMContentProvider (porque permite que a ferramenta de com build faça essa alteração), mas ainda precisar processar as opções de identidade, você poderá implementar MAMActivityIdentityRequirementListener para um ou Activity MAMIdentityRequirementListener para um ou Service ContentProviders . O comportamento padrão para MAMActivity.onMAMIdentitySwitchRequired pode ser acessado chamando o método estático MAMActivity.defaultOnMAMIdentitySwitchRequired(activity, identity, reason, callback) .

Da mesma forma, se você precisar substituir MAMActivity.onSwitchMAMIdentityComplete , poderá implementar sem herdar MAMActivityIdentitySwitchListener explicitamente de MAMActivity .

Opções de identidade e restrições de captura de tela

O MAM controla o Window sinalizador para impor a política de captura de FLAG_SECURE tela. Alguns aplicativos também podem FLAG_SECURE ser definidos para suas próprias finalidades. Quando a política do MAM não restringe capturas de tela, o MAM não modificará FLAG_SECURE . Na transição de uma identidade cuja política exige desabilitar capturas de tela para uma identidade cuja política não o faça, o MAM limpará FLAG_SECURE . Assim, o aplicativo não deve depender FLAG_SECURE do conjunto restante após uma transição de identidade.

Preservando identidade em operações assíncronas

É comum que operações no thread da interface do usuário enviem tarefas em segundo plano para outro thread. Um aplicativo com várias identidades deseja garantir que essas tarefas em segundo plano operem com a identidade apropriada, que geralmente é a mesma identidade usada pela atividade que as despachou. O SDK do MAM fornece MAMAsyncTask e MAMIdentityExecutors como uma conveniência para ajudar na preservação da identidade. Eles devem ser usados se a operação assíncrona puder gravar dados corporativos em um arquivo ou se comunicar com outros aplicativos.

MAMAsyncTask

Para usar , basta herdar dele em vez de e substituir substituições MAMAsyncTask de e com e com e AsyncTask doInBackground onPreExecute doInBackgroundMAM onPreExecuteMAM respectivamente. O MAMAsyncTask construtor tem um contexto de atividade. Por exemplo:

AsyncTask<Object, Object, Object> task = new MAMAsyncTask<Object, Object, Object>(thisActivity) {

    @Override
    protected Object doInBackgroundMAM(final Object[] params) {
        // Do operations.
    }

    @Override
    protected void onPreExecuteMAM() {
        // Do setup.
    };
}

MAMIdentityExecutors

MAMIdentityExecutorspermite que você envolva uma instância ou existente como uma preservação de Executor ExecutorService identidade com e Executor / ExecutorService wrapExecutor wrapExecutorService métodos. Por exemplo,

Executor wrappedExecutor = MAMIdentityExecutors.wrapExecutor(originalExecutor, activity);
ExecutorService wrappedService = MAMIdentityExecutors.wrapExecutorService(originalExecutorService, activity);

Proteção de Arquivos

Cada arquivo tem uma identidade associada a ele no momento da criação, com base na identidade do thread e do processo. Essa identidade será usada para criptografia de arquivo e limpeza seletiva. Somente arquivos cuja identidade é gerenciada e tem política que exige criptografia serão criptografados. A limpeza de funcionalidade seletiva padrão do SDK apagará apenas os arquivos associados à identidade gerenciada para a qual uma limpeza foi solicitada. O aplicativo pode consultar ou alterar a identidade de um arquivo usando a [classe MAMFileProtectionManager.]

Responsabilidade do aplicativo

O MAM não pode inferir automaticamente uma relação entre os arquivos que estão sendo lidos e os dados que estão sendo exibidos em Activity . Apps must set the UI identity appropriately before displaying corporate data. This includes data read from files. If a file comes from outside the app (either from a ContentProvider or read from a publicly writable location), the app must attempt to determine the file identity (using the correct MAMFileProtectionManager.getProtectionInfo overload for the data source) before displaying information read from the file. If getProtectionInfo reports a non-null, non-empty identity, the UI identity must be set to match this identity (using MAMActivity.switchMAMIdentity or MAMPolicyManager.setUIPolicyIdentity um ). Se a opção de identidade falhar, os dados do arquivo não devem ser exibidos. Ao ler de um URI de conteúdo, talvez seja necessário primeiro ler a identidade (por meio da sobrecarga que está tomando um ), em seguida, definir o contexto ou a identidade do thread adequadamente antes de abrir um descritor de arquivo ou fluxo de entrada no será getProtectionInfo bem-sucedido. Uri ContentResolver

Um fluxo de exemplo pode ter a seguinte aparência:

  • O usuário seleciona um documento a ser aberto no aplicativo.

  • Durante o fluxo aberto, antes de ler dados do disco, o aplicativo confirma a identidade que deve ser usada para exibir o conteúdo:

    MAMFileProtectionInfo info = MAMFileProtectionManager.getProtectionInfo(docPath)
    if (info != null)
        MAMPolicyManager.setUIPolicyIdentity(activity, info.getIdentity(), callback, EnumSet.noneOf<IdentitySwitchOption.class>)
    
  • O aplicativo aguarda até que um resultado seja relatado como retorno de chamada.

  • Se o resultado relatado for uma falha, o aplicativo não exibirá o documento.

  • O aplicativo abre e renderiza o arquivo.

Se um aplicativo usa o Android para baixar arquivos, o SDK MAM tentará proteger esses arquivos automaticamente usando a prioridade de DownloadManager identidade descrita anteriormente. O contexto usado para recuperar o DownloadManager será usado se a identidade do thread não foret. Se os arquivos baixados contêm dados corporativos, é responsabilidade do aplicativo chamar [proteger] se os arquivos são movidos ou recriados após o download.

Single-Identity transição de várias identidades

Se um aplicativo lançado anteriormente com a integração do Intune de identidade única mais tarde integrar várias identidades, os aplicativos instalados anteriormente para marcar arquivos ou diretórios específicos com a identidade vazia (que removerá a criptografia se eles foram will experience a transition (not visible to the user, there is no associated UX). The app is not required to do anything explicit to handle this transition. All files created before the transition will continue being regarded as managed (so they will stay encrypted if encryption policy is on). If desired, you can detect the upgrade and use MAMFileProtectionManager.protect criptografados).

Cenários offline

A marcação de identidade de arquivo é confidencial para o modo offline. Os seguintes pontos devem ser levados em consideração:

  • Se o Portal da Empresa não estiver instalado, os arquivos não poderão ser marcados com identidade.

  • Se o Portal da Empresa estiver instalado, mas o aplicativo não tiver a política do MAM do Intune, os arquivos não poderão ser marcados com identidade confiável.

  • Quando a marcação de identidade de arquivo fica disponível, todos os arquivos criados anteriormente são tratados como pessoais/não gerenciados (pertencentes à identidade de cadeia de caracteres vazia), a menos que o aplicativo tenha sido instalado anteriormente como um aplicativo gerenciado de identidade única, nesse caso, eles são tratados como pertencentes ao usuário inscrito.

Proteção de Diretório

Os diretórios podem ser protegidos usando o mesmo [método de] proteção usado para proteger arquivos. A proteção de diretório aplica-se recursivamente a todos os arquivos e subdiretivos contidos no diretório e aos novos arquivos criados no diretório. Como a proteção de diretório é aplicada de forma recursiva, a chamada pode levar algum tempo para ser concluída protect para diretórios grandes. Por esse motivo, os aplicativos que aplicam proteção a um diretório que contém um grande número de arquivos podem desejar ser executados de forma protect assíncrona em um thread em segundo plano.

Proteção de Dados

Não é possível marcar um arquivo como pertencente a várias identidades. Aplicativos que devem armazenar dados pertencentes a diferentes usuários no mesmo arquivo podem fazer isso manualmente, usando os recursos fornecidos por MAMDataProtectionManager. Isso permite que o aplicativo criptografe dados e os a tie a um usuário específico. Os dados criptografados são adequados para armazenar em disco em um arquivo. Você pode consultar os dados associados à identidade e os dados podem ser descriptografados posteriormente.

Os aplicativos que fazem uso do MAMDataProtectionManager devem implementar um receptor para a MANAGEMENT_REMOVED notificação. Depois que essa notificação for concluída, os buffers que foram protegidos por essa classe não poderão mais ser lidos se a criptografia de arquivo estiver habilitada quando os buffers foram protegidos. Um aplicativo pode remediar essa situação chamando MAMDataProtectionManager.unprotect todos os buffers durante essa notificação. Também é seguro chamar proteção durante essa notificação se desejar preservar informações de identidade - a criptografia é garantida para ser desabilitada durante a notificação.

Provedores de Conteúdo

Se o aplicativo fornece dados corporativos diferentes de um , o aplicativo deve chamar o método em ParcelFileDescriptor ContentProvider isProvideContentAllowed(String) MAMContentProvider, passando a UPN (nome principal do usuário) do proprietário para o conteúdo. Se essa função retornar false, o conteúdo não deverá ser retornado ao chamador. Os descritores de arquivo retornados por meio de um provedor de conteúdo são manipulados automaticamente com base na identidade do arquivo.

Se você não herdar explicitamente e permitir que a ferramenta de com build faça essa alteração, você poderá chamar uma versão estática MAMContentProvider do mesmo método: MAMContentProvider.isProvideContentAllowed(provider, contentIdentity) .

Limpeza Seletiva

Se um aplicativo de várias identidades se registrar para a WIPE_USER_DATA para um usuário pessoal ou a notification, it is the app's responsibility to remove all data for the user being wiped, including all files that have been identity-tagged as belonging to that user. If the app removes user data from a file but wishes to leave other data in the file, it must change the identity of the file (via MAMFileProtectionManager.protect identidade vazia). Se a política de criptografia estiver em uso, quaisquer arquivos restantes pertencentes ao usuário que está sendo apagado não serão descriptografados e se tornarão inacessíveis para o aplicativo após a limpeza.

Um aplicativo que está se registrando não receberá o benefício do comportamento de limpeza seletiva padrão WIPE_USER_DATA do SDK. Para aplicativos com várias identidades cientes, essa perda pode ser mais significativa, já que a limpeza seletiva padrão do MAM apagará somente os arquivos cuja identidade é direcionada por um apagamento. Se um aplicativo ciente de várias identidades desejar __ que a limpeza seletiva padrão do MAM seja feita e desejar executar suas próprias ações na limpeza, ele deverá se registrar para notificações WIPE_USER_AUXILIARY_DATA MAMNotificationType. Essa notificação será enviada imediatamente pelo SDK antes de executar a limpeza seletiva padrão do MAM. Um aplicativo nunca deve se registrar para WIPE_USER_DATA ambos e WIPE_USER_AUXILIARY_DATA .

A limpeza seletiva padrão fechará o aplicativo normalmente, encerrando atividades e encerrando o processo do aplicativo. Se seu aplicativo substituir a limpeza seletiva padrão, talvez você queira considerar fechar seu aplicativo manualmente para impedir que o usuário acesse dados na memória depois que uma limpeza ocorrer.

Habilitando a configuração direcionada ao MAM para seus aplicativos Android (opcional)

Os pares de valores de chave específicos do aplicativo podem ser configurados no console do Intune para MAM-WE e Android Enterprise. Esses pares de valores-chave não são interpretados pelo Intune, mas são passados para o aplicativo. Os aplicativos que querem receber essa configuração podem usar as classes MAMAppConfigManager e MAMAppConfig para fazer isso. Se várias políticas são direcionadas para o mesmo aplicativo, pode haver vários valores conflitantes disponíveis para a mesma chave.

Observação

A configuração de configurações para entrega via MAM-WE não pode ser entregue (quando o Portal da Empresa offline não está instalado). Somente o Enterprise AppRestrictions será entregue por meio de uma MAMUserNotification identidade vazia nesse caso.

Obter a configuração de aplicativo para um usuário

A configuração do aplicativo pode ser recuperada da seguinte forma:

MAMAppConfigManager configManager = MAMComponents.get(MAMAppConfigManager.class);
String identity = "user@contoso.com"
MAMAppConfig appConfig = configManager.getAppConfig(identity);

Se não houver nenhum usuário registrado no MAM, mas seu aplicativo ainda quiser recuperar a configuração do Android Enterprise (que não será direcionada a um usuário específico), você poderá passar uma cadeia de caracteres nulo ou vazia.

Conflitos

Um valor definido na configuração do aplicativo MAM substituirá um valor com a mesma chave definida no Android Enterprise config.

Se um administrador configurar valores conflitantes para a mesma chave (por exemplo, direcionando conjuntos de configurações de aplicativos diferentes com a mesma chave para vários grupos que contêm o mesmo usuário), o Intune não tem nenhuma maneira de resolver esse conflito automaticamente e disponibiliza todos os valores para seu aplicativo.

Seu aplicativo pode solicitar todos os valores de uma determinada chave de um objeto MAMAppConfig:

List<Boolean> getAllBooleansForKey(String key)
List<Long> getAllIntegersForKey(final String key)
List<Double> getAllDoublesForKey(final String key)
List<String> getAllStringsForKey(final String key)

ou solicitar um valor a ser escolhido:

Boolean getBooleanForKey(String key, BooleanQueryType queryType)
Long getIntegerForKey(String key, NumberQueryType queryType)
Double getDoubleForKey(String key, NumberQueryType queryType)
String getStringForKey(String key, StringQueryType queryType)

Seu aplicativo também pode solicitar os dados brutos como uma lista de conjuntos de pares de valores-chave.

List<Map<String, String>> getFullData()

Exemplo completo

MAMAppConfigManager configManager = MAMComponents.get(MAMAppConfigManager.class);
String identity = "user@contoso.com"
MAMAppConfig appConfig = configManager.getAppConfig(identity);
String fooValue = null;
if (appConfig.hasConflict("foo")) {
    List<String> values = appConfig.getAllStringsForKey("foo");
    fooValue = chooseBestValue(values);
} else {
    valueToUse = appConfig.getStringForKey("foo", MAMAppConfig.StringQueryType.Any);
}
Long barValue = appConfig.getIntegerForKey("bar", MAMAppConfig.NumberQueryType.Min);

Notificação

A configuração do aplicativo adiciona um novo tipo de notificação:

  • REFRESH_APP_CONFIG: essa notificação é enviada em um MAMUserNotification e informa ao aplicativo que os novos dados de configuração do aplicativo estão disponíveis.

Leitura posterior

Para obter mais informações sobre como criar uma política de configuração de aplicativo direcionada ao MAM no Android, consulte a seção sobre a configuração de aplicativo direcionado ao MAM em Como usar políticas de configuração de aplicativo Microsoft Intune para Android.

A configuração do aplicativo também pode ser configurada usando a API Graph de usuário. Para obter informações, consulte os documentos Graph API de configuração direcionada do MAM.

Temas personalizados (opcional)

Um tema personalizado pode ser fornecido ao SDK do MAM que será aplicado a todas as telas e caixas de diálogo do MAM. Se um tema não for fornecido, um tema MAM padrão será usado.

Como fornecer um tema

Para fornecer um tema, você precisa adicionar a seguinte linha de código no Application.onCreate método:

MAMThemeManager.setAppTheme(R.style.AppTheme);

No exemplo acima, você precisa substituir pelo R.style.AppTheme tema de estilo que deseja que o SDK aplique.

Personalização de estilo (preterido)

Isso agora é preterido e Temas Personalizados (acima) é a maneira preferencial de personalizar exibições.

Os views gerados pelo SDK do MAM podem ser personalizados visualmente para corresponder mais de perto ao aplicativo no qual ele está integrado. Você pode personalizar cores primárias, secundárias e de plano de fundo, bem como o tamanho do logotipo do aplicativo. Essa personalização de estilo é opcional e os padrões serão usados se nenhum estilo personalizado for configurado.

Como personalizar

Para que as alterações de estilo se apliquem aos modo de exibição do MAM do Intune, você deve primeiro criar um arquivo XML de substituição de estilo. Esse arquivo deve ser colocado no diretório "/res/xml" do seu aplicativo e você pode nomeá-lo como quiser. A seguir está um exemplo do formato que esse arquivo precisa seguir.

<?xml version="1.0" encoding="utf-8"?>
<styleOverrides>
    <item
        name="foreground_color"
        resource="@color/red"/>
    <item
        name="accent_color"
        resource="@color/blue"/>
    <item
        name="background_color"
        resource="@color/green"/>
    <item
        name="logo_image"
        resource="@drawable/app_logo"/>
</styleOverrides>

Você deve reutilizar recursos que já existem em seu aplicativo. Por exemplo, você deve definir a cor verde no arquivo colors.xml e fazer referência a ela aqui. Não é possível usar o código de cores Hex "#0000ff". O tamanho máximo do logotipo do aplicativo é 110 dip (dp). Você pode usar uma imagem de logotipo menor, mas aderir ao tamanho máximo gerará os resultados mais bem-semelhantes. Se você exceder o limite de 110 dip, a imagem será dimensionado para baixo e possivelmente causará desfocado.

Abaixo está a lista completa de atributos de estilo permitidos, os elementos da interface do usuário que eles controlam, os nomes de item de atributo XML e o tipo de recurso esperado para cada um.

Atributo Style Elementos da interface do usuário afetados Nome do item de atributo Tipo de recurso esperado
Cor da tela de fundo Cor de plano de fundo da tela PIN
Cor de preenchimento da caixa PIN
background_color Cor
Cor de primeiro plano Cor do texto em primeiro plano
Borda da caixa PIN no estado padrão
Caracteres (incluindo caracteres ofuscados) na caixa PIN quando o usuário insera um PIN
foreground_color Cor
Cor do destaque Borda da caixa PIN quando realçada
Hiperlinks
accent_color Cor
Logotipo do aplicativo Ícone grande que aparece na tela PIN do aplicativo Intune logo_image Desenhável

Registro padrão (opcional)

Veja a seguir as diretrizes para exigir o prompt do usuário no início do aplicativo para um registro automático do serviço APP-WE (chamamos esse registro padrão nesta seção), exigindo que as políticas de proteção de aplicativos do Intune permitam que apenas usuários protegidos do Intune usem seu aplicativo LOB Android integrado ao SDK. Ele também aborda como habilitar o SSO para seu aplicativo LOB android integrado ao SDK. Isso não é suportado para aplicativos da loja que podem ser usados por usuários que não são do Intune.

Observação

Os benefícios do registro padrão incluem um método simplificado de obtenção de política do serviço APP-WE para um aplicativo no dispositivo.

Observação

O registro padrão está ciente da nuvem soberana.

Habilitar o registro padrão com as seguintes etapas:

  1. Se o aplicativo integrar o MSAL ou você precisar habilitar o SSO, configure o MSAL seguindo configurações comuns do MSAL #2. Caso não seja, você pode ignorar esta etapa.

  2. Habilita o registro padrão adicionando o seguinte valor no manifesto sob a <application> marca:

    <meta-data android:name="com.microsoft.intune.mam.DefaultMAMServiceEnrollment" android:value="true" />
    

    Observação

    Essa deve ser a única integração MAM-WE no aplicativo. Se houver outras tentativas de chamar APIs MAMEnrollmentManager, surgirão conflitos.

  3. Habilita a política de MAM necessária adicionando o seguinte valor no manifesto sob a <application> marca:

    <meta-data android:name="com.microsoft.intune.mam.MAMPolicyRequired" android:value="true" />
    

    Observação

    Isso força o usuário a baixar o Portal da Empresa no dispositivo e concluir o fluxo de registro padrão antes do uso.

Limitações

Limitações de imposição de política

  • Usando Resolvedores de Conteúdo : a política "transferir ou receber" do Intune pode bloquear ou bloquear parcialmente o uso de um resolvedor de conteúdo para acessar o provedor de conteúdo em outro aplicativo. Isso fará com que os métodos retornem nulos ou lancem um valor ContentResolver de falha (por exemplo, openOutputStream serão atados se FileNotFoundException bloqueados). O aplicativo pode determinar se uma falha ao gravar dados por meio de um resolvedor de conteúdo foi causada pela política (ou seria causada pela política) fazendo a chamada:

    MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(contentURI);
    

    ou se não houver atividade associada:

      MAMPolicyManager.getCurrentThreadPolicy().getIsSaveToLocationAllowed(contentURI);
    

    Nesse segundo caso, os aplicativos de várias identidades devem ter o cuidado de definir a identidade do thread adequadamente (ou passar uma identidade explícita para uma getPolicyForIdentity chamada).

Serviços exportados

O arquivo AndroidManifest.xml incluído no SDK do Aplicativo do Intune contém MAMNotificationReceiverService, que deve ser um serviço exportado para permitir que o Portal da Empresa envie notificações para um aplicativo gerenciado. O serviço verifica o chamador para garantir que somente o Portal da Empresa tem permissão para enviar notificações.

Limitações de reflexão

Algumas das classes base do MAM (por exemplo, , ) contêm métodos (com base nas classes base do Android originais) que usam tipos de parâmetro ou retorno presentes apenas acima de determinados níveis MAMActivity MAMDocumentsProvider de API. Por esse motivo, talvez nem sempre seja possível usar a reflexão para enumerar todos os métodos de componentes do aplicativo. Essa restrição não se limita ao MAM, é a mesma restrição que se aplicaria se o próprio aplicativo implementou esses métodos a partir das classes base do Android.

Robolectric

Não há suporte para o teste do comportamento do SDK MAM em Robolectric. Há problemas conhecidos executando o SDK MAM em Robolectric devido a comportamentos presentes em Robolectric que não imitam com precisão aqueles em dispositivos reais ou emuladores.

Se você precisar testar seu aplicativo em Robolectric, a solução alternativa recomendada é mover sua lógica de classe de aplicativo para um auxiliar e produzir seu apk de teste de unidade com uma classe de aplicativo que não herda de MAMApplication.

Expectativas do consumidor do SDK

O SDK do Intune mantém o contrato fornecido pela API Android, embora as condições de falha possam ser disparadas com mais frequência como resultado da aplicação da política. Essas práticas recomendadas do Android reduzirão a probabilidade de falha:

  • As funções SDK do Android que podem retornar null têm uma maior probabilidade de serem nulas agora. Para minimizar problemas, verifique se as verificações nulas estão nos locais certos.

  • Os recursos que podem ser verificados devem ser verificados por meio de suas APIs de substituição de MAM.

  • Quaisquer funções derivadas devem ser chamada para suas versões de super classe.

  • Evite o uso de qualquer API de forma ambígua. Por exemplo, usar Activity.startActivityForResult sem verificar o requestCode causará comportamento estranho.

Serviços

A imposição de política pode afetar interações de serviço. Métodos que estabelecem uma conexão de serviço vinculada, como podem falhar devido à imposição de política subjacente e podem Context.bindService Service.onBind resultar em ou ServiceConnection.onNullBinding ServiceConnection.onServiceDisconnected . Interagir com um serviço vinculado estabelecido pode levar a uma imposição de SecurityException política em Binder.onTransact .

Telemetria

O SDK do Aplicativo do Intune para Android não controla a coleta de dados do seu aplicativo. O Portal da Empresa do aplicativo registra dados gerados pelo sistema por padrão. Esses dados são enviados para Microsoft Intune. De acordo com a Política da Microsoft, não coletamos dados pessoais.

Observação

Se os usuários finais optarem por não enviar esses dados, eles deverão desativar a telemetria em Configurações no Portal da Empresa aplicativo. Para saber mais, confira Desativar a coleção de dados de uso da Microsoft.

  • Todos os projetos de biblioteca devem compartilhar o mesmo android:package quando possível. Isso não falhará esporáticamente em tempo de executar; isso é puramente um problema de tempo de com build. Versões mais recentes do SDK do Aplicativo do Intune removerão parte da redundância.

  • Use as ferramentas de com build SDK do Android mais novas.

  • Remover todas as bibliotecas desnecessárias e nãousadas (por exemplo, android.support.v4)

Testar

Consulte o Guia de Teste.