Un Intent se emplea habitualmente para lanzar una Activity,
ya sea de la propia aplicación o de una aplicación externa.
Compatibilidad
v1
Lo mínimo necesario
Para lanzar una Activity de la propia app se usa un Intent
explícito, ya que el nombre de la clase que representa la Activity destino es
conocido:
Un Intent implícito define una llamada al sistema operativo. En este caso lo que se define es una acción general a ejecutar y la información para el Activity destino, de forma que el sistema es quien decide qué app o componente del mismo debe ejecutar para satisfacer la orden.
- Disponer de todas las activities configuradas en el Manifest:
<activity
android:name="es.hubiqus.drawer.NoticiasActivity"
android:label="@string/app_name"
android:configChanges="orientation|screenSize"
>
</activity>
|
- Lanzar la segunda Activity desde código:
startActivity(new Intent(getActivity(), NoticiaActivity.class));
|
Un Intent implícito define una llamada al sistema operativo. En este caso lo que se define es una acción general a ejecutar y la información para el Activity destino, de forma que el sistema es quien decide qué app o componente del mismo debe ejecutar para satisfacer la orden.
Por ejemplo, empleo de un Intent para ver una web, que la
visualizará en un navegador del dispositivo:
//Acción ver
//La URL debe ser de servidor externo en formato correcto http(s)://...
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
|
Además de la información básica, en la llamada del Intent se
pueden incluir otros elementos extra, como se puede ver en el siguiente código para
compartir información con otras apps:
//Acción enviar
Intent intent = new Intent(Intent.ACTION_SEND);
//Tipo de contenido que se va a enviar
intent.setType("text/plain");
//Asunto
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
//Texto
intent.putExtra(Intent.EXTRA_TEXT, shareText);
//Crear diálogo para seleccionar app
startActivity(Intent.createChooser(intent, getString(R.string.compartir)));
|
También es posible incluir flags que determinan cómo atenderá
el sistema operativo a la petición:
Intent intent = new Intent(getActivity(), InicioActivity.class);
//Limpiar todo el back stack
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
|
Parámetros
Para pasar parámetros a un Intent se puede emplear un
Bundle:
Bundle args = new Bundle();
args.putSerializable(NoticiaActivity.PARAM_ITEM, noticia);
Intent intent = new Intent(getActivity(), NoticiaActivity.class);
intent.putExtras(args);
startActivity(intent);
|
También se puede emplear un paso directo de parámetros básicos
a través de las distintas versiones del método putExtra de la clase Intent, sin
necesidad de usar el Bundle.
Los datos se recogen en la Activity destino a través de
getIntent:
Bundle args = getIntent().getExtras();
|
Serializable y Parcelable
Además de datos de tipos básicos Java, en Android se pueden
emplear para comunicar activities o fragments dos tipos especiales de clases.
Cualquier clase que implemente el interfaz Serializable o Parcelable se
convierte automáticamente en una clase que puede ser pasada a través de
parámetro de forma sencilla.
Serializable es el interfaz Java clásico para serializar
(convertir una clase en representación de bytes) y poder enviar de un extremo a
otro. En Android se introduce Parcelable como una alternativa más eficiente.
Implementar un interfaz Serializable es muy sencillo,
simplemente se necesita añadir la cabecera correspondiente a la clase siempre
que dicha clase se encuentre formada por atributos que a su vez sean
serializables, tales como tipos básicos o clases habituales (String, ArrayList,
…). En caso de disponer de atributos no serializables será necesario
implementar los métodos del interfaz para indicar cómo se realizan las
conversiones de información.
public class Noticia implements Serializable {
|
En el caso de Parcelable, aunque se trate de una conversión
de tipos básicos sí que es imprescindible implementar algunos métodos y disponer
de una clase Creator. El comportamiento es análogo al que se emplea para
serializar y deserializar un objeto, escribir los datos hacia el Parcel en un
orden y recogerlos en el mismo orden.
public class Persona implements Parcelable {
private String nombre;
private String direccion;
/**
* Constructor usado para recrear un objeto desde
un parcel
* @param in parcel del cual leer el objeto
*/
public Poi(Parcel in) {
this.nombre = in.readString();
this.direccion = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nombre);
dest.writeString(direccion);
}
public static final
Parcelable.Creator<Persona> CREATOR =
new
Parcelable.Creator<Persona>() {
public Persona
createFromParcel(Parcel in) {
return new Persona(in);
}
public Persona[] newArray(int size) {
return new Persona[size];
}
};
}
|
Resultados
Cuando un Intent lanza una Activity habitualmente cede el
control a la misma y no espera un retorno. En Android también es posible
comunicar las activities para producir un resultado desde la segunda Activity
que sea empleado en la primera.
En primer lugar es necesario lanzar el Intent empleando el
método startActivityForResult acompañado de una constante que será definida en
la clase y que simplemente actúa como etiqueta para saber qué Activity fue
lanzada:
//Acción para selección de imagen
private static final int SEL_IMAGEN = 0;
//Acción para selección de localización
private static final int SEL_COORDENADA = 1;
...
startActivityForResult(intent,
SEL_IMAGEN);
|
El método onActivityResult será quien se encargue de recoger
el resultado y actuar en consecuencia. Este método es invocado automáticamente
al recuperar la Activity llamante el control del sistema, es decir, cuando la
segunda Activity se cierra y en pantalla vuelve a aparecer la anterior.
@Override
public void onActivityResult(int reqCode, int resultCode, Intent intent)
{
//reqCode es la constante que determina qué Activity fue invocada
switch (reqCode)
{
case SEL_IMAGEN:
//resultCode OK indica que se produjo
resultado en el destino
if (resultCode ==
Activity.RESULT_OK) {
...
}
break;
case SEL_COORDENADA:
if (resultCode == Activity.RESULT_OK) {
...
}
break;
}
}
|
En la Activity destino se guarda el resultado en un Intent el
cual se pasará a la Activity principal a través del parámetro correspondiente
del método onActivityResult.
Bundle args = new Bundle();
args.putString(PARAM_RES, "Resultado
de la Activity 2");
Intent result = new Intent();
result.putExtras(args);
setResult(Activity.RESULT_OK, result);
|
No hay comentarios:
Publicar un comentario