Actualités sur les produits

Une méthode plus fiable pour ajouter et modifier des contacts sur Android

Temps de lecture : 6 min
Voir le profil de Roxanna Aliabadi Walker
Roxanna Aliabadi Walker Responsable produit, Android

Nouveautés

Les applications qui ciblent la prochaine version d'Android ne pourront plus écrire directement dans les contacts avec l'autorisation WRITE_CONTACTS. À la place, vous pouvez utiliser les intents de contact standards (ACTION_INSERT, ACTION_EDIT et ACTION_INSERT_OR_EDIT). Pour obtenir une implémentation de référence complète, consultez le guide du développeur sur la modification des contacts à l'aide d'intents. 

Sur les appareils exécutant la prochaine version d'Android, ces trois intents de contact se comporteront de manière cohérente et ne nécessiteront aucune autorisation. Si votre application cible la prochaine version d'Android ou une version ultérieure et tente d'écrire directement dans les contacts, ces écritures seront refusées et entraîneront une SecurityException ou un refus d'autorisation. Pour le petit nombre d'applications qui nécessitent un accès étendu pour créer et modifier des contacts, une nouvelle autorisation d'accès spécial aux applications, MANAGE_CONTACTS, sera disponible dans Android 17 QPR2 (4e trimestre 2026). Google Play publie aujourd'hui des consignes mises à jour concernant l'accès aux contacts, y compris MANAGE_CONTACTS.

Pourquoi nous faisons cela

Actuellement, si votre application doit enregistrer ne serait-ce qu'un seul contact, vous pouvez demander l'autorisation WRITE_CONTACTS. Cependant, cette autorisation accorde un accès étendu, permettant à une application d'apporter des modifications généralisées aux contacts sur l'appareil en arrière-plan, même sans interaction de l'utilisateur. La plupart des applications n'ont pas besoin d'une autorisation aussi étendue.

Bien qu'il existe des alternatives, vous nous avez indiqué qu'elles devaient être plus standardisées dans l'écosystème. Auparavant, les intents de contact se comportaient différemment d'un appareil à l'autre. Certains éditeurs ont supprimé les données que vous avez transmises, comme une photo de contact. Sur certains appareils, le bouton Retour enregistrait le contact sans que l'utilisateur ne le veuille, ou l'option "Créer un contact" était difficile à trouver. Demander l'autorisation était donc le choix le plus rationnel. Nous corrigeons tous ces problèmes dans la prochaine version d'Android et exigeons que les appareils qui l'exécutent respectent les mêmes normes.

Que faire à la place ?

Ajouter ou modifier un contact : utiliser les intents de contact

Lorsque vous utilisez ces intents (ACTION_INSERT, ACTION_EDIT et ACTION_INSERT_OR_EDIT), le système se charge du travail difficile en présentant une expérience d'éditeur de contacts claire et standardisée. Il ouvre un formulaire rapide de demi-feuille pour les nouvelles entrées, ou permet à l'utilisateur de rechercher et d'ajouter facilement des informations à un contact existant. Les utilisateurs peuvent facilement développer cette boîte de dialogue en un éditeur pleine page pour ajouter des détails, sans que votre application ait besoin d'autorisations d'écriture directes. Voici les maquettes UX provisoires : 

Figure01_01_Quick_Insert_Half_Sheet_Prefilled.png
Capture d'écran 2 – Titre : Maquette d'une feuille complète pour créer un contact : capture d'écran d'une interface utilisateur Android provisoire montrant un éditeur de contact en plein écran avec un sélecteur d'avatar, un nom, un numéro de téléphone et des champs d'adresse e-mail. La conception est étiquetée "UX not Final" (UX non finalisée).

Figure 1 : Créer un contact  *UX non définitive*

Figure02_01_Add_To_Existing_0_Search_State_Half_Sheet.png
Capture d'écran 2 – Titre : Maquette d'une feuille complète "Ajouter des informations à un contact existant" : capture d'écran d'une interface utilisateur Android provisoire montrant un éditeur de contact en plein écran avec un sélecteur d'avatar, un nom, un numéro de téléphone et des champs d'adresse e-mail. La conception pleine page comporte des chips de divulgation progressive pour les champs secondaires. La conception est étiquetée "UX not Final" (Expérience utilisateur non définitive).

