Esta lección te enseñará a
También deberías leer
Iniciar otra actividad no tiene por qué ser un camino de una única dirección. También puedes recibir un resultado de la actividad iniciada. Para ello, llama a startActivityForResult()
(en lugar de startActivity()
).
Por ejemplo, tu aplicación puede iniciar una aplicación de cámara y recibir la fotografía tomada como resultado. O podrías iniciar la aplicación de Contactos para que el usuario elija un contacto y recibir los detalles de esa persona como resultado.
Por supuesto, la actividad que inicies debe estar diseñada para devolver un resultado. Si es así, esta devolverá el resultado en forma de otro objeto Intent
. Tu actividad recibirá esta intención en la retrollamada onActivityResult()
.
Nota: Al llamar a startActivityForResult()
puedes utilizar intenciones explícitas o implícitas. Si inicias una de tus propias actividades esperando un resultado, deberías utilizar una intención explícita para asegurarte de que obtienes el resultado esperado.
Iniciar la actividad
El Intent
utilizado para iniciar una actividad que va a devolver un resultado no tiene nada de particular, sólo necesitas pasar un parámetro adicional de tipo entero al método startActivityForResult()
.
Este entero es un "código de petición" con la que identificarla. Cuando recibes el Intent
resultado, la retrollamada proporciona este mismo código para que tu aplicación pueda reconocer la petición y determinar cómo manejarla.
Por ejemplo, el siguiente código permite mostrar una actividad con la que el usuario puede escoger un contacto:
static final int PICK_CONTACT_REQUEST = 1; // El código de petición ... private void pickContact() { Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts")); pickContactIntent.setType(Phone.CONTENT_TYPE); // Sólo mostramos los contactos con número de teléfono startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); }
Recibir el resultado
Cuando el usuario termina de utilizar esta segunda actividad, el sistema llama al método onActivityResult()
de la actividad inicial. Este método tiene tres argumentos:
- El código de petición que pasaste en
startActivityForResult()
. - Un código de resultado especificado por la segunda actividad. Este puede ser
RESULT_OK
si la operación terminó con éxito oRESULT_CANCELED
si el usuario canceló la operación o falló por algún motivo. - Un
Intent
con la información de resultado.
Por ejemplo, así es como manejarías el resultado de la intención "escoger un contacto":
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Comprobamos a qué petición estamos respondiendo if (requestCode == PICK_CONTACT_REQUEST) { // Nos aseguramos de que la petición terminó con éxito if (resultCode == RESULT_OK) { // El usuario seleccionó un contacto. // La Uri del Intent identifica el contacto seleccionado. // Hacemos algo con el contacto (ejemplo más detallado a continuación) } } }
En este ejemplo, el Intent
resultado devuelto por la aplicación de Contactos o la aplicación de Personas de Android proporciona una Uri
que identifica el contacto que seleccionó el usuario.
Para gestionar el resultado de manera adecuada, debes saber cuál será el formato del Intent
resultado. Esto es fácil cuando la actividad que devuelve el resultado es una de tus actividades. Las aplicaciones incluidas en la plataforma Android ofrecen sus propias APIs en las que puedes confiar para que te devuelvan un resultado específico. Por ejemplo, la aplicación Personas (Contactos en algunas versiones antiguas) siempre devuelve un resultado con una URI de contenido que identifica el contacto seleccionado, y la aplicación de Cámara devuelve un Bitmap
en el extra "data"
(lee la clase acerca de Tomar fotografías).
Extra: Leer los datos de un contacto
En el ejemplo anterior sobre cómo obtener un resultado de la aplicación Personas no se explica cómo leer los datos del resultado porque esto requiere de una discusión más avanzada acerca de los proveedores de contenido. Sin embargo, si tienes curiosidad, aquí tienes algo más de código que muestra cómo consultar el resultado para obtener el número de teléfono del contacto seleccionado:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Comprobamos a qué petición estamos respondiendo
if (requestCode == PICK_CONTACT_REQUEST) {
// Nos aseguramos de que la petición haya tenido éxito
if (resultCode == RESULT_OK) {
// Obtenemos la URI que apunta al contacto seleccionado
Uri contactUri = data.getData();
// Sólo necesitamos la columna NUMBER, porque sólo habrá una única fila en el resultado
String[] projection = {Phone.NUMBER};
// Ejecutamos la consulta en el contacto para obtener la columna NUMBER
// No necesitamos indicar una selección o un orden (sólo hay un único resultado para la URI dada)
// PRECAUCIÓN: El método query() debería llamarse desde un hilo aparte para evitar bloquear
// el hilo de interfaz de usuario de tu aplicación. (Por simplicidad, este código no lo hace.)
// Considera usar CursorLoader
para ejecutar la consulta.
Cursor cursor = getContentResolver()
.query(contactUri, projection, null, null, null);
cursor.moveToFirst();
// Obtenemos el número de teléfono de la columna NUMBER
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
// Hacemos algo con el número de teléfono...
}
}
}
Nota: Antes de Android 2.3 (nivel API 9), ejecutar una consulta en el Proveedor de Contactos
(como la que se muestra arriba) requeriría que tu aplicación pidiera el permiso READ_CONTACTS
(ver Seguridad y permisos). Sin embargo,
desde Android 2.3, la aplicación de Contactos/Personas concede a tu aplicación un permiso temporal para leer del Proveedor de Contactos cuando te devuelve un resultado. Este permiso temporal sólo se aplica para el contacto pedido, por lo que no podrás consultar ningún otro contacto que no sea el especificado por la Uri
de la intención, a menos que solicites el permiso READ_CONTACTS
.