Novità sui prodotti

Un modo più affidabile per aggiungere e modificare i contatti su Android

Tempo di lettura: 6 min
Visualizza il profilo di Roxanna Aliabadi Walker
Roxanna Aliabadi Walker Product Manager, Android

Che cosa cambia

Le app che hanno come target la prossima release di Android non potranno più scrivere direttamente nei contatti con l'autorizzazione WRITE_CONTACTS. Puoi invece utilizzare gli intent di contatto standard (ACTION_INSERT, ACTION_EDIT e ACTION_INSERT_OR_EDIT). Per un'implementazione di riferimento completa, consulta la guida per gli sviluppatori su come modificare i contatti utilizzando gli intent. 

Sui dispositivi con la prossima release di Android, questi tre intent di contatto si comporteranno in modo coerente e non richiederanno alcuna autorizzazione. Se la tua app ha come target la prossima release di Android o versioni successive e tenta di scrivere direttamente nei contatti, queste scritture verranno rifiutate e genereranno un errore SecurityException o un rifiuto dell'autorizzazione. Per il piccolo insieme di app che richiedono un accesso ampio per creare e modificare i contatti, in Android 17 QPR2 (4° trimestre del 2026) sarà disponibile una nuova autorizzazione di accesso speciale alle app, MANAGE_CONTACTS. Oggi Google Play pubblica le linee guida aggiornate per l'accesso ai contatti, tra cui MANAGE_CONTACTS.

Perché lo facciamo

Al momento, se la tua app deve salvare anche un solo contatto, potresti richiedere WRITE_CONTACTS. Tuttavia, questa autorizzazione concede un accesso ampio, consentendo a un'app di apportare modifiche estese ai contatti su tutto il dispositivo in background, anche senza l'interazione dell'utente. La maggior parte delle app non ha bisogno di un'autorizzazione così ampia.

Sebbene esistano delle alternative, ci avete riferito che devono essere più standardizzate nell'ecosistema. In precedenza, gli intent di contatto si comportavano in modo diverso da un dispositivo all'altro. Alcuni editor hanno eliminato i dati che hai trasmesso, ad esempio una foto del contatto. Su alcuni dispositivi, il pulsante Indietro salvava il contatto senza che l'utente lo volesse o l'opzione "Crea nuovo contatto" era difficile da trovare. Quindi chiedere l'autorizzazione era la scelta razionale. Stiamo risolvendo tutti questi problemi nella prossima versione di Android e richiediamo che i dispositivi che la eseguono seguano gli stessi standard.

Cosa utilizzare in alternativa

Aggiungi o modifica un contatto: utilizza gli intent dei contatti

Quando utilizzi questi intent (ACTION_INSERT, ACTION_EDIT e ACTION_INSERT_OR_EDIT), il sistema si occupa del lavoro più complesso presentando un'esperienza di modifica dei contatti pulita e standardizzata. Si apre un modulo rapido a metà schermo per le nuove voci oppure l'utente può cercare e aggiungere facilmente informazioni a un contatto esistente. Gli utenti possono espandere facilmente questa finestra in un editor a pagina intera per compilare ulteriori dettagli, il tutto senza che la tua app abbia mai bisogno di autorizzazioni in scrittura dirette. Di seguito sono riportati i mockup UX provvisori: 

Figure01_01_Quick_Insert_Half_Sheet_Prefilled.png
Screenshot 2 - Titolo: Mockup a schermo intero di Crea un nuovo contatto: screenshot di un'interfaccia utente Android provvisoria che mostra un editor di contatti a schermo intero con un selettore di avatar, nome, telefono e campi email. Il design è etichettato come "UX non definitiva".

Figura 1: Crea un nuovo contatto  *UX non finale*

Figure02_01_Add_To_Existing_0_Search_State_Half_Sheet.png
Screenshot 2 - Titolo: Mockup a schermo intero di "Aggiungi informazioni a un contatto esistente": screenshot di un'interfaccia utente Android provvisoria che mostra un editor di contatti a schermo intero con un selettore di avatar, campi per nome, telefono ed email. Il design a pagina intera presenta chip di divulgazione progressiva per i campi secondari. Il design è etichettato come "UX non definitiva".

Figura 2: aggiungi informazioni a un contatto esistente *UX non finale*


Nota:i diversi produttori di dispositivi potrebbero modificare l'esperienza utente in base allo stile del proprio sistema operativo, ma il comportamento rimarrà invariato.


Puoi semplificare ulteriormente il processo di creazione passando payload di dati facoltativi, noti come Extra, insieme all'intent:

  • EXTRA_ACCOUNT suggerisce l'account in cui salvare il contatto, il che è utile se la tua app sincronizza i contatti. Questo extra esisteva già, ma il supporto variava in base al dispositivo. A partire dalla prossima release di Android, il supporto sarà standardizzato su tutti i dispositivi.
  • EXTRA_PHOTO_URI passa una foto per precompilare l'immagine del contatto. L'editor gestisce l'autorizzazione in lettura dell'URI per te. Si tratta di una novità della prossima release di Android e sarà supportata in tutto l'ecosistema.

