Es la hora, es la hora (de que nos dejemos de caracolear y nos movamos con los próximos números) de que continuemos con nuestra saga de programación de Apps de Android desde cero.
En esta ocasión veremos como movernos entre actividades y como almacenar información mediante las preferencias de la app.
El detalle, como siempre, después del salto.
Les recordamos que este tutorial forma parte de la saga Cómo programar apps para Android, el cual ya tiene dos partes disponible, que pueden ver en este enlace:
Cómo programar apps para Android #1: Descarga, instalación y primera app
Cómo programar apps para Android #2: Ciclo de vida, vistas e interacciones
Vamos con lo primero:
Específicamente, lo siguiente:
Sin más que decir, vamos, manos a la obra:
En los números anteriores de esta saga, tanto en los ejemplos como en el trabajo de nuestra App, hemos visto como crear y trabajar en los métodos de una actividad, su ciclo de vida y como interactuar con las vistas que están asociadas a una actividad en particular. A la vez, al momento de partir y definir una App, dijimos que podía estar compuesta de una o más actividades (por lo general son varias). Las buenas prácticas indican que cada “sección o módulo” de nuestra App debiese estar asociada como mínimo a una Actividad, por lo que si por ej. nuestra aplicación contara con una sección de “Mi Cuenta” y otra de “Lista de Amigos”, lo lógico sería que cada una de ellas estuviera asociada a métodos de distintas Actividades (AccountActivity y FriendsActivity por ejemplo).
Pero viendo ese ejemplo, ¿qué pasa si estamos en una de ellas y queremos movernos a otra? ¿Cómo iniciamos una actividad a partir de otra?. Afortunadamente, esto es muy sencillo, solo debemos crear un objeto del tipo Intent. Estos objetos se encargan de enlazar 2 componentes de una aplicación (en este caso las Actividades) en tiempo de ejecución y Android las define como un “intento de hacer algo”, así de sencillo. El código para movernos de una Actividad a otra es el siguiente:
Intent intent = new Intent(this, FriendsActivity.class); startActivity(intent);
En el código anterior creamos un objeto de la clase Intent llamado intent (pueden llamarlo como quieran). A este objeto le entregamos 2 parámetros: El Contexto actual (que puede ser this o el nombre de la actividad.this, como AccountActivity.this, dependiendo de si nos encontramos operando a nivel de la actividad o dentro de un sub-contexto como por ej. al capturar un click de un botón).
Una vez que hemos creado el objeto Intent, llamamos al método startActivity y se lo pasamos como parámetro. Este método se encargará de llamar a la Actividad de destino y la cargará sobre la actual, por lo que si en la Actividad de destino presionamos el botón back en nuestro dispositivo, nos devolverá a la original (en este caso AccountActivity).
¿Y si no quiero que vuelva a esa Actividad?
Esto pasa a menudo. Por lo general las apps cuentan con al menos una Actividad a la que no queremos que los usuarios vuelvan a acceder (como por ej. una pantalla de Login), por lo que si los llevamos de una Actividad así a otra, lo que querremos es que al presionar el botón Back minimicen la app, y esto lo logramos agregando lo siguiente luego de hacer el proceso de llamado:
Intent intent = new Intent(this, FriendsActivity.class); startActivity(intent); this.finish();
Con esa última línea (this.finish( )) nos aseguramos que la Actividad que inicia la llamada se finalice luego de hacer la redirección, por lo que el usuario no podrá volver a ella.
¿Y si quiero pasar información entre Actividades?
Si, se puede, y es tan sencillo como lo anterior. A cada objeto del tipo Intent que creemos, podemos asociarle datos de todo tipo (String, int, boolean, byte, Bundle, double, float, etc.) con una simple sentencia:
Intent intent = new Intent(this, FriendsActivity.class); intent.putExtra("MENSAJE", "Hola mundo!"); startActivity(intent);
Lo que hicimos, luego de crear el objeto, fue llamar al método putExtra, el cual acepta 2 parámetros: El nombre de lo que estamos enviando (que siempre es una cadena de texto) y su valor (que puede ser cualquiera de los tipos que indicábamos más arriba). Para rescatar el valor en la Actividad de destino es muy simple también, solo con el siguiente código:
Intent intent = getIntent(); String mensaje = intent.getStringExtra("MENSAJE");
Lo que hacemos es bastante directo: Declaramos un objeto del tipo Intent y en el almacenamos el Intent actual (con el que llegamos a esta Actividad). Una vez que lo tenemos almacenado, llamamos al método getStringExtra, el cual acepta 1 parámetro: El nombre del dato que queremos recuperar, que fue almacenado en la Actividad original (en este caso “MENSAJE”). Así como se pueden enviar muchos tipos de datos, hay muchos métodos para recuperarlos (por ej. getIntExtra o getBooleanExtra entre otros). Algunos de ellos piden un parámetro adicional al nombre del dato que queremos recuperar, que es un valor por defecto en caso de que no se pueda rescatar: Por ej. para un getIntExtra donde quisierámos recuperar un dato llamado edad, sería algo así:
Intent intent = getIntent(); int edad = intent.getIntExtra("EDAD", 20);
De esa forma, si el dato no viene originalmente, se le asignará un valor de 20 a la variable edad.
Nota: El nombre de los datos no es necesario que sea en mayúscula. Acá lo definimos así para dejarlo más claro que se diferencia del valor en caso de que sea una cadena.
A medida que vamos desarrollando aplicaciones más complejas, es muy probable que necesitemos alguna forma para poder almacenar información (un dato del usuario, o un valor que nos indique si el usuario está autentificado para no mostrarle una pantalla de Login, etc.). Si bien cuando tenemos gran cantidad de información lo más recomendable es utilizar una base de datos local o algún método externo (como un servidor remoto), en ocasiones solo necesitamos guardar unos cuantos valores por lo que hacer todo ese proceso se vuelve innecesario.
Para ello, Android nos provee de una API llamada SharedPreferences, la cual nos permite crear objetos del mismo tipo que apuntan a un archivo local que permite almacenar información en pares “llave-valor”, tal como en el caso de los extra en los Intents que veíamos anteriormente. A diferencia de lo anterior eso si, acá solamente podemos trabajar con algunos tipos de valores (int, boolean, float, long, String y String set), pero por lo general con estos tipos cubrimos de buena manera las necesidades que podamos tener.
Para trabajar con las preferencias de una app es muy sencillo, solo debemos partir por abrir el archivo de preferencias de la siguiente forma:
Context context = getActivity(); SharedPreferences preferences = context.getSharedPreferences("NOMBRE DEL ARCHIVO DE PREFERENCIAS", Context.MODE_PRIVATE);
Algunas notas sobre el código anterior:
¿Cómo almaceno valores en las preferencias?
Para guardar datos, vamos a necesitar de un nuevo tipo de objeto llamado Editor, el cual se encarga de hacer esta tarea. Considerando el código anterior, y siguiendo, sería algo así:
Editor editor = preferences.edit(); editor.putInt("CANTIDAD", 35); editor.putString("RESPUESTA", "Serpiente"); editor.commit();
Acá hicimos lo siguiente:
¿Cómo leo los datos?
Para leer los datos que guardamos, solo debemos hacer lo siguiente (considerando que ya abrimos las preferencias anteriormente):
int cantidad = preferences.getInt("CANTIDAD", 0); String respuesta = preferences.getString("RESPUESTA", "");
Llamamos a los métodos getInt y getString entregándole 2 parámetros: La llave y un valor por defecto en caso de que no exista. Ya con eso podemos trabajar con los valores y volver a escribir sobre ellos de ser necesario.
¿Cómo valido si un dato existe en las preferencias?
Muy sencillo. La clase SharedPreferences cuenta con un método llamado contains, el cual nos retorna un booleano en caso de que el valor por el que preguntamos exista o no. Considerando nuestros ejemplos anteriores:
boolean existe = preferences.contains("CANTIDAD"); // retorna true boolean existe = preferences.contains("PATADA_DESCENDENTE"); // retorna false
El trabajo con preferencias en la app es bastante útil y por ello es algo que conviene aprender desde el comienzo, ya que nos servirá para muchas funcionalidades que tengamos planificadas.
Como siempre les recordamos que este tutorial ha sido desarrollado, probado y documentado por el equipo de CLH, por lo que cuenta con nuestro Sello de Garantía:
Cualquier consulta o comentario que puedan tener, los invitamos a dejarnos unas líneas en el área habilitada a continuación.
Esperamos que este tutorial haya sido de utilidad para Uds.
¡Hasta la próxima!
Las tardes gloriosas de domingo y las grandes ovaciones a estadio lleno, no son algo extraño para Xabadu. Luego de ser descubierto a los 4 años en un partido de barrio por los ojeadores del gran Aviación F.C., sacudió el mercado nacional al ser traspasado en $500 pesos chilenos (1 USD) y 3 coca colas al renombrado Estrella Blanca de Lolol. Luego de una impresionante carrera por equipos como Lozapenco, Santa Cruz, Deportivo Lago Chungará y una incursión en la 3a división del futbol de Kazajstan, su record imbatible hasta la fecha de 1257 goles en 20 partidos lo llevo a ser elegido como uno de los arqueros más recordados en la historia pelotera nacional. Una lesión en el colmillo superior derecho lo llevó al retiro el año 2003, pero está de vuelta y sin duda que su jerarquía y experiencia internacional será un gran aporte.
7:42:38 am
Excelente tutorial!! Estaría bueno en la cuarta entrega ejemplos para trabajar con bases de datos.
gracias!!
5:46:23 pm
Gracias Fernando!, en el próximo número hablaremos del desarrollo en distintos dispositivos, pero incorporaremos lo de las bases en el 5to.
Saludos!
12:44:55 am
Me sirve mucho. Sigo este tutorial al pie de la letra. Lo agradezco mucho.
10:56:27 am
Muy bueno tutorial!!
Gracias!
Espero el 4° capitulo!
8:48:03 am
Muy buen artículo. Explicado muy clarito y con ejemplos. Para cuando el cuarto?
10:39:52 pm
Graciassss por todo muy buen explicado se puede seguir superar fácil. Esperando nuevas entregas.
Felicitaciones
7:12:28 pm
Y ese codigo donde va, en la misma clase del tutorial anterior o se tiene que crear una nueva?
11:46:10 am
@diana: Este código sirve para cualquier caso donde lo necesites, ya sea una clase nueva o alguna que ya estás usando.
Saludos!