Modificare i contatti utilizzando intent

Questa lezione mostra come utilizzare un Intent per inserire un nuovo contatto o modificare i dati di un contatto. Anziché accedere direttamente al fornitore di servizi di contatto, un Intent avvia l'app Contatti, che esegue il Activity appropriato. Per le azioni di modifica descritte in questa lezione, Se invii dati estesi in Intent, questi vengono inseriti nell'interfaccia utente del Activity che viene avviata.

L'utilizzo di un Intent per inserire o aggiornare un singolo contatto è il metodo preferito per modificare il fornitore di contatti, per i seguenti motivi:

  • Ti fa risparmiare tempo e fatica per lo sviluppo di codice e interfaccia utente.
  • Evita di introdurre errori causati da modifiche che non seguono le Regole del provider di contatti.
  • Riduce il numero di autorizzazioni da richiedere. La tua app non ha bisogno dell'autorizzazione per scrivere nel provider di contatti, perché delega le modifiche all'app Contatti, che dispone già di questa autorizzazione.

Inserire un nuovo contatto utilizzando un'intenzione

Spesso vuoi consentire all'utente di inserire un nuovo contatto quando l'app riceve nuovi dati. Ad esempio, un'app di recensioni di ristoranti può consentire agli utenti di aggiungere il ristorante come contatto mentre lo recensiscono. Per farlo utilizzando un'intenzione, crea l'intenzione utilizzando tutti i dati a tua disposizione e poi inviala all'app Contatti.

L'inserimento di un contatto tramite l'app Contatti inserisce un nuovo contatto non elaborato nella tabella ContactsContract.RawContacts del fornitore di servizi di contatto. Se necessario, l'app dei contatti richiede agli utenti il tipo di account e l'account da utilizzare durante la creazione dei dati non elaborati contatto. L'app Contatti avvisa inoltre gli utenti se il contatto non elaborato esiste già. Gli utenti avranno quindi di annullare l'inserimento, nel qual caso non viene creato alcun contatto. Per ulteriori informazioni maggiori informazioni sui contatti non elaborati, consulta Fornitore di contatti Guida alle API.

Crea un intent

Per iniziare, crea un nuovo oggetto Intent con l'azione Intents.Insert.ACTION. Imposta il tipo MIME su RawContacts.CONTENT_TYPE. Ad esempio:

Kotlin

...
// Creates a new Intent to insert a contact
val intent = Intent(ContactsContract.Intents.Insert.ACTION).apply {
    // Sets the MIME type to match the Contacts Provider
    type = ContactsContract.RawContacts.CONTENT_TYPE
}

Java

...
// Creates a new Intent to insert a contact
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
// Sets the MIME type to match the Contacts Provider
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);

Se hai già i dettagli del contatto, ad esempio un numero di telefono o un indirizzo email, puoi inserirli nell'intent come dati estesi. Per un valore chiave, utilizza la costante appropriata da Intents.Insert. L'app Contatti visualizza i dati nella schermata di inserimento, consentendo agli utenti di apportare ulteriori modifiche e aggiunte.

Kotlin

private var emailAddress: EditText? = null
private var phoneNumber: EditText? = null
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = findViewById(R.id.email)
phoneNumber = findViewById(R.id.phone)
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
intent.apply {
    // Inserts an email address
    putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress?.text)
    /*
     * In this example, sets the email type to be a work email.
     * You can set other email types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK
    )
    // Inserts a phone number
    putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber?.text)
    /*
     * In this example, sets the phone type to be a work phone.
     * You can set other phone types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK
    )
}

Java

private EditText emailAddress = null;
private EditText phoneNumber = null;
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = (EditText) findViewById(R.id.email);
phoneNumber = (EditText) findViewById(R.id.phone);
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
// Inserts an email address
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress.getText())
/*
 * In this example, sets the email type to be a work email.
 * You can set other email types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK)
// Inserts a phone number
      .putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber.getText())
/*
 * In this example, sets the phone type to be a work phone.
 * You can set other phone types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK);

Dopo aver creato il Intent, invialo chiamando startActivity().

Kotlin

    /* Sends the Intent
     */
    startActivity(intent)