Prima: scrittura diretta con WRITE_CONTACTS (genera un'eccezione SecurityException o un rifiuto dell'autorizzazione quando l'app ha come target la prossima release di 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)
}

 

 

Dopo: apertura dell'editor dei contatti (nessuna autorizzazione necessaria).

 

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)
}

 

Prima: aggiornamento diretto di un contatto esistente

 

// 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)
}

Dopo: l'utente può scegliere un contatto da aggiornare o crearne uno nuovo

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)
}

Se sai già quale contatto aggiornare, utilizza ACTION_EDIT con l'URI del contatto:

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)
}

 

Scegli un contatto: utilizza il Selettore di contatti

Se devi solo leggere i contatti scelti dall'utente, utilizza il Selettore di contatti, disponibile da Android 17. Non richiede autorizzazioni.

App di messaggistica e di chiamata: utilizza la directory delle persone

Alcune app aggiungono azioni "Chiama con…" o "Invia messaggio con…" ai contatti in modo che le persone possano avviare una chiamata o una chat dall'app Telefono o dall'app Contatti. Se la tua app lo fa oggi scrivendo voci aggiuntive nei contatti dell'utente, passa alla directory Persone, in arrivo in Android QPR2 (Q4 2026). Si tratta di una nuova directory di sistema in cui la tua app pubblica i modi in cui le persone possono contattarsi nella tua app, senza modificare i contatti dell'utente.

Esempi di come le app possono eseguire la migrazione

Per vedere come funzionano queste alternative nella pratica, ecco alcuni esempi di come diversi tipi di app possono approcciare l'accesso ai contatti:

Esempio di tipo di app (non esclusivo).Percorso di migrazione consigliato
App social, di pagamento P2P e di ride sharingSe la tua app consente agli utenti di trovare amici, dividere un conto o condividere lo stato di un viaggio, non hai bisogno delle autorizzazioni Contatti. Utilizza il Selettore di contatti per la selezione una tantum dei contatti e avvia ACTION_INSERT con EXTRA_PHOTO_URI quando un utente tocca "Salva nei contatti" su un profilo.
Scanner per biglietti da visita e app di networking per eventiSe la tua app scansiona un badge o un codice QR e salva un nuovo contatto o aggiunge un numero di telefono di lavoro alla voce di un collega esistente, utilizza ACTION_INSERT o ACTION_INSERT_OR_EDIT. L'editor standardizzato a metà schermo precompila i campi analizzati (nome, azienda, telefono, email e foto) in modo che l'utente possa verificare e salvare con un solo tocco senza concedere autorizzazioni in background.
App di messaggistica e chiamate VoIPAnziché richiedere a WRITE_CONTACTS di inserire righe personalizzate "Chiama con…" o "Invia messaggio con…" nella rubrica dell'utente, pubblica i metadati di raggiungibilità tramite la directory Persone e utilizza ACTION_INSERT quando gli utenti aggiungono un nuovo contatto da un thread di chat.
App CRM aziendali e di sincronizzazione cloudSe la tua app esegue la sincronizzazione continua e bidirezionale dei contatti in background con un account cloud o aziendale, in cui non è possibile chiedere all'utente un'UI di intent per ogni record, la tua app è idonea a dichiarare MANAGE_CONTACTS 

Modifiche da controllare

  • I tipi di dati personalizzati non sono supportati nell'editor. Se passi righe Insert.DATA con tipi MIME diversi dai tipi ContactsContract.CommonDataKinds standard, questi tipi MIME verranno ignorati automaticamente dall'editor.
  • SHOW_OR_CREATE_CONTACT non è gestito dall'editor di sistema. Le app Contatti preinstallate sul dispositivo possono comunque gestirlo. Per un comportamento coerente su tutti i dispositivi, utilizza ACTION_INSERT_OR_EDIT.
  • Le scritture non vanno a buon fine per impostazione predefinita. Una volta scelto come target la prossima release di Android, qualsiasi scrittura diretta senza MANAGE_CONTACTS genera un SecurityException or permission denial. Esegui un test.

Ho bisogno di MANAGE_CONTACTS?

Probabilmente no. Se la tua app salva o modifica i contatti perché un utente lo ha richiesto, gli intent riportati sopra ti coprono, senza autorizzazione e senza dichiarazione di Play Console.

MANAGE_CONTACTS è per le app il cui scopo principale è la gestione dei contatti, dove gli intent non sono sufficienti. Ad esempio:

La tua app…Hai bisogno di MANAGE_CONTACTS?
Salva un contatto da una chat, un biglietto da visita o un ordine.No, usa ACTION_INSERT
Aggiunge un numero o un indirizzo email a un contatto esistente.No,utilizza ACTION_INSERT_OR_EDIT o ACTION_EDIT
Consente agli utenti di scegliere i contatti da invitare, con cui condividere o a cui inviare pagamenti.No,utilizza il Selettore di contatti
Aggiunge azioni di chiamata o messaggio ai contatti.No, utilizza la directory degli utenti
Ha una propria schermata di modifica dei contatti con il proprio brand.No,un'interfaccia personalizzata da sola non è idonea
È un'app dedicata alla gestione dei contatti o alla sostituzione del tastierino.Probabilmente sì
È un'app di protezione antispam e ID chiamante che aggiorna in blocco le voci della rubrica.Probabilmente sì
Sincronizza i contatti con un account aziendale o cloud in background.Probabilmente sì
Esegue il backup/ripristino collettivo dei contatti o il trasferimento da smartphone a smartphone.Probabilmente sì
Imposta suonerie personalizzate per i singoli contatti.Probabilmente sì

Come funziona:

  • MANAGE_CONTACTS è un'autorizzazione di accesso speciale alle app. Non è una finestra di dialogo di runtime. Gli utenti la attivano in Impostazioni > Accesso speciale per le app > Gestisci contatti.
// Opens Settings > Apps > Special app access > Manage contacts
val intent = Intent(Settings.ACTION_MANAGE_CONTACTS, Uri.fromParts("package", packageName, null))
context.startActivity(intent)
  • Riguarda la lettura, l'aggiunta, la modifica e l'eliminazione di contatti, account e dati della directory degli utenti. Non è necessario richiedere anche READ_CONTACTS.
  • Per pubblicare su Google Play con MANAGE_CONTACTS, devi inviare una dichiarazione in Play Console in cui spieghi perché gli intent non sono sufficienti per la funzionalità di base della tua app.

Passaggi per la migrazione

  • Trova le scritture dei tuoi contatti. Cerca nel codice WRITE_CONTACTS, ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data.CONTENT_URI e applyBatch(ContactsContract.AUTHORITY, …).
  • Sostituisci ogni scrittura basata sull'utente con un intent: ACTION_INSERT per i nuovi contatti e ACTION_EDIT o ACTION_INSERT_OR_EDIT per gli aggiornamenti.
  • Utilizza solo tipi di dati standard in Insert.DATA. Spostare le azioni di chiamata o messaggio nella directory delle persone.
  • Decidi se hai davvero bisogno di MANAGE_CONTACTS utilizzando la tabella riportata sopra. In questo caso, pianifica la dichiarazione di Play Console.
  • Rimuovi WRITE_CONTACTS dal file manifest quando non è più necessario per nessun percorso del codice.

Spostamenti

QuandoChe cosa succede
21 ottobre 2026Google Play annuncia le norme relative a MANAGE_CONTACTS
2026 (Android 17 Quarterly Platform Release 2)MANAGE_CONTACTS autorizzazione diventa disponibile
2027 (prossima release di Android)WRITE_CONTACTS non concede più l'accesso in scrittura alle app che hanno come target la prossima release di Android. Gli intent di contatto sono standardizzati su tutti i dispositivi
2027, non prima della prossima release di AndroidPlay Console chiede alle app che utilizzano MANAGE_CONTACTS di inviare una dichiarazione
2027, non prima della prossima release di AndroidConformità alle norme di Google Play obbligatoria

Domande frequenti

  • Questo problema riguarda tutte le app?
    • La modifica relativa al ritiro di WRITE_CONTACTS si applica solo alle app che hanno come target la prossima release di Android e quelle successive. Le app che hanno come target versioni precedenti mantengono il loro comportamento attuale, tuttavia il nuovo editor dei contatti standardizzato sarà disponibile per tutte le app in esecuzione sul nuovo sistema operativo, indipendentemente dall'SDK target.
  • La mia app può eliminare i contatti con un intent?
    • No. Non esiste un intent per l'eliminazione dei contatti. Gli utenti eliminano i contatti nella loro app Contatti. Le app con MANAGE_CONTACTS possono eliminare i contatti direttamente.
  • Ho già la mia schermata di modifica dei contatti. Posso tenerlo?
    • Solo se la tua app è idonea per MANAGE_CONTACTS. La volontà di mantenere un design personalizzato non è di per sé un motivo valido.
  • MANAGE_CONTACTS sostituisce READ_CONTACTS?
    • MANAGE_CONTACTS include l'accesso in lettura, quindi non è necessario richiedere entrambi, ma molte app sono idonee per READ_CONTACTS e non hanno bisogno di modificare i contatti. Queste app potrebbero continuare a richiedere READ_CONTACTS.
  • Cosa succede ai miei utenti con versioni di Android precedenti?
    • Gli intent dei contatti funzionano anche sulle versioni precedenti e vengono gestiti dall'app Contatti del dispositivo. La maggior parte delle app funzionerà bene su tutti i dispositivi che utilizzano questi intent. Se la tua app è interessata da un problema di coerenza specifico risolto solo nelle ultime versioni, puoi mantenere l'autorizzazione WRITE_CONTACTS nel manifest con un valore maxSdkVersion appropriato.
Continua a leggere