Figure 2 : Ajouter des informations à un contact existant *UX non finalisée*


Remarque : Les fabricants d'appareils peuvent modifier l'expérience utilisateur pour l'adapter au style de leur OS, mais le comportement reste le même.


Vous pouvez simplifier davantage le processus de création en transmettant des charges utiles de données facultatives, appelées "extras", en plus de votre intent :

  • EXTRA_ACCOUNT suggère le compte dans lequel enregistrer le contact, ce qui est utile si votre application synchronise les contacts. Cet extra existait déjà, mais sa prise en charge variait selon l'appareil. À partir de la prochaine version d'Android, la compatibilité sera standardisée sur tous les appareils.
  • EXTRA_PHOTO_URI transmet une photo pour préremplir l'image du contact. L'éditeur gère l'autorisation de lecture de l'URI pour vous. Cette fonctionnalité est nouvelle dans la prochaine version d'Android et sera compatible avec l'ensemble de l'écosystème.

Avant : écriture directe avec WRITE_CONTACTS (génère une exception SecurityException ou un refus d'autorisation une fois que votre application cible la prochaine version d'Android).

 

// Requires android.permission.WRITE_CONTACTS
fun saveContactDirectly(context: Context, name: String, phone: String, account: Account) {
    val ops = arrayListOf(
        ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .build()
    )
    context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
}

 

 

Après : ouverture de l'éditeur de contacts (aucune autorisation requise)

 

fun saveContactWithEditor(
    context: Context,
    name: String,
    phone: String,
    account: Account,
    photoUri: Uri
) {
    val intent = Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI).apply {
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
        // Suggest which account the contact is saved to
        putExtra(ContactsContract.Intents.Insert.EXTRA_ACCOUNT, account)
        // New in the upcoming Android release: pre-fill the contact photo
        putExtra(ContactsContract.Intents.Insert.EXTRA_PHOTO_URI, photoUri)
        clipData = ClipData.newRawUri("", photoUri)
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }
    context.startActivity(intent)
}

 

Avant : modifier directement un contact existant

 

// Requires android.permission.WRITE_CONTACTS
fun addPhoneDirectly(context: Context, rawContactId: Long, phone: String) {
    val values = ContentValues().apply {
        put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
        put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
    }
    context.contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)
}

Après : l'utilisateur peut choisir un contact à modifier ou en créer un