Java

    /* Sends the Intent
     */
    startActivity(intent);

Questa chiamata apre una schermata nell'app Contatti che consente agli utenti di inserire un nuovo contatto. La il tipo e il nome dell'account del contatto sono indicati nella parte superiore dello schermo. Dopo che gli utenti hanno inserito i dati e fatto clic su Fine, viene visualizzato l'elenco contatti dell'app Contatti. Gli utenti tornano alla tua app facendo clic su Indietro.

Modificare un contatto esistente utilizzando un intent

La modifica di un contatto esistente utilizzando un Intent è utile se l'utente ha già scelto un contatto di suo interesse. Ad esempio, un'app che trova i contatti con gli indirizzi postali, ma l'assenza di un codice postale potrebbe offrire agli utenti la possibilità di cercarlo e poi aggiungerlo al contatto.

Per modificare un contatto esistente utilizzando un intent, utilizza una procedura simile a all'inserimento di un contatto. Crea un'intenzione come descritto nella sezione Inserire un nuovo contatto utilizzando un'intenzione, ma aggiungi all'intenzione il valore Contacts.CONTENT_LOOKUP_URI e il tipo MIMEContacts.CONTENT_ITEM_TYPE del contatto. Se vuoi modificare il contatto con i dettagli che hai già, puoi inserirli nei dati estesi dell'intent. Nota che alcune le colonne del nome non possono essere modificate utilizzando un intent; queste colonne sono elencate nel riepilogo del riferimento dell'API per la classe ContactsContract.Contacts nella sezione "Update" (Aggiorna).

Infine, invia l'intent. In risposta, l'app Contatti mostra una schermata di modifica. Quando l'utente ha terminato la modifica e salvato le modifiche, l'app Contatti mostra un elenco di contatti. Quando l'utente Se fai clic su Indietro, viene visualizzata l'app.

Creare l'intent

Per modificare un contatto, chiama Intent(action) al crea un intent con l'azione ACTION_EDIT. Chiama setDataAndType() per impostare il valore dei dati per lo scopo su Contacts.CONTENT_LOOKUP_URI del contatto e il tipo MIME su Contacts.CONTENT_ITEM_TYPE. Poiché una chiamata a setType() sovrascrive il valore corrente dei dati per Intent, devi impostare i dati e il tipo MIME contemporaneamente.

Per ottenere il valore Contacts.CONTENT_LOOKUP_URI di un contatto, chiama Contacts.getLookupUri(id, lookupkey) con i valori Contacts._ID e Contacts.LOOKUP_KEY del contatto come argomenti.

Nota: il valore LOOKUP_KEY di un contatto è l'identificatore da utilizzare per recuperarlo. Rimane costante, anche se il provider modifica l'ID riga del contatto per gestire le operazioni interne.

Il seguente snippet mostra come creare un intent:

Kotlin

    // The Cursor that contains the Contact row
    var mCursor: Cursor? = null
    // The index of the lookup key column in the cursor
    var lookupKeyIndex: Int = 0
    // The index of the contact's _ID value
    var idIndex: Int = 0
    // The lookup key from the Cursor
    var currentLookupKey: String? = null
    // The _ID value from the Cursor
    var currentId: Long = 0
    // A content URI pointing to the contact
    var selectedContactUri: Uri? = null
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    mCursor?.apply {
        // Gets the lookup key column index
        lookupKeyIndex = getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)
        // Gets the lookup key value
        currentLookupKey = getString(lookupKeyIndex)
        // Gets the _ID column index
        idIndex = getColumnIndex(ContactsContract.Contacts._ID)
        currentId = getLong(idIndex)
        selectedContactUri = ContactsContract.Contacts.getLookupUri(currentId, mCurrentLookupKey)
    }

    // Creates a new Intent to edit a contact
    val editIntent = Intent(Intent.ACTION_EDIT).apply {
        /*
         * Sets the contact URI to edit, and the data type that the
         * Intent must match
         */
        setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE)
    }

