Programación Android, startActivityForResult (Lanzar una actividad para recibir un resultado)

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0

En un ejemplo anterior mandamos información de nuestra actividad a la siguiente que lanzábamos, a través de los extras del Intent. Pero en android tenemos también la posibilidad de lanzar una nueva actividad a la espera de que esta nos devuelva un determinado resultado, y así tratar la información en nuestra actividad principal.

En esta ocasión vamos a explicar cómo podemos utilizar esta herramienta. Para ello diseñaremos una interfaz con dos EditText y dos Button, ambos botones van a llamar a una siguiente actividad, que lanzaremos a la espera de un resultado, y cuando recibamos el resultado, trataremos la información en función de cómo haya sido llamada la segunda actividad. La segunda actividad tendrá únicamente un EditText y un Button, en el EditText escribiremos un texto, y al darle al Button estableceremos el resultado. Este texto introducido lo mostraremos en el EditText de la primera actividad que corresponda al Button que hayamos pulsado inicialmente.

Puede parecer un poco abstracto así explicado, por eso, para entenderlo mejor, pasaremos a mostrar el código, con el que será más fácil entender el ejercicio.

Creando la actividad principal

Primero, creamos la vista de nuestra primera actividad con dos EditText y dos Button:
Main

El código XML quedaría parecido a este:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Main" >

   <TextView
        android:id=&quot;@+id/tvNombre&quot;
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="@string/tvNombre" />

    <EditText
        android:id="@+id/etNombre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tvNombre"
        android:layout_below="@+id/tvNombre"
        android:ems="10"
        android:inputType="text" />

    <TextView
        android:id="@+id/tvApellido"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/etNombre"
        android:layout_below="@+id/etNombre&"
        android:layout_marginTop="28dp"
        android:text="@string/tvApellido" />

    <EditText
        android:id="@+id/etApellido"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tvApellido"
        android:layout_below="@+id/tvApellido"
        android:ems="10"
        android:inputType="text" />

    <Button
        android:id="@+id/btNombre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/etNombre"
        android:layout_alignParentRight="true"
        android:text="@string/btNombre"
        android:onClick="rellenarNombre" />

    <Button
        android:id="@+id/btApellido"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/etApellido"
        android:layout_alignParentRight="true"
        android:text="@string/btApellido"
        android:onClick="rellenarApellido" />

</RelativeLayout>

Como se puede ver en el XML, los botones ya tienen un método onClick definido, este método lo tendremos que codificar nosotros en java, para que se ejecute al darle al botón.

Ahora tenemos que escribir el código de nuestra actividad, para que lance la segunda actividad a la espera de su resultado. Como hemos dicho, vamos a llamarla con dos opciones distintas, por lo tanto necesitamos una variable que identifique qué opción estamos utilizando para llamar a la segunda actividad, y así saber cómo debemos tratar la información resultante:

// Estas variables las declaramos al principio de nuestra clase, justo debajo
// de la cabecera:
private final static int NOMBRE = 0;
private final static int APELLIDO = 1;

startActivityForResult

También tendremos que definir los métodos que se ejecutan al pulsar los botones. Estos botones tendrán que lanzar la segunda actividad, e identificar qué botón está llamando a la segunda actividad. Para esto, en lugar de usar el método startActivity, usaremos el método startActivityForResult, cuyo uso es muy parecido:

// Método que se ejecuta al pulsar el botón btNombre:
public void rellenarNombre(View v) {
	Intent i = new Intent(this, RellenarCampos.class);
	// Iniciamos la segunda actividad, y le indicamos que la iniciamos
	// para rellenar el nombre:
	startActivityForResult(i, NOMBRE);
}
// Método que se ejecuta al pulsar el botón btApellido
public void rellenarApellido(View v) {
	Intent i = new Intent(this, RellenarCampos.class);
	// Iniciamos la segunda actividad, y le indicamos que la iniciamos
	// para rellenar el apellido:
	startActivityForResult(i, APELLIDO);
}

Con esto hemos lanzado la segunda actividad, ahora tendremos que crear esta segunda actividad, a la que, como se puede ver en nuestro Intent, hemos llamado RellenarCampos.

Creando la segunda actividad

En esta segunda actividad sólo tendremos que definir un EditText, que luego utilizaremos para recoger los datos que queremos mandar a la primera aplicación, y dos Button, uno para aceptar el resultado y otro para cancelarlo:
Result

El XML debería resultaros parecido al siguiente:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".RellenarCampos" >

    &lt;EditText
        android:id="@+id/etResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:ems="10"
        android:inputType="text" />

    <Button
        android:id="@+id/btAceptar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft=";@+id/etResult"
        android:layout_below="@+id/etResult"
        android:layout_marginTop="23dp"
        android:text="@string/btAceptar" />

    <Button
        android:id="@+id/btCancelar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/btAceptar"
        android:layout_alignRight="@+id/etResult"
        android:text="@string/btCancelar" />

</RelativeLayout>

En esta ocasión podemos ver que los Butones no tienen definido el método onClick desde el XML, porque esta vez codificaré el evento directamente en java (en realidad es indiferente qué método se utilice, cada programador utilizará el método que más cómodo le resulte).

setResult

