1. Avant de commencer
Qu'est-ce qu'un profil professionnel ?
Un profil professionnel est un profil secondaire qui peut être activé sur l'appareil personnel d'un utilisateur lorsqu'une entreprise autorise ses employés à se servir de leurs appareils personnels pour le travail.
Les profils professionnels peuvent être contrôlés par un administrateur informatique. Les fonctionnalités disponibles sont définies séparément de celles du profil principal de l'utilisateur. Cette approche permet aux organisations de contrôler l'environnement d'exécution des applications et des données spécifiques à l'entreprise sur l'appareil d'un utilisateur, tout en laissant ce dernier utiliser ses applications et son profil personnels.
En quoi cela peut-il avoir une incidence sur votre application ? Toute application peut être installée sous un profil professionnel, ce qui signifie qu'elle peut être soumise à des restrictions d'exécution et à des changements de comportement. Vous devez également vous assurer que l'application est sécurisée si elle est utilisée à des fins professionnelles. Même si elle est exécutée sous un profil personnel, un profil professionnel peut avoir une incidence sur son comportement.
Conditions préalables
Cet atelier de programmation s'adresse aux développeurs Android disposant de compétences élémentaires à intermédiaires.
Nous partons du principe que vous avez déjà créé une application, que vous avez déjà utilisé Android Studio et que vous avez déjà testé votre application sur un appareil ou un émulateur.
Objectifs de l'atelier
Dans cet atelier de programmation, vous modifierez une application pour optimiser l'expérience utilisateur lorsqu'elle est installée sur un appareil avec un profil professionnel. Vous découvrirez comment votre application peut :
- traiter simultanément les contacts personnels et professionnels ;
- basculer du profil professionnel au profil personnel.
Ce dont vous avez besoin
- Un appareil Android non géré (qui n'appartient pas à une organisation ou n'est pas géré par celle-ci)
2. Configuration
Configurer un appareil de test
Nous vous recommandons d'utiliser un appareil physique pour cet atelier de programmation. Toutefois, vous pouvez effectuer la configuration ci-dessous sur un émulateur à l'aide d'une image incluant le Google Play Store.
TestDPC
Google développe l'application TestDPC pour vous aider à simuler et à tester un environnement géré sur votre propre appareil. Elle permet de configurer un profil professionnel et d'activer ou de désactiver certaines fonctionnalités de l'appareil, comme le ferait un administrateur informatique.
Installer l'application TestDPC
Sur votre appareil, ouvrez le Google Play Store et téléchargez l'application TestDPC.
Configurer un profil professionnel
Une fois l'application TestDPC installée, deux icônes doivent apparaître sur l'appareil : une icône de configuration et l'icône de l'application TestDPC. Appuyez sur l'icône de configuration et suivez les étapes.
Vous disposez désormais de deux profils distincts, un pour les applications personnelles et un pour les applications professionnelles. Vous pouvez passer de l'un à l'autre via les onglets situés en haut de la liste d'applications.
Notez que chaque profil a sa propre application Play Store. Vous pouvez repérer les applications professionnelles grâce à l'image représentant un porte-documents au-dessus de l'icône du lanceur.
Vous pouvez installer des applications via le Play Store comme d'habitude. En fonction du Play Store que vous lancez (personnel ou professionnel), l'application ne sera installée que dans le profil correspondant. Les applications peuvent également se trouver dans les deux profils lorsqu'elles sont installées depuis les deux Play Store. Dans ce cas, chaque version de l'application disposera d'une configuration et d'un espace de stockage totalement isolés.
Installer l'application sur un profil spécifique
Dans les paragraphes suivants, nous verrons comment passer du profil par défaut au profil professionnel, et vice versa, avec la classe CrossProfileApps. Pour confirmer ce comportement, l'application doit être installée dans les deux profils.
Vous pouvez confirmer l'ID du profil à l'aide de la commande adb ci-dessous.
$ adb shell pm list users
Vous pouvez installer une application dans un profil désigné à l'aide de la commande adb ci-dessous.
$ adb install --user [id number of profile] [path of apk file]
Vous pouvez obtenir les mêmes résultats avec la définition de la configuration d'exécution/de débogage dans votre projet en sélectionnant l'option "Install for all users" (Installer pour tous les utilisateurs).
Lorsque vous mettez à jour l'application en l'exécutant à partir d'Android Studio, elle est installée dans les deux profils.
3. Charger les contacts
Configurez des contacts de test à utiliser dans l'application de démonstration :
- Lancez l'application Contacts de l'appareil à partir du profil personnel.
- Ajoutez des contacts de test que vous pouvez identifier comme des contacts personnels.
- Lancez l'application Contacts à partir du profil professionnel. Notez que les contacts personnels que vous venez d'ajouter ne s'y trouvent pas.
- Ajoutez des contacts de test que vous pouvez identifier en tant que contacts professionnels.
Une fois que vous êtes satisfait des contacts que vous avez configurés, essayez le code de démarrage de l'application de démonstration.
4. Télécharger le code de démarrage
- Pour télécharger l'application exemple, deux options s'offrent à vous :
- Clonez le dépôt depuis GitHub.
$ git clone https://github.com/android/enterprise-samples.git $ cd enterprise-samples/Work-profile-codelab
- Téléchargez le projet via le lien ci-dessous.
- Ouvrez et créez l'application dans Android Studio.
Voici ce à quoi ressemble l'application lorsque vous la lancez pour la première fois :
Essayer
À la fin de cet atelier de programmation, votre application affichera les contacts professionnels et personnels lorsqu'elle sera exécutée dans le profil personnel. Vous pourrez également passer d'un profil à l'autre en lançant une autre instance de l'application dans l'autre profil à partir de l'application elle-même.
5. Afficher à la fois les contacts personnels et professionnels
Lors du chargement des contacts à l'aide de ContactsContract.Contacts.CONTENT_URI
, l'application choisit les contacts à afficher en fonction du profil dans lequel elle est exécutée. Toutefois, dans de nombreux cas, vous souhaiterez peut-être que l'application charge les deux listes de contacts à la fois. Par exemple, un utilisateur peut vouloir partager un élément personnel (photo, document) avec un collègue de travail. Pour ce faire, vous devez récupérer les deux listes de contacts.
Ouvrez MainActivity.kt.
La méthode onCreateLoader()
permet de créer le chargeur de curseur pour récupérer et charger les contacts. Actuellement, elle ne renvoie qu'un indicateur CursorLoader à l'aide de la valeur ContentURI par défaut. Vous appellerez cette méthode deux fois : une fois pour les contacts personnels et une autre pour les contacts professionnels. Pour les différencier, nous transmettrons un ID différent à onCreateLoader()
pour chaque cas. Vous devrez vérifier l'ID transmis dans la méthode pour décider de l'URI à utiliser.
Tout d'abord, modifiez la valeur de la variable ContentURI en fonction de la valeur de l'ID transmis à la méthode. Dans le cas de PERSONAL_CONTACTS_LOADER_ID, attribuez-la à l'élément ContactsContract.Contacts.CONTENT_URI
par défaut. Dans le cas contraire, vous créerez un élément ENTERPRISE_CONTENT_FILTER_URI
comme décrit ici.
ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI
.buildUpon()
.appendPath(nameFilter)
.appendQueryParameter(
ContactsContract.DIRECTORY_PARAM_KEY,
ContactsContract.Directory.ENTERPRISE_DEFAULT.toString()
)
.build()
Dans la mesure où il s'agit d'un URI de filtre de contenu, l'outil de création requiert un filtre de recherche (expression de recherche) qui servira à rechercher/charger les contacts.
Pour l'instant, codez l'expression de recherche en dur en lui donnant n'importe quel nom commençant par la lettre "a".
val nameFilter = Uri.encode("a") // names that start with a
Vous devez également spécifier le répertoire de contacts à rechercher. Vous utiliserez le répertoire ENTERPRISE_DEFAULT
, qui recherchera les contacts stockés localement sur l'appareil.
Votre méthode onCreateLoader()
devrait se présenter comme suit :
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
val nameFilter = Uri.encode("a") // names that start with a
val contentURI = when (id) {
PERSONAL_CONTACTS_LOADER_ID -> ContactsContract.Contacts.CONTENT_URI
else -> {
ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI
.buildUpon()
.appendPath(nameFilter)
.appendQueryParameter(
ContactsContract.DIRECTORY_PARAM_KEY,
ContactsContract.Directory.ENTERPRISE_DEFAULT.toString()
)
.build()
}
}
return CursorLoader(
this, contentURI, arrayOf(
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
), null, null, null
)
}
Vous devez maintenant initialiser un autre Loader
avec une nouvelle valeur d'ID pour déclencher la méthode ci-dessus.
Commencez par créer une valeur d'ID constante pour les contacts professionnels en haut de MainActivity
:
const val WORK_CONTACTS_LOADER_ID = 1
Ensuite, dans initLoaders()
, utilisez LoaderManager
pour initialiser un nouveau Loader
avec le nouvel ID créé au-dessus :
private fun initLoaders() {
LoaderManager.getInstance(this).
initLoader(PERSONAL_CONTACTS_LOADER_ID, null, this)
LoaderManager.getInstance(this).
initLoader(WORK_CONTACTS_LOADER_ID, null, this)
}
Toutes les autres méthodes devraient fonctionner de la même façon, car le curseur de données des deux chargeurs a la même structure.
Essayer
Exécutez l'application dans votre profil personnel pour afficher vos contacts professionnels et personnels.
Qu'en est-il du profil professionnel ?
Si vous exécutez l'application dans le profil professionnel, seuls les contacts professionnels s'affichent, pas les contacts personnels. Cela s'explique par le fait que l'un des principaux objectifs des profils professionnels est de protéger la confidentialité des données des utilisateurs. Par conséquent, les applications professionnelles ne permettent généralement pas d'accéder aux informations des profils personnels.
6. Changer de profil dans une application
Android inclut des API pour lancer une autre instance de l'application dans un profil différent, ce qui permet aux utilisateurs de changer de compte. Par exemple, une application de messagerie peut fournir une interface utilisateur qui permet à l'utilisateur de passer d'un profil personnel à un profil professionnel et d'accéder à deux comptes de messagerie.
Toutes les applications peuvent appeler ces API pour lancer l'activité principale de la même application si celle-ci est déjà installée dans l'autre profil.
Pour ajouter la possibilité de changer de compte entre différents profils dans votre application, vous devez d'abord ajouter un bouton à la mise en page de l'activité principale. Ce bouton permettra aux utilisateurs de changer de profil.
Ouvrez activity_main.xml
et ajoutez un widget de bouton sous le widget recycler-view :
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/button"
app:layout_constraintTop_toBottomOf="@+id/contacts_rv"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Revenez dans MainActivity.kt
et définissez l'événement de clic du bouton pour qu'il change de profil dans la méthode onCreate
.
Pour ce faire, commencez par récupérer le service système CrossProfileApps
:
val crossProfileApps = getSystemService(CrossProfileApps::class.java)
Cette classe fournit toutes les API dont vous avez besoin pour implémenter une fonctionnalité permettant de changer de profil. Vous pouvez récupérer la liste des profils utilisateur en appelant targetUserProfiles
, qui affichera tous les autres profils dans lesquels cette application est installée.
val userHandles = crossProfileApps.targetUserProfiles
Vous pouvez maintenant utiliser le premier élément userHandle renvoyé et lancer l'application dans l'autre profil.
crossProfileApps.startMainActivity(
componentName,
userHandles.first()
)
Vous pouvez même obtenir un texte localisé invitant l'utilisateur à changer de profil et l'utiliser pour définir la valeur de texte du bouton.
val label = crossProfileApps.getProfileSwitchingLabel(userHandles.first())
À présent, si l'on réunit tous ces éléments, voici ce que vous ajouterez à la fin de la méthode onCreate au niveau de MainActivity.kt :
override fun onCreate(savedInstanceState: Bundle?) {
...
val crossProfileApps = getSystemService(CrossProfileApps::class.java)
val userHandles = crossProfileApps.targetUserProfiles
val label = crossProfileApps.getProfileSwitchingLabel(userHandles.first())
binding.button.apply {
text = label
setOnClickListener {
crossProfileApps.startMainActivity(
componentName,
userHandles.first()
)
}
}
}
Essayer
Si vous exécutez l'application maintenant, le bouton en bas de l'écran vous indiquera qu'elle est prête à basculer vers le profil professionnel ou le profil personnel, selon le profil depuis lequel vous l'avez lancée.
Cliquez sur ce bouton pour lancer l'application dans l'autre profil.
7. Félicitations !
Vous avez modifié une application qui fonctionne à la fois dans les profils personnels et professionnels, et qui récupère les contacts professionnels, même en mode personnel, lorsqu'elle détecte l'ajout de contacts professionnels dans le profil professionnel.
Vous avez également créé un moyen pour les utilisateurs de basculer entre les profils professionnel et personnel de la même application lorsqu'ils exécutent l'application sans avoir à la fermer et à la redémarrer depuis le profil approprié. Il s'agit d'une bonne pratique pour les utilisateurs qui font un usage différent de votre application dans différents profils.