Java

    // The Cursor that contains the Contact row
    public Cursor mCursor;
    // The index of the lookup key column in the cursor
    public int lookupKeyIndex;
    // The index of the contact's _ID value
    public int idIndex;
    // The lookup key from the Cursor
    public String currentLookupKey;
    // The _ID value from the Cursor
    public long currentId;
    // A content URI pointing to the contact
    Uri selectedContactUri;
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    // Gets the lookup key column index
    lookupKeyIndex = mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
    // Gets the lookup key value
    currentLookupKey = mCursor.getString(lookupKeyIndex);
    // Gets the _ID column index
    idIndex = mCursor.getColumnIndex(ContactsContract.Contacts._ID);
    currentId = mCursor.getLong(idIndex);
    selectedContactUri =
            Contacts.getLookupUri(currentId, mCurrentLookupKey);
    ...
    // Creates a new Intent to edit a contact
    Intent editIntent = new Intent(Intent.ACTION_EDIT);
    /*
     * Sets the contact URI to edit, and the data type that the
     * Intent must match
     */
    editIntent.setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);

Aggiungi il flag di navigazione

In Android 4.0 (API versione 14) e versioni successive, un problema nell'app Contatti causa errori per la navigazione. Quando la tua app invia un'intenzione di modifica all'app Contatti e gli utenti modificano e salvano un contatto, quando fanno clic su Indietro viene visualizzata la schermata dell'elenco dei contatti. Per tornare alla tua app, deve fare clic su Recenti e scegliere la tua app.

Per risolvere questo problema in Android 4.0.3 (API versione 15) e versioni successive, aggiungi l'estensione chiave dei dati finishActivityOnSaveCompleted all'intent, con un valore pari a true. Le versioni di Android precedenti ad Android 4.0 accettano questa chiave, ma non ha alcun effetto. Per impostare i dati estesi:

Kotlin

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true)

Java

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true);

Aggiungi altri dati estesi

Per aggiungere altri dati estesi a Intent, chiama putExtra() a tua scelta. Puoi aggiungere dati estesi per i campi di contatto comuni utilizzando le coppie chiave-valore specificate in Intents.Insert. Ricorda che alcune le colonne della tabella ContactsContract.Contacts non possono essere modificate. Queste colonne sono elencate nella sezione summary del riferimento dell'API per la classe ContactsContract.Contacts nella sezione "Aggiorna".

Invia l'intent

Infine, invia l'intent che hai creato. Ad esempio:

Kotlin

    // Sends the Intent
    startActivity(editIntent)

Java

    // Sends the Intent
    startActivity(editIntent);

Consenti agli utenti di scegliere di inserire o modificare utilizzando un intent

Puoi consentire agli utenti di scegliere se inserire un contatto o modificarne uno esistente inviando un Intent con l'azione ACTION_INSERT_OR_EDIT. Ad esempio, un'app client di posta consentire agli utenti di aggiungere l'indirizzo email in arrivo a un nuovo contatto o aggiungerlo come ulteriore per un contatto esistente. Imposta il tipo MIME per questo intent su Contacts.CONTENT_ITEM_TYPE, ma non impostare l'URI dei dati.

Quando invii questa intent, l'app Contatti mostra un elenco di contatti. Gli utenti possono inserire un nuovo contatto o sceglierne uno esistente e modificarlo. Eventuali campi di dati estesi aggiunti all'intent vengono completati nella schermata visualizzata. Puoi utilizzare uno qualsiasi dei valori chiave specificati in Intents.Insert. Il seguente snippet di codice mostra come creare e inviare l'intent:

Kotlin

    // Creates a new Intent to insert or edit a contact
    val intentInsertEdit = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        // Sets the MIME type
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
    }
    // Add code here to insert extended data, if desired

    // Sends the Intent with an request ID
    startActivity(intentInsertEdit)

Java

    // Creates a new Intent to insert or edit a contact
    Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT);
    // Sets the MIME type
    intentInsertEdit.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
    // Add code here to insert extended data, if desired
    ...
    // Sends the Intent with an request ID
    startActivity(intentInsertEdit);