Ce guide du développeur explique comment améliorer votre application afin d'utiliser les contacts les données du profil professionnel. Si vous n'avez pas utilisé les API de contacts d'Android auparavant, consultez la section Fournisseur de contacts pour vous familiariser avec les API.
Présentation
Les appareils dotés d'un profil professionnel stockent les contacts dans un espace de stockage local distinct. pour les profils professionnel et personnel. Par défaut, lorsqu'une application s'exécute dans le profil personnel, elle n'affiche pas les contacts professionnels. Toutefois, une application peut accéder aux coordonnées du profil professionnel. Par exemple, une application qui il s'agit de l'application Contacts de Google qui affiche à la fois les contacts de l'annuaire professionnel dans les résultats de recherche.
Les utilisateurs souhaitent souvent utiliser leurs applications et appareils personnels pour le travail. En utilisant contacts du profil professionnel, votre application peut faire partie de la journée de travail de vos utilisateurs.
Expérience utilisateur
Réfléchissez à la manière dont votre application peut présenter les coordonnées du profil professionnel. La meilleure approche dépend de la nature de votre application et de la raison pour laquelle les utilisateurs l'utiliser, mais pensez aux points suivants:
- Votre application doit-elle inclure les contacts du profil professionnel par défaut ou si l'utilisateur à activer ?
- En quoi la combinaison ou la séparation des contacts professionnels et personnels a-t-elle une incidence sur du flux utilisateur ?
- Que se passe-t-il si vous appuyez accidentellement sur un contact d'un profil professionnel ?
- Qu'advient-il de l'interface de votre application lorsque les contacts du profil professionnel ne sont pas ? disponibles ?
Votre application doit indiquer clairement un contact du profil professionnel. Vous pouvez peut-être badge le contact à l'aide d'une icône de travail familière, comme une mallette.
Par exemple, l'application Google Contacts (voir figure 1) effectue les opérations suivantes pour : afficher à la fois des contacts professionnels et personnels:
- Insère un sous-titre pour séparer les sections professionnelle et personnelle de la liste.
- Badge des contacts professionnels avec une icône en forme de mallette.
- Ouvre un contact professionnel dans le profil professionnel lorsque l'utilisateur appuie dessus.
Si la personne qui utilise l'appareil désactive le profil professionnel, votre application ne pourra pas rechercher des coordonnées dans le profil professionnel ou dans le journal de bord de l'organisation des annuaires de contacts. Selon la façon dont vous utilisez les contacts du profil professionnel, vous pouvez : omettez ces contacts de manière silencieuse ou vous devrez peut-être désactiver l'interface utilisateur .
Autorisations
Si votre application fonctionne déjà avec les contacts de l'utilisateur, vous disposez de ses
READ_CONTACTS
(ou éventuellement
WRITE_CONTACTS
) que vous avez demandée dans votre
fichier manifeste de l'application. Parce qu'une même personne utilise le profil personnel et le profil professionnel
vous n'avez pas besoin d'une autorisation supplémentaire pour accéder aux données de contact
profil.
Un administrateur informatique peut bloquer le profil professionnel partageant les coordonnées avec le profil personnel. Si un responsable IT administrateur bloque l'accès, vos recherches de contacts sont renvoyées sous forme de résultats vides. Votre application n'a pas besoin de gérer des erreurs spécifiques si l'utilisateur a désactivé le travail profil. Le fournisseur de contenu de l'annuaire continue de renvoyer des informations l'annuaire des contacts professionnels de l'utilisateur (voir la section Répertoires). Pour tester ces autorisations, consultez la page Développement et tests. .
Recherches de contacts
Vous pouvez récupérer les contacts du profil professionnel à l'aide des mêmes API et processus que ceux utilisés que votre application utilise pour obtenir les contacts du profil personnel. L'URI d'entreprise de Contacts est compatible avec Android 7.0 (niveau d'API 24) ou version ultérieure. Vous devez faire en sorte les ajustements suivants à l'URI:
- Définir l'URI du fournisseur de contenu sur
Contacts.ENTERPRISE_CONTENT_FILTER_URI
, et indiquez le nom du contact sous forme de chaîne de requête. - Définissez un répertoire de contacts dans lequel effectuer la recherche. Par exemple :
ENTERPRISE_DEFAULT
trouve des contacts dans le travail le magasin local de la fiche.
La modification de l'URI fonctionne avec n'importe quel mécanisme de fournisseur de contenu, tel qu'un
CursorLoader
: idéal pour charger des données de contact dans des interfaces utilisateur, car
l'accès aux données a lieu sur un thread de nœud de calcul. Par souci de simplicité, les exemples
appel de guide ContentResolver.query()
. Voici comment trouver
contacts figurant dans le répertoire local des contacts du profil professionnel:
Kotlin
// First confirm the device user has given permission for the personal profile. // There isn't a separate work permission, but an IT admin can block access. val readContactsPermission = ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_CONTACTS) if (readContactsPermission != PackageManager.PERMISSION_GRANTED) { return } // Fetch Jackie, James, & Jason (and anyone else whose names begin with "ja"). val nameQuery = Uri.encode("ja") // Build the URI to look up work profile contacts whose name matches. Query // the default work profile directory which is the locally-stored contacts. val contentFilterUri = ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI .buildUpon() .appendPath(nameQuery) .appendQueryParameter( ContactsContract.DIRECTORY_PARAM_KEY, ContactsContract.Directory.ENTERPRISE_DEFAULT.toString() ) .build() // Query the content provider using the generated URI. var cursor = getContentResolver() .query( contentFilterUri, arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY ), null, null, null ) // Print any results found using the work profile contacts' display name. cursor?.use { while (it.moveToNext()) { Log.i(TAG, "Work profile contact: ${it.getString(2)}") } }
Java
// First confirm the device user has given permission for the personal profile. // There isn't a separate work permission, but an IT admin can block access. int readContactsPermission = ContextCompat.checkSelfPermission( getBaseContext(), Manifest.permission.READ_CONTACTS); if (readContactsPermission != PackageManager.PERMISSION_GRANTED) { return; } // Fetch Jackie, James, & Jason (and anyone else whose names begin with "ja"). String nameQuery = Uri.encode("ja"); // Build the URI to look up work profile contacts whose name matches. Query // the default work profile directory which is the locally stored contacts. Uri contentFilterUri = ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI .buildUpon() .appendPath(nameQuery) .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(ContactsContract.Directory.ENTERPRISE_DEFAULT)) .build(); // Query the content provider using the generated URI. Cursor cursor = getContentResolver().query( contentFilterUri, new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }, null, null, null); if (cursor == null) { return; } // Print any results found using the work profile contacts' display name. try { while (cursor.moveToNext()) { Log.i(TAG, "Work profile contact: " + cursor.getString(2)); } } finally { cursor.close(); }
Répertoires
De nombreuses organisations utilisent des
annuaires distants, comme Microsoft Exchange ou LDAP,
contenant les coordonnées de l'ensemble de l'organisation. Votre application peut vous aider
les utilisateurs communiquent et partagent avec leurs collègues de travail
. Notez que ces répertoires contiennent
généralement des milliers de contacts,
et votre application a également besoin d'une connexion réseau active pour effectuer des recherches. Vous pouvez utiliser
le fournisseur de contenu Directory
pour obtenir les répertoires utilisés par le
comptes d'utilisateurs et obtenir davantage d'informations sur un annuaire individuel.
Interrogez Directory.ENTERPRISE_CONTENT_URI
fournisseur de contenu pour obtenir les annuaires du profil personnel et du profil professionnel
profil renvoyé ensemble. La recherche dans les répertoires de profils professionnels est prise en charge dans
Android 7.0 (niveau d'API 24) ou version ultérieure Votre application a besoin que l'utilisateur donne
Autorisations READ_CONTACTS
pour travailler avec ses contacts
répertoires.
Android stocke les coordonnées dans différents types
annuaires distants, la classe Directory
comporte des méthodes que vous pouvez appeler pour en trouver d'autres.
à propos d'un répertoire:
isEnterpriseDirectoryId()
- Appelez cette méthode pour savoir si l'annuaire provient d'un compte de profil professionnel.
N'oubliez pas que le fournisseur de contenu
ENTERPRISE_CONTENT_URI
renvoie les coordonnées des annuaires de profils personnel et professionnel. isRemoteDirectoryId()
- Appelez cette méthode pour savoir si l'annuaire est distant. Annuaires distants Il peut s'agir de magasins de contacts professionnels ou des réseaux sociaux de l'utilisateur.
L'exemple suivant montre comment utiliser ces méthodes pour filtrer le profil professionnel répertoires:
Kotlin
// First, confirm the device user has given READ_CONTACTS permission. // This permission is still needed for directory listings ... // Query the content provider to get directories for BOTH the personal and // work profiles. val cursor = getContentResolver() .query( ContactsContract.Directory.ENTERPRISE_CONTENT_URI, arrayOf(ContactsContract.Directory._ID, ContactsContract.Directory.PACKAGE_NAME), null, null, null ) // Print the package name of the work profile's local or remote contact directories. cursor?.use { while (it.moveToNext()) { val directoryId = it.getLong(0) if (ContactsContract.Directory.isEnterpriseDirectoryId(directoryId)) { Log.i(TAG, "Directory: ${it.getString(1)}") } } }
Java
// First, confirm the device user has given READ_CONTACTS permission. // This permission is still needed for directory listings ... // Query the content provider to get directories for BOTH the personal and // work profiles. Cursor cursor = getContentResolver().query( ContactsContract.Directory.ENTERPRISE_CONTENT_URI, new String[]{ ContactsContract.Directory._ID, ContactsContract.Directory.PACKAGE_NAME }, null, null, null); if (cursor == null) { return; } // Print the package name of the work profile's local or remote contact directories. try { while (cursor.moveToNext()) { long directoryId = cursor.getLong(0); if (ContactsContract.Directory.isEnterpriseDirectoryId(directoryId)) { Log.i(TAG, "Directory: " + cursor.getString(1)); } } } finally { cursor.close(); }
L'exemple récupère l'ID et le nom de package du répertoire. Afficher un utilisateur
interface qui aide les utilisateurs à choisir une source d'annuaire de contacts, vous devrez peut-être
récupérer plus d'informations
sur le répertoire. Pour voir d'autres champs de métadonnées
peuvent être disponibles, consultez la documentation de référence de la classe Directory
.
Recherches de numéros de téléphone
Les applications peuvent interroger
PhoneLookup.CONTENT_FILTER_URI
pour
rechercher les coordonnées d'un numéro de téléphone ; Vous pouvez obtenir des
résultats de recherche de
le fournisseur de contacts des profils personnels et professionnels si vous remplacez cet URI par
PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
Cet URI de contenu de profil professionnel est disponible sur Android 5.0 (niveau d'API 21) ou
plus élevée.
L'exemple suivant montre une application qui interroge l'URI de contenu du profil professionnel pour configurer l'interface utilisateur pour un appel entrant:
Kotlin
fun onCreateIncomingConnection( connectionManagerPhoneAccount: PhoneAccountHandle, request: ConnectionRequest ): Connection { var request = request // Get the telephone number from the incoming request URI. val phoneNumber = this.extractTelephoneNumber(request.address) var displayName = "Unknown caller" var isCallerInWorkProfile = false // Look up contact details for the caller in the personal and work profiles. val lookupUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phoneNumber) ) val cursor = getContentResolver() .query( lookupUri, arrayOf( ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.CUSTOM_RINGTONE ), null, null, null ) // Use the first contact found and check if they're from the work profile. cursor?.use { if (it.moveToFirst() == true) { displayName = it.getString(1) isCallerInWorkProfile = ContactsContract.Contacts.isEnterpriseContactId(it.getLong(0)) } } // Return a configured connection object for the incoming call. val connection = MyAudioConnection() connection.setCallerDisplayName(displayName, TelecomManager.PRESENTATION_ALLOWED) // Our app's activity uses this value to decide whether to show a work badge. connection.setIsCallerInWorkProfile(isCallerInWorkProfile) // Configure the connection further ... return connection }
Java
public Connection onCreateIncomingConnection ( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) { // Get the telephone number from the incoming request URI. String phoneNumber = this.extractTelephoneNumber(request.getAddress()); String displayName = "Unknown caller"; boolean isCallerInWorkProfile = false; // Look up contact details for the caller in the personal and work profiles. Uri lookupUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phoneNumber)); Cursor cursor = getContentResolver().query( lookupUri, new String[]{ ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.CUSTOM_RINGTONE }, null, null, null); // Use the first contact found and check if they're from the work profile. if (cursor != null) { try { if (cursor.moveToFirst() == true) { displayName = cursor.getString(1); isCallerInWorkProfile = ContactsContract.Contacts.isEnterpriseContactId(cursor.getLong(0)); } } finally { cursor.close(); } } // Return a configured connection object for the incoming call. MyConnection connection = new MyConnection(); connection.setCallerDisplayName(displayName, TelecomManager.PRESENTATION_ALLOWED); // Our app's activity uses this value to decide whether to show a work badge. connection.setIsCallerInWorkProfile(isCallerInWorkProfile); // Configure the connection further ... return connection; }
Recherches d'adresses e-mail
Votre application peut obtenir les coordonnées personnelles ou professionnelles d'une adresse e-mail en interrogeant
Email.ENTERPRISE_CONTENT_LOOKUP_URI
L'interrogation de cette URL lance d'abord la recherche d'une correspondance exacte dans les contacts personnels. Si
le fournisseur ne correspond à aucun contact personnel, il recherche
vos contacts professionnels. Cet URI est disponible dans Android 6.0 (niveau d'API 23).
ou supérieur.
Pour rechercher les coordonnées d'une adresse e-mail, procédez comme suit:
Kotlin
// Build the URI to look up contacts from the personal and work profiles that // are an exact (case-insensitive) match for the email address. val emailAddress = "somebody@example.com" val contentFilterUri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Email.ENTERPRISE_CONTENT_LOOKUP_URI, Uri.encode(emailAddress) ) // Query the content provider to first try to match personal contacts and, // if none are found, then try to match the work contacts. val cursor = contentResolver.query( contentFilterUri, arrayOf( ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.Contacts.DISPLAY_NAME ), null, null, null ) ?: return // Print the name of the matching contact. If we want to work-badge contacts, // we can call ContactsContract.Contacts.isEnterpriseContactId() with the ID. cursor.use { while (it.moveToNext()) { Log.i(TAG, "Matching contact: ${it.getString(2)}") } }
Java
// Build the URI to look up contacts from the personal and work profiles that // are an exact (case-insensitive) match for the email address. String emailAddress = "somebody@example.com"; Uri contentFilterUri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Email.ENTERPRISE_CONTENT_LOOKUP_URI, Uri.encode(emailAddress)); // Query the content provider to first try to match personal contacts and, // if none are found, then try to match the work contacts. Cursor cursor = getContentResolver().query( contentFilterUri, new String[]{ ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.Contacts.DISPLAY_NAME }, null, null, null); if (cursor == null) { return; } // Print the name of the matching contact. If we want to work-badge contacts, // we can call ContactsContract.Contacts.isEnterpriseContactId() with the ID. try { while (cursor.moveToNext()) { Log.i(TAG, "Matching contact: " + cursor.getString(2)); } } finally { cursor.close(); }
Afficher un contact professionnel
Les applications exécutées dans le profil personnel peuvent afficher une fiche de contact dans le profil professionnel.
Appeler
ContactsContract.QuickContact.showQuickContact()
po
Android 5.0 ou version ultérieure pour lancer l'application Contacts dans le profil professionnel et afficher
la fiche du contact.
Pour générer un URI correct pour le profil professionnel, vous devez appeler
ContactsContract.Contacts.getLookupUri()
et transmettre une
l'ID de contact et la clé de recherche. L'exemple suivant montre comment obtenir l'URI
puis affichez la fiche:
Kotlin
// Query the content provider using the ENTERPRISE_CONTENT_FILTER_URI address. // We use the _ID and LOOKUP_KEY columns to generate a work-profile URI. val cursor = getContentResolver() .query( contentFilterUri, arrayOf(ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY), null, null ) // Show the contact details card in the work profile's Contacts app. The URI // must be created with getLookupUri(). cursor?.use { if (it.moveToFirst() == true) { val uri = ContactsContract.Contacts.getLookupUri(it.getLong(0), it.getString(1)) ContactsContract.QuickContact.showQuickContact( activity, Rect(20, 20, 100, 100), uri, ContactsContract.QuickContact.MODE_LARGE, null ) } }
Java
// Query the content provider using the ENTERPRISE_CONTENT_FILTER_URI address. // We use the _ID and LOOKUP_KEY columns to generate a work-profile URI. Cursor cursor = getContentResolver().query( contentFilterUri, new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, }, null, null, null); if (cursor == null) { return; } // Show the contact details card in the work profile's Contacts app. The URI // must be created with getLookupUri(). try { if (cursor.moveToFirst() == true) { Uri uri = ContactsContract.Contacts.getLookupUri( cursor.getLong(0), cursor.getString(1)); ContactsContract.QuickContact.showQuickContact( getActivity(), new Rect(20, 20, 100, 100), uri, ContactsContract.QuickContact.MODE_LARGE, null); } } finally { cursor.close(); }
Disponibilité
Le tableau suivant récapitule les versions d'Android compatibles avec le profil professionnel. coordonnées dans le profil personnel:
Version d'Android | Assistance |
---|---|
5.0 (niveau d'API 21) | Utilisez PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI pour rechercher les numéros de téléphone des contacts professionnels. |
6.0 (niveau d'API 23) | Recherchez les noms des contacts professionnels correspondant aux adresses e-mail en utilisant Email.ENTERPRISE_CONTENT_LOOKUP_URI . |
7.0 (niveau d'API 24) | Interrogez les noms des contacts professionnels dans les annuaires professionnels à l'aide de Contacts.ENTERPRISE_CONTENT_FILTER_URI .Répertoriez tous les annuaires des profils professionnel et personnel à l'aide de Directory.ENTERPRISE_CONTENT_URI . |
Développement et tests
Pour créer un profil professionnel, procédez comme suit:
- Installez notre application Test DPC.
- Ouvrez l'application Configurer l'outil Test DPC (et non l'icône de l'application Test DPC).
- Suivez les instructions à l'écran pour configurer un profil géré.
- Dans le profil professionnel, ouvrez l'application Contacts et ajoutez des exemples de contacts.
Pour simuler le blocage de l'accès aux contacts du profil professionnel par un administrateur informatique, procédez comme suit:
- Dans le profil professionnel, ouvrez l'application Test DPC.
- Recherchez le paramètre Désactiver la recherche de contacts dans tous les profils ou le paramètre Désactiver le paramètre d'affichage du numéro de l'appelant dans tous les profils
- Activez le paramètre.
Pour en savoir plus sur les tests de votre application avec des profils professionnels, consultez Tester votre application pour Compatibilité avec les profils professionnels.
Ressources supplémentaires
Pour en savoir plus sur les contacts ou le profil professionnel, consultez les ressources suivantes:
- D'autres bonnes pratiques professionnelles sont disponibles dans les profils professionnels. profils.
- Récupérer une liste de contacts présente les étapes nécessaires pour lister les contacts dans une application.
- Contacts Provider explique de la base de données de contacts.