fun addPhoneWithEditor(context: Context, phone: String) {
    val intent = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

Si vous savez déjà quel contact mettre à jour, utilisez ACTION_EDIT avec l'URI de ce contact :

fun editKnownContact(context: Context, contactUri: Uri, phone: String) {
    val intent = Intent(Intent.ACTION_EDIT, contactUri).apply {
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

 

Sélectionner un contact : utiliser le sélecteur de contacts

Si vous n'avez besoin de lire que les contacts choisis par l'utilisateur, utilisez le sélecteur de contacts, disponible depuis Android 17. Elle ne nécessite aucune autorisation.

Applications d'appels et de chat : utiliser l'annuaire

Certaines applications ajoutent des actions "Appeler avec…" ou "Envoyer un message avec…" aux contacts pour que les utilisateurs puissent passer un appel ou discuter depuis l'application Téléphone ou l'application Contacts. Si votre application procède ainsi aujourd'hui en écrivant des entrées supplémentaires dans les contacts de l'utilisateur, passez à l'annuaire des contacts, qui sera disponible dans Android QPR2 (4e trimestre 2026). Il s'agit d'un nouveau répertoire système dans lequel votre application publie la façon dont les utilisateurs peuvent se contacter dans votre application, sans modifier leurs contacts.

Exemples de migration d'applications

Pour voir comment ces alternatives fonctionnent en pratique, voici quelques exemples d'approches de l'accès aux contacts pour différents types d'applications :

Exemple de type d'application (non exclusif).Processus de migration recommandé
Applications de réseaux sociaux, de paiement P2P et de covoiturageSi votre application permet aux utilisateurs de trouver des amis, de partager une addition ou de partager l'état d'un trajet, vous n'avez pas besoin d'autorisations d'accès aux contacts. Utilisez le sélecteur de contacts pour sélectionner un contact une seule fois, puis lancez ACTION_INSERT avec EXTRA_PHOTO_URI lorsqu'un utilisateur appuie sur "Enregistrer dans les contacts" sur un profil.
Scanners de cartes de visite et applications de réseautage pour les événementsSi votre application scanne un badge ou un QR code et enregistre un nouveau contact, ou ajoute un numéro de téléphone professionnel à l'entrée d'un collègue existant, utilisez ACTION_INSERT ou ACTION_INSERT_OR_EDIT. L'éditeur standardisé de demi-feuille préremplit les champs analysés (nom, entreprise, téléphone, adresse e-mail et photo) afin que l'utilisateur puisse vérifier et enregistrer les informations d'un simple geste, sans accorder d'autorisations en arrière-plan.
Applications d'appels et de messagerie VoIPPlutôt que de demander à WRITE_CONTACTS d'injecter des lignes personnalisées "Appeler avec…" ou "Envoyer un message avec…" dans le carnet d'adresses de l'utilisateur, publiez les métadonnées d'accessibilité via l'annuaire de contacts et utilisez ACTION_INSERT lorsque les utilisateurs ajoutent un contact à partir d'un fil de discussion.
Applications de CRM d'entreprise et de synchronisation cloudSi votre application effectue une synchronisation continue et bidirectionnelle des contacts en arrière-plan avec un compte cloud ou d'entreprise, et qu'il n'est pas possible d'inviter l'utilisateur à l'aide d'une UI d'intent pour chaque enregistrement, votre application peut déclarer MANAGE_CONTACTS .

Modifications à vérifier

  • Les types de données personnalisés ne sont pas acceptés dans l'éditeur. Si vous transmettez des lignes Insert.DATA avec des types MIME autres que les types ContactsContract.CommonDataKinds standards, ces types MIME seront ignorés par l'éditeur sans qu'un message d'erreur ne s'affiche.
  • SHOW_OR_CREATE_CONTACT n'est pas géré par l'éditeur du système. Les applications Contacts fournies avec l'appareil peuvent toujours le gérer. Pour un comportement cohérent sur tous les appareils, utilisez ACTION_INSERT_OR_EDIT.
  • Les écritures échouent par défaut. Une fois que vous ciblez la prochaine version d'Android, toute écriture directe sans MANAGE_CONTACTS entraîne une SecurityException or permission denial. Testez-le.

Ai-je besoin de MANAGE_CONTACTS ?

Probablement pas. Si votre application enregistre ou modifie des contacts à la demande d'un utilisateur, les intents ci-dessus vous couvrent, sans autorisation ni déclaration dans la Play Console.

MANAGE_CONTACTS est destiné aux applications dont l'objectif principal est de gérer les contacts, lorsque les intents ne suffisent pas. Exemple :

Votre application…Besoin d'MANAGE_CONTACTS ?
Enregistre un contact à partir d'un chat, d'une carte de visite ou d'une commande.Non,utiliser ACTION_INSERT
Ajoute un numéro ou une adresse e-mail à un contact existant.Non,utilisez ACTION_INSERT_OR_EDIT ou ACTION_EDIT.
Permet aux utilisateurs de sélectionner des contacts à inviter, avec lesquels partager des contenus ou à payer.Non,utiliser le sélecteur de contacts
Ajoute des actions d'appel ou de message aux contacts.Non,utiliser l'annuaire des personnes
Il dispose de son propre écran de modification des contacts.Non,une interface personnalisée seule ne suffit pas.
Il s'agit d'une application dédiée de gestion des contacts ou de remplacement du clavier téléphonique.Probablement oui
Il s'agit d'une application d'affichage du numéro de l'appelant et de protection antispam qui met à jour de manière groupée les entrées du carnet d'adresses.Probablement oui
Synchronise les contacts avec un compte d'entreprise ou cloud en arrière-plan.Probablement oui
Effectue une sauvegarde/restauration groupée des contacts ou un transfert de téléphone à téléphone.Probablement oui
Définit des sonneries personnalisées pour des contacts spécifiques.Probablement oui

Fonctionnement :

  • MANAGE_CONTACTS est une autorisation d'accès spéciale pour les applications. Il ne s'agit pas d'une boîte de dialogue d'exécution. Les utilisateurs l'activent sous Paramètres > Accès spéciaux des applis > Gérer les contacts.
// Opens Settings > Apps > Special app access > Manage contacts
val intent = Intent(Settings.ACTION_MANAGE_CONTACTS, Uri.fromParts("package", packageName, null))
context.startActivity(intent)
  • Il couvre la lecture, l'ajout, la modification et la suppression de contacts, de comptes et de données de l'annuaire de contacts. Vous n'avez pas besoin de demander également READ_CONTACTS.
  • Pour publier sur Google Play avec MANAGE_CONTACTS, vous devez envoyer une déclaration dans la Play Console expliquant pourquoi les intents ne suffisent pas pour la fonctionnalité de base de votre application.

Étapes de migration

  • Trouvez vos contacts. Recherchez WRITE_CONTACTS, ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data.CONTENT_URI et applyBatch(ContactsContract.AUTHORITY, …) dans votre code.
  • Remplacez chaque écriture pilotée par l'utilisateur par un intent : ACTION_INSERT pour les nouveaux contacts, et ACTION_EDIT ou ACTION_INSERT_OR_EDIT pour les mises à jour.
  • Utilisez uniquement des types de données standards dans Insert.DATA. Déplacez les actions d'appel ou de message vers l'annuaire.
  • Déterminez si vous avez vraiment besoin de MANAGE_CONTACTS à l'aide du tableau ci-dessus. Si c'est le cas, planifiez votre déclaration dans la Play Console.
  • Supprimez WRITE_CONTACTS de votre fichier manifeste une fois qu'aucun chemin de code n'en a besoin.

Vos trajets

QuandConséquences
21 octobre 2026Google Play annonce la règle MANAGE_CONTACTS
2026 (Android 17 Quarterly Platform Release 2)L'autorisation MANAGE_CONTACTS devient disponible
2027 (prochaine version d'Android)WRITE_CONTACTS n'accorde plus d'accès en écriture aux applications ciblant la prochaine version d'Android. Les intents de contact sont standardisés sur tous les appareils
2027, pas avant la prochaine version d'AndroidLa Play Console demande aux applications qui utilisent MANAGE_CONTACTS d'envoyer une déclaration
2027, pas avant la prochaine version d'AndroidRespect du règlement Play requis

Questions fréquentes

  • Est-ce que cela concerne toutes les applications ?
    • L'abandon de WRITE_CONTACTS ne s'applique qu'aux applications qui ciblent la prochaine version d'Android et les versions ultérieures. Les applications ciblant des versions plus anciennes conservent leur comportement actuel. Toutefois, le nouvel éditeur de contacts standardisé sera disponible pour toutes les applications exécutées sur le nouvel OS, quel que soit leur SDK cible.
  • Mon application peut-elle supprimer des contacts avec un intent ?
    • Non, il n'existe pas d'intent pour supprimer des contacts. Les utilisateurs suppriment des contacts dans leur application Contacts. Les applications disposant de l'autorisation MANAGE_CONTACTS peuvent supprimer des contacts directement.
  • Je dispose déjà de mon propre écran de modification des contacts. Puis-je la garder ?
    • Uniquement si votre application est éligible à MANAGE_CONTACTS. Le fait de vouloir conserver une conception personnalisée n'est pas une raison suffisante en soi.
  • MANAGE_CONTACTS remplace-t-il READ_CONTACTS ?
    • MANAGE_CONTACTS inclut l'accès en lecture. Vous n'avez donc pas besoin de demander les deux, mais de nombreuses applications sont éligibles à READ_CONTACTS sans avoir besoin de modifier les contacts. Ces applications peuvent continuer à demander l'autorisation READ_CONTACTS.
  • Qu'en est-il de mes utilisateurs sur d'anciennes versions d'Android ?
    • Les intents de contact fonctionnent également sur les anciennes versions, gérées par l'application Contacts de l'appareil. La plupart des applications fonctionnent correctement sur tous les appareils utilisant ces intents. Si votre application est concernée par un problème de cohérence spécifique qui n'est résolu que dans les dernières versions, vous pouvez conserver l'autorisation WRITE_CONTACTS dans votre fichier manifeste, limitée à un maxSdkVersion approprié.
Continuer la lecture