Una vez que ya tenemos la interfaz gráfica diseñada, tenemos que codificar nuestra segunda actividad para que recoja los datos del EditText y los envíe a la actividad que la inició. Lo haremos con el siguiente código:

// Declaramos las variables Button para posteriormente definir
// sus métodos onClick.
Button btAceptar, btCancelar;
// Declaramos el EditText para recoger el resultado.
EditText etResult;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.rellenar_campos);
	// Enlazamos las variables con los componentes que tenemos en el XML
	btAceptar = (Button)findViewById(R.id.btAceptar);
	btCancelar = (Button)findViewById(R.id.btCancelar);
	etResult = (EditText)findViewById(R.id.etResult);

	// Definimos el listener que ejecutará el método onClick del botón aceptar.
	btAceptar.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View v) {
			// Si el EditText no está vacío recogemos el resultado.
			if(etResult.getText().length()!=0) {
				// Guardamos el texto del EditText en un String.
				String resultado = etResult.getText().toString();
				// Recogemos el intent que ha llamado a esta actividad.
				Intent i = getIntent();
				// Le metemos el resultado que queremos mandar a la
				// actividad principal.
				i.putExtra("RESULTADO", resultado);
				// Establecemos el resultado, y volvemos a la actividad
				// principal. La variable que introducimos en primer lugar
				// "RESULT_OK" es de la propia actividad, no tenemos que
				// declararla nosotros.
				setResult(RESULT_OK, i);

				// Finalizamos la Activity para volver a la anterior
				finish();
			} else {
 				// Si no tenía nada escrito el EditText lo avisamos.
 				Toast.makeText(RellenarCampos.this,
 				&quot;No se ha introducido nada en el campo de texto&quot;,
				 Toast.LENGTH_SHORT).show();
 			}
		});

 	// Definimos el listener que ejecutará el método onClick del botón cancelar.
 	btCancelar.setOnClickListener(new OnClickListener() {

 		@Override
		public void onClick(View v) {
 			// Si se pulsa el botón, establecemos el resultado como cancelado.
 			// Al igual que con "RESULT_OK", esta variable es de la activity.
			setResult(RESULT_CANCELED);

			// Finalizamos la Activity para volver a la anterior
			finish();
		}
 	});
}

onActivityResult

Y por último, tenemos que definir cómo recuperar la información resultante de la segunda actividad, y qué hacer con ella, para esto sobreescribiremos un método que nos proporciona Android, onActivityResult, que nos proporciona los parámetros necesarios para saber qué lanzó la segunda actividad, y si el resultado es de “OK” o “CANCELED”.

Primero declaramos las variables de los EditText que necesitamos para luego mostrar los datos, justo debajo de las variables estáticas que creamos antes (NOMBRE, APELLIDO).

EditText etNombre, etApellido;

Después las iniciamos con el inicio de la actividad.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	etNombre = (EditText)findViewById(R.id.etNombre);
	etApellido = (EditText)findViewById(R.id.etApellido);
}

Por último sobreescribimos el método onActivityResult.

// Este método nos trae la información de para qué se llamó la segunda actividad,
// cuál fue el resultado ("OK" o "CANCELED"), y el intent que nos traerá la
// información que necesitamos de la segunda actividad.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	// Comprobamos si el resultado de la segunda actividad es "RESULT_CANCELED".
	if (resultCode == RESULT_CANCELED) {
		// Si es así mostramos mensaje de cancelado por pantalla.
		Toast.makeText(this, "Resultado cancelado", Toast.LENGTH_SHORT)
				.show();
	} else {
		// De lo contrario, recogemos el resultado de la segunda actividad.
		String resultado = data.getExtras().getString("RESULTADO");
		// Y tratamos el resultado en función de si se lanzó para rellenar el
		// nombre o el apellido.
		switch (requestCode) {
		case NOMBRE:
			etNombre.setText(resultado);
			break;
		case APELLIDO:
			etApellido.setText(resultado);
			break;
		}
	}
}

Descargas

Puedes ver el resultado del ejemplo en tu móvil descargando nuestra aplicación desde Google Play.

Puedes acceder a nuestro repositorio para bajar el proyecto aquí.

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
The following two tabs change content below.
Reborn as IT Developer. Desarrollador Android y fundador de Proyecto Simio. "En realidad, yo no puedo enseñar nada a nadie, sólo puedo hacerles pensar." - Sócrates.

20 thoughts on “Programación Android, startActivityForResult (Lanzar una actividad para recibir un resultado)

  1. Hola: gracias por compartir tu conocimiento: tengo una aplicacion la cual cuenta con dos botones en la actividad principal, la idea es que al darle click en ellos, me envíen a la actividad del recyclerview el cual sería el mismo para los dos botones, lo unico es que al darle click en el botón 1 muestre la información solo de ese botón y en el botón 2 al darle click se muestre solo la información de ese botón, agradezco toda la información que me puedas dar, gracias.

  2. Es el mejor tutorial en español que he encontrado en toda la red acerca de como funciona el envío y recepción de variables en Android. Felicidades amigo, tienes el don!

  3. Buenos días, sólo un detalle… en el onClick del botón Aceptar te faltó el finish(); para que se vuelva a la activity anterior. Gracias por tu aporte, me sirvió :)

Deja un comentario