miércoles, 11 de enero de 2012

5.7.- Programación Android - Contador con SharedPreferences

- no title specified
5.7.- Programación en Android: Contador con SharedPreferences

En este capítulo veremos como hacer un contador de las veces que ejecutamos nuestra aplicación y como utilizar la clase SharedPreferences para guardar y recuperar datos simples de la aplicación, como pueden ser datos de configuración o en este caso, un contador de las veces que se ha ejecutado la aplicación. También veremos como acceder a un elemento del layout (diseño ui) y como modificarlo.

Con el uso de la clase SharedPreferences podemos tener los datos clasificados en distintos ficheros, o podemos ponerlo todo en uno solo. Partiendo de nuestro programa de ejemplo HolaMundoAndroid, vamos a proceder a modificarlo para hacer nuestro sencillo contador, no os espereis nada complicado ni avanzado ya que esto es sólo con el objeto de romper el hielo, y ya veremos el uso de esta clase en profundidad más adelante.  Si no habeis realizado el proyecto anterior, podeis bajarlo de aqui (mirar al final), contiene el código utilizado para ver los estados de la actividad, y partiremos de él.
Crearemos una cadena (String), en el fichero de recursos que contendrá el nombre del fichero que utilizaremos para nuestras preferencias.  Para ello en el fichero strings.xml añadimos un nuevo valor string que tendrá el nombre del fichero SharedPreferences.  En este ejemplo le hemos llamado fichero_contador a la variable, y "ContadorEjecuciones" al archivo de preferencias.  Esta cadena sólo la definiremos en values, y no en values-es ya que si no la encuentra en los recursos localizados, entonces lo coge del recurso por defecto, que es string.xml de la carpeta values.


Realizado esto vamos a añadir un método a nuestra clase HolaAndroidActivity, a este método lo llamaremos CargarContador(), y devolverá un valor int que será el número de veces que se halla ejecutado el programa.
Para ello creamos el objeto ficheroSP y lo derivamos de la clase SharedPreferences.  Y haciendo uso de la función getSharedPreferences(nombrefichero, modoapertura), cogemos el contenido del fichero.
int icontador = 0; // Contador del número de ejecuciones.
SharedPreferences ficheroSP = getSharedPreferences(
        getString(R.string.fichero_contador), MODE_PRIVATE);
        // MODE_PRIVATE: Sólo nuestra aplicación tiene acceso a estas preferencias.
        // MODE_WORLD_READABLE: Todas las apps. pueden leerlas, pero solo la nuestra cambiarlas
        // MODE_WORLD_WRITABLE: Todas las apps. pueden leerlas y escribirlas.
        // MODE_MULTI_PROCESS: (AND2.3) Varios procesos pueden acceder.
Una vez realizado esto, comprobamos si hemos guardado antes ese valor, utilizando el método contains(String Clave),  y si es así cogemos el valor con getInt(String Clave, valor por defecto).  El valor por defecto es el valor que devolverá en caso de no existir esa clave.
if (ficheroSP.contains("Contador") == true) {
        // Cogemos el valor de "Contador". Si no existe, devuelve 0
        icontador = ficheroSP.getInt("Contador", 0);
        Log.d("HolaAndroidActivity", "CargarContador, en IF");
}
En el ejemplo, sigo haciendo uso del Log, para reportar en que parte del programa me encuentro.  Normalmente, esto lo haría de forma condicional, dependiendo del valor de una variable debug, así alterando el valor de esta variable, quitaría o pondría los logs.
Una vez hecho esto incrementamos el valor del contador, y procedemos a actualizar el fichero de preferencias.  Debemos entonces crear un interface Editor, para así crear o modificar los valores.  Una vez hecho, ponemos el valor en el fichero, primero la clave (String) y despues el valor, en este caso un entero.  Cuando hallamos terminado de poner los valores, debemos actualizar el fichero, para lo cuál hacemos uso del método commit() o también podríamos utilizar apply().
// Para crear o modificar el valor, hacemos uso del interface SharedPreferences.Editor
SharedPreferences.Editor ficheroSPEditor = ficheroSP.edit();
// Ahora creamos/modificamos el par, Nombrevariable-valor
ficheroSPEditor.putInt("Contador", icontador);
// Ahora aplicamos estos cambios
ficheroSPEditor.commit(); // Actualizamos los campos.(o .apply();
Al salír de la función, simplemente retornamos el valor que tenemos en la variable icontador. (return icontador;)
Debemos añadir la llamada a esta función en onCreate(), y así obtener el valor del contador.
Hasta aquí hemos obtenido el valor y lo actualizamos con cada ejecución, nos falta modificar el layout para poder mostrar el valor.  Como anteriormente estuvimos creando nuestra aplicación en dos idiomas, pues ahora vamos a crear una cadena de texto en strings.xml que será el título del contador.  Debemos crear el recurso tanto para español como para el lenguaje por defecto.  Le llamaremos contador, y el valor será "Contador:" para español y "Counter:" para inglés.

