Sélecteur de contacts : partage de contacts axé sur la confidentialité
Temps de lecture : 4 min
La confidentialité et le contrôle dont bénéficient les utilisateurs restent au cœur de l'expérience Android. Tout comme le sélecteur de photos a permis de partager des contenus multimédias de manière sécurisée et facile à implémenter, nous apportons désormais le même niveau de confidentialité, de simplicité et d'expérience utilisateur à la sélection de contacts.
Une nouvelle norme pour la confidentialité des contacts
Auparavant, les applications nécessitant l'accès aux contacts d'un utilisateur spécifique s'appuyaient sur l'autorisation générale READ_CONTACTS. Bien que fonctionnelle, cette approche accordait souvent aux applications plus de données que nécessaire. Le nouveau sélecteur de contacts Android, introduit dans Android 17, change cette dynamique en fournissant une interface standardisée, sécurisée et interrogeable pour la sélection des contacts.
Cette fonctionnalité permet aux utilisateurs de n'accorder aux applications l'accès qu'aux contacts spécifiques qu'ils choisissent, conformément à l'engagement d'Android en faveur de la transparence des données et de la réduction de l'empreinte des autorisations.
Fonctionnement
Les développeurs peuvent intégrer le sélecteur de contacts à l'aide de l'intent Intent.ACTION_PICK_CONTACTS. Cette API mise à jour offre plusieurs fonctionnalités puissantes :
- Demandes de données précises : les applications peuvent spécifier exactement les champs dont elles ont besoin, comme les numéros de téléphone ou les adresses e-mail, plutôt que de recevoir l'intégralité de la fiche de contact.
- Compatibilité avec la sélection multiple : le sélecteur est compatible avec la sélection d'un ou de plusieurs contacts, ce qui offre aux développeurs plus de flexibilité pour des fonctionnalités telles que les invitations de groupe.
- Limites de sélection : les développeurs peuvent définir des limites personnalisées sur le nombre de contacts qu'un utilisateur peut sélectionner à la fois.
- Accès temporaire : une fois sélectionné, le système renvoie un URI de session qui fournit un accès en lecture temporaire aux données demandées, garantissant que l'accès ne persiste pas plus longtemps que nécessaire.
- Accès à d'autres profils : lorsque vous utilisez ce nouvel intent, l'interface permet aux utilisateurs de sélectionner des contenus d'autres profils utilisateur, comme un profil professionnel, un profil cloné ou un espace privé.
- Performances optimisées : le sélecteur de contacts renvoie un seul URI qui permet d'interroger les résultats de manière collective, ce qui évite d'avoir à interroger séparément chaque URI de contact, comme l'exige
ACTION_PICK. Cette efficacité réduit encore les frais généraux du système en utilisant une seule transactionBinder.
Rétrocompatibilité et implémentation
Pour les appareils équipés d'Android 17 ou version ultérieure, le système met automatiquement à niveau les anciens intents ACTION_PICK qui spécifient des types de données de contact vers la nouvelle interface plus sécurisée. Toutefois, pour profiter pleinement des fonctionnalités avancées telles que la sélection multiple, nous encourageons les développeurs à mettre à jour leur code d'implémentation et à utiliser ContentResolver pour interroger l'URI de session renvoyé.
Intégrer le sélecteur de contactsPour intégrer le sélecteur de contacts, les développeurs utilisent l'intent ACTION_PICK_CONTACTS. Vous trouverez ci-dessous un exemple de code montrant comment lancer le sélecteur et demander des champs de données spécifiques, tels que l'adresse e-mail et le numéro de téléphone.
// State to hold the list of selected contacts var contacts by remember { mutableStateOf<List>(emptyList()) } // Launcher for the Contact Picker intent val pickContact = rememberLauncherForActivityResult(StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { val resultUri = it.data?.data ?: return@rememberLauncherForActivityResult // Process the result URI in a background thread coroutine.launch { contacts = processContactPickerResultUri(resultUri, context) } } } // Define the specific contact data fields you need val requestedFields = arrayListOf( Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, ) // Set up the intent for the Contact Picker val pickContactIntent = Intent(ACTION_PICK_CONTACTS).apply { putExtra(EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5) putStringArrayListExtra( EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS, requestedFields ) putExtra(EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS, false) } // Launch the picker pickContact.launch(pickContactIntent)
Une fois que l'utilisateur a effectué une sélection, l'application traite le résultat en interrogeant l'URI de session renvoyé pour extraire les coordonnées demandées.
// Data class representing a parsed Contact with selected details data class Contact(val id: String, val name: String, val email: String?, val phone: String?) // Helper function to query the content resolver with the URI returned by the Contact Picker. // Parses the cursor to extract contact details such as name, email, and phone number private suspend fun processContactPickerResultUri( sessionUri: Uri, context: Context ): List<Contact> = withContext(Dispatchers.IO) { // Define the columns we want to retrieve from the ContactPicker ContentProvider val projection = arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY, ContactsContract.Data.MIMETYPE, // Type of data (e.g., email or phone) ContactsContract.Data.DATA1, // The actual data (Phone number / Email string) ) val results = mutableListOf<Contact>() // Note: The Contact Picker Session Uri doesn't support custom selection & selectionArgs. context.contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor -> // Get the column indices for our requested projection val contactIdIdx = cursor.getColumnIndex(ContactsContract.Contacts._ID) val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE) val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY) val data1Idx = cursor.getColumnIndex(ContactsContract.Data.DATA1) while (cursor.moveToNext()) { val contactId = cursor.getString(contactIdIdx) val mimeType = cursor.getString(mimeTypeIdx) val name = cursor.getString(nameIdx) ?: "" val data1 = cursor.getString(data1Idx) ?: "" // Determine if the current row represents an email or a phone number val email = if (mimeType == Email.CONTENT_ITEM_TYPE) data1 else null val phone = if (mimeType == Phone.CONTENT_ITEM_TYPE) data1 else null // Add the parsed contact to our results list results.add(Contact(contactId, name, email, phone)) } } return@withContext results }
Consultez la documentation complète ici.
Bonnes pratiques pour les développeurs
Pour offrir une expérience utilisateur optimale et maintenir des normes de sécurité élevées, nous vous recommandons de suivre les conseils ci-dessous :
- Minimisation des données : ne demandez que les champs de données spécifiques (par exemple, l'adresse e-mail) dont votre application a besoin.
- Persistance immédiate : conservez immédiatement les données sélectionnées, car l'accès à l'URI de session est temporaire.
-
Actualités sur les produitsLe sélecteur de photos intégré : un moyen plus fluide de demander des photos et des vidéos de manière privée dans votre application.
Roxanna Aliabadi Walker, Yacine Rezgui • Temps de lecture : 8 min -
Actualités sur les produitsÀ mesure que le développement agentique s'accélère, l'ingénierie Android atteint une nouvelle frontière passionnante : passer de la complétion de code assistée à des agents qui s'exécutent de bout en bout sous votre direction. Vous disposez d'un choix et d'une flexibilité totaux concernant les modèles et les agents que vous utilisez.
Jason Buchel • Temps de lecture : 3 min -
Actualités sur les produitsAujourd'hui, nous avons expliqué comment nous faisions évoluer notre vision "plus qu'un magasin". De l'onglet "Vous", qui sert désormais d'espace personnel à plus de 250 millions d'utilisateurs actifs par mois, à notre plate-forme de jeux unifiée qui connecte plus de 700 millions de profils de joueurs, Google Play répond aux besoins des utilisateurs où qu'ils se trouvent.
Paul Feng • Temps de lecture : 3 min
Recevez chaque semaine les dernières informations sur le développement Android dans votre boîte de réception.