Le sélecteur de contacts Android est une interface standardisée et navigable qui permet aux utilisateurs de partager des contacts avec votre application. Disponible sur les appareils fonctionnant sous Android 17 ou version ultérieure, il offre une alternative respectueuse de la confidentialité à l'autorisation READ_CONTACTS étendue. Au lieu de demander l'accès à l'intégralité du carnet d'adresses de l'utilisateur, votre application spécifie les champs de données dont elle a besoin, tels que les numéros de téléphone ou les adresses e-mail, et l'utilisateur sélectionne les contacts spécifiques à partager. Cela accorde à votre application un accès en lecture uniquement aux données sélectionnées, ce qui garantit un contrôle précis tout en offrant une expérience utilisateur cohérente avec des fonctionnalités de recherche, de changement de profil et de sélection multiple intégrées, sans avoir à créer ni à gérer l'UI.
Intégrer le sélecteur de contacts
Pour intégrer le sélecteur de contacts, utilisez l'intent Intent.ACTION_PICK_CONTACTS.
Cette intention lance le sélecteur et renvoie les contacts sélectionnés à votre application.
Contrairement à l'ancien ACTION_PICK, le sélecteur de contacts vous permet de spécifier plusieurs champs de données requis par votre application en même temps. Pour ce faire, utilisez Intent.EXTRA_REQUESTED_DATA_FIELDS en transmettant un ArrayList<String> de types MIME définis dans ContactsContract.CommonDataKinds.
Voici quelques types MIME courants :
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
Lancer le sélecteur
Utilisez registerForActivityResult avec le contrat StartActivityForResult pour lancer le sélecteur. Vous pouvez configurer l'intention pour autoriser une ou plusieurs sélections.
Sélectionner un seul contact
Dans cet exemple, l'application ne demande que des numéros de téléphone. Le sélecteur filtrera la liste pour n'afficher que les contacts disposant d'un numéro de téléphone et permettra à l'utilisateur de sélectionner un numéro spécifique.
Kotlin
// Define the specific data fields you need
val requestedFields = arrayListOf(
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
)
// Set up the intent
val pickContactIntent = Intent(Intent.ACTION_PICK_CONTACTS).apply {
type = ContactsContract.Contacts.CONTENT_TYPE
putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS, requestedFields)
}
// Launch the picker
pickContactLauncher.launch(pickContactIntent)
Java
// Define the specific data fields you need
ArrayList<String> requestedFields = new ArrayList<>();
requestedFields.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
// Set up the intent
Intent pickContactIntent = new Intent(Intent.ACTION_PICK_CONTACTS);
pickContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
pickContactIntent.putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS,
requestedFields);
// Launch the picker
pickContactLauncher.launch(pickContactIntent);
Sélectionner plusieurs contacts
Pour activer la sélection multiple, ajoutez l'extra Intent.EXTRA_ALLOW_MULTIPLE. Vous pouvez éventuellement limiter le nombre d'éléments qu'un utilisateur peut sélectionner.
Kotlin
val requestedFields = arrayListOf(
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
)
val pickMultipleIntent = Intent(Intent.ACTION_PICK_CONTACTS).apply {
type = ContactsContract.Contacts.CONTENT_TYPE
putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS, requestedFields)
// Enable multi-select
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
// Optional: Set a custom limit (max 50 recommended)
putExtra(Intent.EXTRA_SELECTION_LIMIT, 10)
}
pickMultipleLauncher.launch(pickMultipleIntent)
Gérer les résultats
Lorsque l'utilisateur termine la sélection, le système renvoie un RESULT_OK et un URI de session. Cet URI accorde un accès en lecture temporaire aux données sélectionnées.
Vous pouvez interroger cet URI à l'aide d'un ContentResolver standard. Le Cursor obtenu contient les champs de données demandés et suit le schéma de ContactsContract.Data.
Kotlin
private val pickContactLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// The result data contains the Session URI
val sessionUri = result.data?.data
sessionUri?.let { uri ->
processSelectedContacts(uri)
}
} else {
// User cancelled the picker
}
}
private fun processSelectedContacts(sessionUri: Uri) {
// Define the projection (columns) you want to retrieve
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.DATA1 // Generic data column (Phone number, Email, etc.)
)
contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor ->
val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
val dataIdx = cursor.getColumnIndex(ContactsContract.Data.DATA1)
val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)
while (cursor.moveToNext()) {
val mimeType = cursor.getString(mimeTypeIdx)
val dataValue = cursor.getString(dataIdx)
val name = cursor.getString(nameIdx)
when (mimeType) {
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> {
Log.d("ContactPicker", "Picked Phone: $dataValue for $name")
}
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE -> {
Log.d("ContactPicker", "Picked Email: $dataValue for $name")
}
}
}
}
}
Rétrocompatibilité
Pour les applications ciblant Android 17 ou version ultérieure, le système met automatiquement à niveau l'intention Intent.ACTION_PICK existante pour utiliser la nouvelle interface du sélecteur de contacts.
Si votre application utilise déjà ACTION_PICK, vous n'avez pas besoin de modifier votre code pour recevoir la nouvelle UI. Toutefois, pour profiter des nouvelles fonctionnalités, comme recevoir un seul Uri pour interroger les données de contact, basculer entre les profils personnel et professionnel, ou effectuer plusieurs demandes de champs de données, vous devez mettre à jour votre implémentation pour utiliser Intent.ACTION_PICK_CONTACTS ou les nouveaux extras d'intent.
Tester sur d'anciens SDK
Vous pouvez tester le nouveau comportement du sélecteur sur les appareils exécutant Android 17 ou version ultérieure, même si votre application cible une version du SDK inférieure, en ajoutant l'extra booléen EXTRA_USE_SYSTEM_CONTACTS_PICKER à votre intent ACTION_PICK.
Bonnes pratiques
- Ne demandez que ce dont vous avez besoin : si votre application n'a besoin que d'envoyer un SMS, demandez
Phone.CONTENT_ITEM_TYPE. Le sélecteur filtrera automatiquement les contacts qui n'ont pas de numéro de téléphone, ce qui permettra à l'utilisateur de bénéficier d'une interface utilisateur plus claire. - Conserver les données immédiatement : l'URI de session accorde une autorisation de lecture temporaire. Si vous devez accéder à ces coordonnées ultérieurement (après l'arrêt du processus de votre application), votre application doit conserver les données de contact.
- Ne vous fiez pas aux données de compte : pour protéger la confidentialité des utilisateurs et éviter l'empreinte numérique, les métadonnées spécifiques au compte sont supprimées des résultats.