Si vous développez des applications pour les grandes entreprises, vous devrez peut-être répondre à des exigences particulières définies par les règles d'une organisation. Les configurations gérées, auparavant appelées restrictions d'application, permettent à l'administrateur informatique de l'organisation de spécifier à distance les paramètres des applications. Cette fonctionnalité est particulièrement utile pour les applications approuvées par l'organisation qui sont déployées dans un profil professionnel.
Par exemple, une organisation peut exiger que les applications approuvées autorisent l'administrateur informatique à:
- Autoriser ou bloquer des URL pour un navigateur Web
- Indiquez si une application est autorisée à synchroniser le contenu via les réseaux mobiles ou uniquement par Wi-Fi.
- Configurer les paramètres de messagerie de l'application
Ce guide explique comment implémenter des paramètres de configuration gérés dans votre application. Pour afficher des exemples d'applications avec une configuration gérée, consultez ManagedConfigurations. Si vous êtes un développeur EMM (Enterprise Mobility Management, gestion de la mobilité en entreprise), consultez le guide de l'API Android Management.
Remarque:Pour des raisons historiques, ces paramètres de configuration sont appelés restrictions. Ils sont implémentés avec des fichiers et des classes qui utilisent ce terme (par exemple,RestrictionsManager
). Cependant, ces restrictions peuvent en réalité implémenter un large éventail d'options de configuration, et pas seulement des restrictions sur les fonctionnalités de l'application.
Présentation de la configuration à distance
Les applications définissent les options de configuration gérée qu'un administrateur informatique peut définir à distance. Il s'agit de paramètres arbitraires pouvant être modifiés par un fournisseur de configuration gérée. Si votre application s'exécute dans un profil professionnel, l'administrateur informatique peut modifier la configuration gérée de votre application.
Le fournisseur de configurations gérées est une autre application exécutée sur le même appareil. Cette application est généralement contrôlée par l'administrateur informatique. L'administrateur informatique communique les modifications de configuration à l'application du fournisseur de configuration gérée, qui, à son tour, modifie les configurations de votre application.
Pour fournir des configurations gérées en externe:
- Déclarez les configurations gérées dans le fichier manifeste de votre application. Cela permet à l'administrateur informatique de lire les configurations de l'application via les API Google Play.
- Chaque fois que l'application est réactivée, utilisez l'objet
RestrictionsManager
pour vérifier les configurations gérées actuelles, et modifier l'interface utilisateur et le comportement de votre application pour qu'ils soient conformes à ces configurations. - Écoutez l'intent
ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Lorsque vous recevez cette diffusion, vérifiez leRestrictionsManager
pour connaître les configurations gérées actuelles et apporter les modifications nécessaires au comportement de votre application.
Définir les configurations gérées
Votre application est compatible avec toutes les configurations gérées que vous souhaitez définir. Vous devez déclarer les configurations gérées de l'application dans un fichier de configuration géré et le déclarer dans le fichier manifeste. La création d'un fichier de configuration permet à d'autres applications d'examiner les configurations gérées fournies par votre application. Les partenaires EMM peuvent consulter les configurations de votre application à l'aide des API Google Play.
Pour définir les options de configuration à distance de votre application, placez l'élément suivant dans l'élément
<application>
de votre fichier manifeste:
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
Créez un fichier nommé app_restrictions.xml
dans le répertoire res/xml
de votre application. La structure de ce fichier est décrite dans la documentation de référence sur RestrictionsManager
. Le fichier comporte un seul élément <restrictions>
de premier niveau, qui contient un élément enfant <restriction>
pour chaque option de configuration de l'application.
Remarque:Ne créez pas de versions localisées du fichier de configuration géré. Votre application ne peut avoir qu'un seul fichier de configuration géré. Les configurations seront donc cohérentes pour votre application dans tous les paramètres régionaux.
Dans un environnement d'entreprise, un EMM utilise généralement le schéma de configuration géré pour générer une console à distance pour les administrateurs informatiques, afin que ceux-ci puissent configurer votre application à distance.
Le fournisseur de configuration gérée peut interroger l'application pour obtenir des détails sur les configurations disponibles pour l'application, y compris leur texte de description. Le fournisseur de configurations et l'administrateur informatique peuvent modifier les configurations gérées de votre application à tout moment, même lorsque l'application n'est pas en cours d'exécution.
Par exemple, supposons que votre application puisse être configurée à distance pour autoriser ou interdire le téléchargement de données via une connexion mobile. Votre application peut comporter un élément <restriction>
comme celui-ci:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android"> <restriction android:key="downloadOnCellular" android:title="@string/download_on_cell_title" android:restrictionType="bool" android:description="@string/download_on_cell_description" android:defaultValue="true" /> </restrictions>
Vous pouvez utiliser l'attribut android:key
de chaque configuration pour lire sa valeur à partir d'un bundle de configuration géré. C'est pourquoi chaque configuration doit comporter une chaîne de clé unique, et la chaîne ne peut pas être localisée. Elle doit être spécifiée à l'aide d'un littéral de chaîne.
Remarque:Dans une application de production, android:title
et android:description
doivent être extraits d'un fichier de ressources localisés, comme décrit dans la section Localiser avec des ressources.
Une application définit des restrictions à l'aide de bundles dans un bundle_array
.
Par exemple, une application avec plusieurs options de connexion VPN peut définir chaque configuration de serveur VPN dans un élément bundle
, avec plusieurs groupes regroupés dans un tableau de bundles:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > <restriction android:key="vpn_configuration_list" android:restrictionType="bundle_array"> <restriction android:key="vpn_configuration" android:restrictionType="bundle"> <restriction android:key="vpn_server" android:restrictionType="string"/> <restriction android:key="vpn_username" android:restrictionType="string"/> <restriction android:key="vpn_password" android:restrictionType="string"/> </restriction> </restriction> </restrictions>
Les types acceptés pour l'élément android:restrictionType
sont répertoriés dans le Tableau 1, et documentés dans la documentation de référence pour RestrictionsManager
et RestrictionEntry
.
Type | android:restrictionType | Utilisation standard |
---|---|---|
TYPE_BOOLEAN
|
"bool" |
Valeur booléenne, "true" ou "false". |
TYPE_STRING
|
"string" |
Valeur de chaîne, telle qu'un nom. |
TYPE_INTEGER
|
"integer" |
Entier avec une valeur comprise entre MIN_VALUE et MAX_VALUE .
|
TYPE_CHOICE
|
"choice" |
Valeur de chaîne sélectionnée dans android:entryValues , généralement présentée sous la forme d'une liste à sélection unique.
|
TYPE_MULTI_SELECT
|
"multi-select" |
Tableau de chaînes avec des valeurs sélectionnées à partir de android:entryValues .
Utilisez cette option pour présenter une liste à sélection multiple dans laquelle plusieurs entrées peuvent être sélectionnées, par exemple pour choisir des titres spécifiques à ajouter à la liste d'autorisation.
|
TYPE_NULL
|
"hidden" |
Type de restriction masqué. Utilisez ce type pour les informations qui doivent être transférées, mais qui ne doivent pas être présentées à l'utilisateur dans l'interface utilisateur. Stocke une seule valeur de chaîne. |
TYPE_BUNDLE_ARRAY
|
"bundle_array" |
Utilisez cette option pour stocker des tableaux soumis à une restriction bundles . Disponible dans Android 6.0 (niveau d'API 23).
|
Remarque:Les fichiers android:entryValues
sont lisibles par un ordinateur et ne peuvent pas être localisés. Utilisez android:entries
pour présenter des valeurs lisibles par l'humain et pouvant être localisées.
Chaque entrée doit avoir un index correspondant dans android:entryValues
.
Vérifier les configurations gérées
Votre application n'est pas automatiquement avertie lorsque d'autres applications modifient ses paramètres de configuration. À la place, vous devez vérifier quelles sont les configurations gérées au démarrage ou à la reprise de votre application, et écouter un intent système pour savoir si les configurations changent pendant l'exécution de votre application.
Pour connaître les paramètres de configuration actuels, votre application utilise un objet RestrictionsManager
. Votre application doit rechercher les configurations gérées actuelles aux moments suivants:
- Lorsque l'application démarre ou redémarre, dans sa méthode
onResume()
- Lorsque l'application est informée d'une modification de configuration, comme décrit dans Écouter les modifications de configuration gérées.
Pour obtenir un objet RestrictionsManager
, récupérez l'activité actuelle avec getActivity()
, puis appelez la méthode Activity.getSystemService()
de cette activité:
Kotlin
var myRestrictionsMgr = activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
Java
RestrictionsManager myRestrictionsMgr = (RestrictionsManager) getActivity() .getSystemService(Context.RESTRICTIONS_SERVICE);
Une fois que vous disposez d'un RestrictionsManager
, vous pouvez obtenir les paramètres de configuration actuels en appelant sa méthode getApplicationRestrictions()
:
Kotlin
var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions
Java
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
Remarque:Pour plus de commodité, vous pouvez également récupérer les configurations actuelles avec un UserManager
en appelant UserManager.getApplicationRestrictions()
. Cette méthode se comporte exactement de la même manière que RestrictionsManager.getApplicationRestrictions()
.
La méthode getApplicationRestrictions()
nécessite la lecture à partir d'un espace de stockage de données. Elle doit donc être effectuée avec parcimonie. N'appelez pas cette méthode chaque fois que vous avez besoin de connaître la configuration actuelle. Vous devez l'appeler une fois au démarrage ou à la reprise de votre application et mettre en cache le bundle de configurations gérées récupérés. Écoutez ensuite l'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
pour savoir si la configuration change lorsque votre application est active, comme décrit dans la section Écouter les modifications de configuration gérée.
Lire et appliquer les configurations gérées
La méthode getApplicationRestrictions()
renvoie un objet Bundle
contenant une paire clé/valeur pour chaque configuration définie. Les valeurs sont toutes de type Boolean
, int
, String
et String[]
. Une fois que vous disposez des configurations gérées Bundle
, vous pouvez vérifier les paramètres de configuration actuels à l'aide des méthodes Bundle
standards pour ces types de données, telles que getBoolean()
ou getString()
.
Remarque:Les configurations gérées Bundle
contiennent un élément pour chaque configuration explicitement définie par un fournisseur de configurations gérées. Cependant, vous ne pouvez pas supposer qu'une configuration sera présente dans le bundle simplement parce que vous avez défini une valeur par défaut dans le fichier XML des configurations gérées.
Il appartient à votre application de prendre les mesures appropriées en fonction des paramètres de configuration gérée actuels. Par exemple, si votre application dispose d'une configuration spécifiant si elle peut télécharger des données via une connexion mobile et que vous constatez qu'elle est définie sur false
, vous devez désactiver le téléchargement de données, sauf lorsque l'appareil est connecté au Wi-Fi, comme illustré dans l'exemple de code suivant:
Kotlin
val appCanUseCellular: Boolean = if (appRestrictions.containsKey("downloadOnCellular")) { appRestrictions.getBoolean("downloadOnCellular") } else { // cellularDefault is a boolean using the restriction's default value cellularDefault } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Java
boolean appCanUseCellular; if (appRestrictions.containsKey("downloadOnCellular")) { appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular"); } else { // cellularDefault is a boolean using the restriction's default value appCanUseCellular = cellularDefault; } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Pour appliquer plusieurs restrictions imbriquées, lisez l'entrée de restriction bundle_array
comme une collection d'objets Parcelable
et castez-la en tant que Bundle
. Dans cet exemple, les données de configuration de chaque VPN sont analysées et utilisées pour créer une liste de choix de connexions au serveur:
Kotlin
// VpnConfig is a sample class used store config data, not defined val vpnConfigs = mutableListOf<VpnConfig>() val parcelables: Array<out Parcelable>? = appRestrictions.getParcelableArray("vpn_configuration_list") if (parcelables?.isNotEmpty() == true) { // iterate parcelables and cast as bundle parcelables.map { it as Bundle }.forEach { vpnConfigBundle -> // parse bundle data and store in VpnConfig array vpnConfigs.add(VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))) } } if (vpnConfigs.isNotEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Java
// VpnConfig is a sample class used store config data, not defined List<VpnConfig> vpnConfigs = new ArrayList<>(); Parcelable[] parcelables = appRestrictions.getParcelableArray("vpn_configuration_list"); if (parcelables != null && parcelables.length > 0) { // iterate parcelables and cast as bundle for (int i = 0; i < parcelables.length; i++) { Bundle vpnConfigBundle = (Bundle) parcelables[i]; // parse bundle data and store in VpnConfig array vpnConfigs.add(new VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))); } } if (!vpnConfigs.isEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Écouter les modifications de la configuration gérée
Chaque fois que les configurations gérées d'une application sont modifiées, le système déclenche l'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
. Votre application doit écouter cet intent afin que vous puissiez modifier son comportement en cas de modification des paramètres de configuration.
Remarque:L'intent ACTION_APPLICATION_RESTRICTIONS_CHANGED
n'est envoyé qu'aux écouteurs enregistrés de manière dynamique, non aux écouteurs déclarés dans le fichier manifeste de l'application.
Le code suivant montre comment enregistrer de manière dynamique un broadcast receiver pour cet intent:
Kotlin
val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) val restrictionsReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // Get the current configuration bundle val appRestrictions = myRestrictionsMgr.applicationRestrictions // Check current configuration settings, change your app's UI and // functionality as necessary. } } registerReceiver(restrictionsReceiver, restrictionsFilter)
Java
IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get the current configuration bundle Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); // Check current configuration settings, change your app's UI and // functionality as necessary. } }; registerReceiver(restrictionsReceiver, restrictionsFilter);
Remarque:Habituellement, votre application n'a pas besoin d'être avertie des modifications de configuration lorsqu'elle est suspendue. Annulez l'enregistrement de votre broadcast receiver lorsque l'application est suspendue. Lorsque l'application redémarre, vous devez d'abord vérifier les configurations gérées actuelles (comme indiqué dans la section Vérifier les configurations gérées), puis enregistrer votre broadcast receiver pour vous assurer que vous êtes informé des modifications de configuration qui se produisent lorsque l'application est active.
Envoyer des commentaires sur la configuration gérée aux EMM
Après avoir appliqué les modifications de configuration gérée à votre application, il est recommandé d'informer les EMM de l'état de ces modifications. Android accepte une fonctionnalité appelée états d'application appariés, que vous pouvez utiliser pour envoyer des commentaires chaque fois que votre application tente d'appliquer des modifications de configuration gérée. Ces commentaires peuvent vous permettre de confirmer que votre application a bien défini des configurations gérées ou d'inclure un message d'erreur si votre application n'a pas appliqué les modifications spécifiées.
Les fournisseurs EMM peuvent récupérer ces commentaires et les afficher dans leur console pour les administrateurs informatiques. Pour en savoir plus à ce sujet, y compris un guide détaillé sur l'ajout de commentaires à votre application, consultez la section Envoyer des commentaires sur les applications aux fournisseurs EMM.
Autres exemples de code
L'exemple ManagedConfigurations illustre davantage l'utilisation des API abordées sur cette page.