Abrimos el layout main.xml, y procedemos a añadirle varios widgets de tipo TextView.  En este caso he probado a meterlos con distintos tamaños (para ir trasteando).  El primero será el que contenga el string localizado para "contador", y lo hacemos ajustanto el campo Text de las propiedades del widget y que apunte al recurso de nuestra cadena: @string/contador
Después añadimos tres TextViews más, que serán los que contengan el número de veces que ejecutamos la aplicación.  Puse tres porque veremos tres formas distintas de convertir un valor int a string.  A estos widgets se le han asignado los siguientes Ids:  tV_contador1, tV_contador2 y tV_contador3. Estos identificadores de los recursos se pueden cambiar en la ventana de propiedades, en la etiqueta Id.

Más adelante describiremos como modificar el layout y organizar los elementos de otra forma, de momento para este ejemplo no vamos a liar más las cosas.

Bien, tenemos los recursos, tenemos las cadenas, tenemos la función que nos contará las ejecuciones... ahora tenemos que implementar el código que altere estos widgets para poner el contador con su valor correspondiente.
Añadimos el siguiente código a onCreate() después de la línea setContentView(...):

int cont;  //Valor que albergará el número de ejecuciones de la aplicación.
cont=CargarContador();
       
TextView txtcontador= (TextView)findViewById(R.id.tV_contador1);
TextView txtcontador2= (TextView)findViewById(R.id.tV_contador2);
TextView txtcontador3= (TextView)findViewById(R.id.tV_contador3);
//Forma "artesana" de convertirlo a string. ;)
txtcontador.setText(cont+"");  
//Forma correcta de convertir el valor en cadena:
txtcontador2.setText(String.valueOf(cont));
//O también podríamos utilizar el método toString del objeto Integer
txtcontador3.setText(Integer.toString(cont));
Ahí podemos ver los tres ejemplos, con tres formas distintas de convertir el entero a cadena.  Y ya estamos listos para poder depurar nuestra aplicación y ver si cuenta o no cuenta.  Le damos a depurar y vemos como nos da la salida.  Si queremos ejecutarlo otra vez, salimos con la flecha atras, y desde el emulador en aplicaciones lo volvemos a ejecutar, y vemos como va incrementando el contador.
Ahora, en la vista DDMS, en el explorador de ficheros, podemos ir a: data->data->com.blogspot.pafh99.cursoandroid.holaandroid->shared_prefs y ahí vemos como nos ha creado el fichero ContadorEjecuciones.xml. Que es dónde estamos almacenando nuestros valores.


Si quereis bajar el código completo de lo que hemos hecho, pulsar aqui.
Nota:  Por alguna extraña razón, el Eclipse, o el plugin de android me cambian los acentos inclúso de los comentarios o de las cadenas de texto.  Tengo los xml como UTF-8  y no sé a qué es debido, si alguien sabe como solucionarlo se lo agradecería.


Ver. 1.0 – Revisión 11.1.2012

No hay comentarios:

Publicar un comentario