En esta lección, se muestra cómo usar un Intent
para insertar un nuevo contacto o modificar los datos de uno existente. En lugar de acceder al proveedor de contactos directamente, un Intent
inicia la app de Contactos, que ejecuta la Activity
apropiada. En el caso de las acciones de modificación que se describen en esta lección, si envías datos extendidos en el Intent
, estos se ingresan en la IU de la Activity
que se inicia.
Se prefiere usar un Intent
para insertar o actualizar un solo contacto
de modificación del proveedor de contactos por los siguientes motivos:
- Te ahorra el tiempo y el esfuerzo que implica desarrollar una IU y un código propios.
- Evita que las modificaciones que no cumplen con las reglas del Proveedor de contactos generen errores.
- Reduce la cantidad de permisos que debes solicitar. Tu app no necesita permiso para escribirle al proveedor de contactos porque este delega las modificaciones a la App de contactos que ya cuenta con ese permiso.
Cómo insertar un nuevo contacto con un intent
A menudo quieres permitir que el usuario inserte un nuevo contacto cuando tu app recibe datos nuevos. Para ejemplo, una aplicación de opiniones sobre restaurantes puede permitir que los usuarios agreguen el restaurante como contacto cuando está de revisarla. Para hacer esto con un intent, debes crearlo usando todos los datos que tengas. disponible y, luego, envía el intent a la App de Contactos.
Cuando realizas la inserción mediante la App de Contactos, se agrega un nuevo contacto sin procesar en la tabla ContactsContract.RawContacts
del Proveedor de contactos. Si es necesario, la App de Contactos solicita a los usuarios el tipo de cuenta y la cuenta que usarán cuando creen un contacto sin procesar. La App de Contactos también notifica a los usuarios si este ya existe. En este caso, los usuarios tienen la opción de cancelar la inserción, de modo que no se creará ningún contacto. Para obtener más información sobre los contactos sin procesar, consulta la guía de la API del Proveedor de Contactos.
Cómo crear un intent
Para comenzar, crea un objeto Intent
nuevo con la acción Intents.Insert.ACTION
.
Establece el tipo MIME en RawContacts.CONTENT_TYPE
. Por ejemplo:
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);
Si ya tienes los detalles del contacto, como un número de teléfono o una dirección de correo electrónico, puedes
insertarlos en el intent como datos extendidos. Para obtener un valor clave, usa la constante apropiada de Intents.Insert
. La app de Contactos
Muestra los datos en su pantalla de inserción, lo que permite a los usuarios realizar más ediciones y adiciones.
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);
Una vez que crees el Intent
, envíalo mediante una llamada a startActivity()
.
Kotlin
/* Sends the Intent */ startActivity(intent)
Java
/* Sends the Intent */ startActivity(intent);
Esta llamada abre una pantalla en la App de Contactos, que permite a los usuarios ingresar un contacto nuevo. El el tipo de cuenta y el nombre del contacto aparecerán en la parte superior de la pantalla. Una vez que los usuarios ingresen los datos y hagan clic en Listo, aparecerá la lista de contactos de la App de Contactos. Luego, los usuarios podrán volver a tu app haciendo clic en Atrás.
Cómo editar un contacto existente con un intent
Editar un contacto existente usando un Intent
es útil si el usuario
ya eligió un contacto de interés. Por ejemplo, una app que encuentra contactos que tienen direcciones postales, pero no tienen un código postal, podría darles a los usuarios la opción de buscar el código y, luego, agregarlo al contacto.
Para editar un contacto existente por medio de un intent, usa un procedimiento similar al siguiente:
insertar un contacto. Crea un intent como se describe en la sección Cómo insertar un nuevo contacto con un intent, pero agrega el Contacts.CONTENT_LOOKUP_URI
del contacto y el Contacts.CONTENT_ITEM_TYPE
del tipo de MIME al intent. Si deseas editar el contacto con detalles que
ya tienes, puedes colocarlas en los datos extendidos del intent. Observa que algunos
las columnas de nombre no se pueden editar con un intent; estas columnas se enumeran en el resumen
Sección de la referencia de la API para la clase ContactsContract.Contacts
en el encabezado "Actualizar".
Por último, envía el intent. En respuesta, la App de Contactos muestra una pantalla de edición. Cuando el usuario termina de editar y guarda los cambios, la App de Contactos muestra una lista de contactos. Cuando el usuario hace clic en Atrás, se muestra tu aplicación.
Cómo crear el intent
Para editar un contacto, llama a Intent(action)
para crear un intent con la acción ACTION_EDIT
. Llamada
setDataAndType()
para establecer el valor de datos del
intent con el Contacts.CONTENT_LOOKUP_URI
del contacto y el tipo de MIME para
tipo de MIME Contacts.CONTENT_ITEM_TYPE
; porque una llamada a
setType()
reemplaza el valor de datos actual del
Intent
, debes configurar los datos y el tipo de MIME al mismo tiempo.
Para obtener el Contacts.CONTENT_LOOKUP_URI
de un contacto, llama a
Contacts.getLookupUri(id, lookupkey)
con el
Contacts._ID
y
Contacts.LOOKUP_KEY
valores como
argumentos.
Nota: El valor LOOKUP_KEY
de un contacto es el identificador que deberías usar para obtenerlo. Permanece constante,
incluso si el proveedor cambia el ID de la fila del contacto para que administre operaciones internas.
En el siguiente fragmento, se muestra cómo crear 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);
Cómo agregar la marca de navegación
En Android 4.0 (nivel de API 14) y versiones posteriores, un problema en la aplicación de contactos hace que la navegación. Cuando tu app envía un intent de edición a la App de Contactos, y los usuarios editan y guardan un contacto, cuando haga clic en Atrás, verá la pantalla de la lista de contactos. Para volver a tu app, deberá hacer clic en Recientes y elegirla.
Para solucionar este problema en Android 4.0.3 (nivel de API 15) y versiones posteriores, agrega la versión
clave de datos finishActivityOnSaveCompleted
al intent, con un valor de true
.
Las versiones de Android anteriores a la 4.0 aceptan esta clave, pero no tiene ningún efecto. Para establecer la
datos extendidos, haz lo siguiente:
Kotlin
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true)
Java
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true);
Cómo agregar otros datos extendidos
Para agregar datos extendidos adicionales a Intent
, llama a
putExtra()
según lo desees.
Puedes agregar datos extendidos para campos de contactos comunes mediante valores clave especificados en Intents.Insert
. Recuerda que algunas
de la tabla ContactsContract.Contacts
.
Estas se enumeran en la sección de resumen de la referencia de la API para la clase
ContactsContract.Contacts
en el encabezado "Actualizar".
Cómo enviar el intent
Por último, debes enviar el intent que construiste. Por ejemplo:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
Cómo permitir que los usuarios elijan insertar o editar con un intent
Para permitir que los usuarios elijan si desean insertar un contacto o editar uno existente, envía
un objeto Intent
con la acción
ACTION_INSERT_OR_EDIT
Por ejemplo, una app cliente
de correo electrónico podría
Permite a los usuarios agregar una dirección de correo electrónico entrante a un contacto nuevo o agregarla como dirección de
de un contacto existente. Establece el tipo MIME para este intent en Contacts.CONTENT_ITEM_TYPE
, pero no establezcas el URI de datos.
Cuando envíes este intent, la App de Contactos mostrará una lista de contactos.
Los usuarios pueden insertar un nuevo contacto o elegir uno existente y editarlo.
Cualquier campo de datos extendidos que agregas al intent completa la pantalla que aparece. Puedes usar
cualquiera de los valores clave especificados en Intents.Insert
En el siguiente fragmento de código, se muestra cómo construir y enviar el 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);