|
Android: Guardar leer preferencias de configuración aplicación Android SharedPreferences
Explicamos cómo guardar la configuración de nuestra aplicación Android en un fichero xml y cómo leerla posteriormente. Para ello usaremos SharedPreferences de Android. Mostramos cómo usar el evento OnDestroy para guardar la configuración y el evento OnStart para cargarla. Mostramos el código fuente Java en Eclipse necesario para usar SharedPreferences y un ejemplo de una aplicación completa que usa esta clase: AjpdSoft Monitor Wifi Android.
Para qué es necesario usar un archivo de configuración en aplicaciones AndroidCuando desarrollamos aplicaciones para dispositivos Android, normalmente suelen usarse valores que el usuario ha de marcar o escribir, por ejemplo un correo electrónico, un número de teléfono, marcar algún CheckBox, o algún RadioButton. En estos casos es recomendable (para que la aplicación quede más "profesional") guardar estos valores en un fichero de configuración para que al abrir la aplicación el usuario tenga los últimos datos introducidos. Esto, en aplicaciones para dispositivos Android, es importante, pues es muy incómodo para el usuario volver a introducir los datos, normalmente los últimos datos que ha introducido suelen ser los que usará habitualmente. Obviamente, este tipo de ficheros de configuración sólo será necesario en estos cosos en lo que desarrollemos una aplicación Android que requiera de escribir y marcar opciones por parte del usuario, si no es así no nesitaremos tales ficheros. En este artículo explicaremos cómo guardar la configuración de una aplicación Android en un fichero XML usando la clase que incorpora Android llamada SharedPreferences. Veremos que es sencillo y el uso es muy parecido al de los ficheros INI de configuración de aplicaciones de Windows. Si lo que queremos es guardar datos tipo clientes, proveedores, contactos, facturas, productos, etc. con varios campos como teléfono, dirección, precio, etc. usaremos bases de datos SQLite, como explicamos en este artículo: Desarrollar aplicación Android con acceso a base de datos SQLite con Eclipse
Requisitos para hacer programas para dispositivos AndroidAntes de continuar, es recomendable revisar el siguiente manual, donde explicamos desde cero (paso a paso) como preparar un equipo Linux para desarrollar aplicaciones Android: Mi primera aplicación Android con Eclipse en Linux, instalar Eclipse Ubuntu
Clase SharedPreferences de AndroidIMPORTANTE: para poder usar la clase SharedPreferences en Android debemos añadir al principio de nuestra clase principal el import:
La clase SharedPreferences de Android permite a los desarrolladores usar sus métodos, funciones y procedimientos para leer y escribir en un fichero de configuración de aplicación Android. Las aplicaciones Android permiten guardar sus datos de configuración en uno (o varios) ficheros de tipo XML, ubicados dentro de la carpeta de instalación de la aplicación, en la subcarpeta shared_prefs. Esta clase proporciona opciones para permitir elegir el método de seguridad para el acceso a estos archivos de configuración. Las posibilidades son:
Leer valores de un fichero de preferencias de configuración de una aplicación AndroidLos métodos que proporciona la clase SharedPreferences para leer los datos del fichero de configuración XML son:
Hemos destacado en negrita las más usuales. Un ejemplo de lectura de un valor de tipo String en el fichero de preferencias "ficheroconfiguracion.xml" puede ser: String valorLeido; SharedPreferences prefs = getSharedPreferences("ficheroconfiguracion", Context.MODE_PRIVATE); valorLeido = prefs.getString("Dato guardado", "Prueba lectura xml configuración"); Explicamos el código anterior: 1. En primer lugar declaramos una variable de tipo String que será en la que guardaremos el valor leído del fichero de configuración. 2. Creamos la variable de tipo SharedPreferences haciendo una llama a "getSharedPreferences", le pasamos como parámetro a este procedimiento el nombre del fichero de configuración, en nuestro caso "ficheroconfiguracion" y el tipo de acceso "MODE_PRIVATE". 3. Por último llamamos al método "getString" para leer el valor de la preferencia "Dato guardado", si no encuentra este valor devolverá el valor por defecto "Prueba lectura xml configuración". De esta forma podremos leer cualquier valor y de cualquier tipo contenido en un fichero de preferencias de nuestra aplicación Android.
Guardar valores de configuración en un fichero de preferencias de una aplicación AndroidLos métodos que proporciona la clase SharedPreferences para guardar los datos en el fichero de configuración ó preferencias XML son:
Hemos destacado en negrita las más usuales. Un ejemplo de escritura de un valor de tipo String en el fichero de preferencias "ficheroconfiguracion.xml" puede ser: SharedPreferences prefs = getSharedPreferences("ficheroconfiguracion", Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putString("Mail", txtMail.getText().toString()); editor.commit(); Explicamos el código anterior: 1. Creamos la variable de tipo SharedPreferences haciendo una llama a "getSharedPreferences", le pasamos como parámetro a este procedimiento el nombre del fichero de configuración, en nuestro caso "ficheroconfiguracion" y el tipo de acceso "MODE_PRIVATE". 2. Declaramos una variable (objeto) de tipo SharedPreferences.Editor, necesario para guardar cambios en el fichero de preferencias. 3. Llamamos al método "putString" para guardar en la preferencia "Mail" el valor contenido en el componente visual TextEdit "txtMail". 4. Guardamos los cambios llamando al método "commit" del Editor. De esta forma podremos guardar cualquier valor y de cualquier tipo en un fichero de preferencias para uso de nuestra aplicación Android.
En qué eventos usar la clase SharedPreferences de Android onDestroy, onStartEsta clase puede ser usada en cualquier parte y momento de la aplicación, puede usarse al pulsar un botón o en otros eventos. Pero lo normal, puesto que se trata de parámetros de configuración de la aplicación, es usar los eventos onStart y onDestroy de la aplicación Android para leer y guardar respectivamente en el fichero de preferencias. Por ejemplo, cuando el usuario (o el propio disositivo Android) cierra la aplicación por que haya finalizado su uso (onDestroy), lo normal es guardar en este momento los parámetros de configuración. De la misma forma, cuando el usuario inicia la aplicación para usarla (onStart), en este momento, la aplicación leerá y cargará los parámetros de configuración. A continuación vamos a explicar cómo programar estos dos eventos para una aplicación Android. Como ejemplo para entender SharedPreferences, supongamos una aplicación que muestra el estado de conexión a la Wifi (IP, estado, SSID, BSSID, MAC) y permite al usuario guardar los datos obtenidos en un fichero de texto. En dicha aplicación permitimos al usuario elegir el nombre del fichero y la ubicación: en tarjeta de memoria (SDCard) o en la carpeta de la aplicación. En el ejemplo queremos guardar el valor del nombre del fichero (TextEdit txtFichero) y el valor de la ubicación (CheckBox opUbicacionFichero). De esta forma, cuando el usuario cierre la aplicación quedarán guardados estos datos y cuando abra la aplicación no tendrá que volver a escribir el nombre del fichero ni el tipo de ubicación. La aplicación en funcionamiento:
En primer lugar añadiremo el los imports la línea:
Crearemos un prodecimiento llamado guardarConfiguracion que escribirá los parámetros de configuración de nuestra aplicación en el fichero de preferencias: //guardar configuración aplicación Android usando SharedPreferences public void guardarConfiguracion() { SharedPreferences prefs = getSharedPreferences("AjpdSoftMonitorWifi", Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("GuardarSDCard", opUbicacionFichero.isChecked()); editor.putString("Fichero", txtFichero.getText().toString()); editor.commit(); } El procedimiento cargarConfiguracion para leer el fichero de preferencias y asignar los valores del txtFichero y el opUbicacionFichero será: //cargar configuración aplicación Android usando SharedPreferences public void cargarConfiguracion() { SharedPreferences prefs = getSharedPreferences("AjpdSoftMonitorWifi", Context.MODE_PRIVATE); txtFichero.setText(prefs.getString("Fichero", "wifi.txt")); opUbicacionFichero.setChecked(prefs.getBoolean("GuardarSDCard", true)); } A continuación crearemos los eventos onStart (al iniciar la aplicación Android) y onDestroy (al cerrar la aplicación Android): //en el evento "Cerrar aplicación" guardar los datos en fichero xml @Override public void onDestroy() { super.onDestroy(); guardarConfiguracion(); } //en el evento "Abrir aplicación" leemos los datos de configuración del fichero xml @Override protected void onStart() { super.onStart(); cargarConfiguracion(); } Aquí podéis ver el código fuente completo de la aplicación.
Formato del fichero XML creado por SharedPreferencesEl fichero xml resultante de usar SharedPreferences tendrá el siguiente formato (mostramos el contenido de un fichero de ejemplo de una aplicación real): <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="Fichero">wifi.txt</string> <boolean name="GuardarSDCard" value="true" /> </map> Como se puede observar, SharedPreferences de Android guardará cada valor de preferencia en una línea, por un lado el keyvalue (identificador de clave, en el ejemplo "Fichero" y "GuardarSDCard") y por otro lado el value (valor de cada clave, en el ejemplo "wifi.txt" y "true"). También guardará el tipo de dato de la clave: boolean, string, int, long, float. En el emulador de Eclipse, el fichero puede verse y consultarse en:
Este fichero será eliminado automáticamente cuando se desintale la aplicación.
Código fuente completo de una aplicación Android que guarda y lee valores del fichero de preferenciasA continuación mostramos el código fuente completo de la aplicación Android AjpdSoft Monitor Wifi Android que obtiene y muestra datos de la conexión Wifi de nuestro dispositivo. En esta aplicación usamos la clase SharedPreferences para guardar y cargar algunos valores de configuración:
package MonitorWifi.wifi; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Environment; import android.widget.TextView; import android.widget.Button; import android.view.View; import java.io.OutputStreamWriter; import android.widget.Toast; import android.widget.EditText; import java.io.File; import java.io.FileOutputStream; import android.widget.CheckBox; public class MonitorWifi extends Activity { TextView textEstado, textIP, textSSID, textSIDOculto; TextView textBSSID, textMAC, textVelocidad, textRSSI; EditText txtFichero; CheckBox opUbicacionFichero; private Button buttonRefrescar; private Button buttonCerrar; private Button buttonGuardar; private String infoIP, infoSSID, infoBSSID, infoSSIDOculto, infoEstado, infoRSSID, infoMAC, infoVelocidad; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Asignamos a cada objeto visual creado a su //respectivo elemento de main.xml textEstado = (TextView)findViewById(R.id.txtEstado); textIP = (TextView)findViewById(R.id.txtIP); textSSID = (TextView)findViewById(R.id.txtSSID); textSIDOculto = (TextView)findViewById(R.id.txtSSIDOculto); textBSSID = (TextView)findViewById(R.id.txtBSSID); textMAC = (TextView)findViewById(R.id.txtMAC); textVelocidad = (TextView)findViewById(R.id.txtVelocidad); textRSSI = (TextView)findViewById(R.id.txtRSSI); buttonRefrescar = (Button) findViewById(R.id.btRefrescar); buttonCerrar = (Button) findViewById(R.id.btCerrar); buttonGuardar = (Button) findViewById(R.id.btGuardar); txtFichero = (EditText) findViewById(R.id.txtFichero); opUbicacionFichero = (CheckBox) findViewById(R.id.opUbicacionFichero); //Botón para volver a comprobar el estado de la wifi buttonRefrescar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //Volver a comprobar datos wifi mostrarEstadoWifi(); } }); //Botón para guardar datos en fichero buttonGuardar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //si el usuario selecciona Guardar en Tarjeta SDCard if (opUbicacionFichero.isChecked()) { String estadoSDCard = Environment.getExternalStorageState(); boolean almacenamientoExternoDisponible = false; boolean almacenamientoExternoEscribible = false; if (Environment.MEDIA_MOUNTED.equals(estadoSDCard)) { almacenamientoExternoDisponible = almacenamientoExternoEscribible = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(estadoSDCard)) { almacenamientoExternoDisponible = true; almacenamientoExternoEscribible = false; } else { almacenamientoExternoDisponible = almacenamientoExternoEscribible = false; } if (almacenamientoExternoEscribible == true & almacenamientoExternoDisponible == true) { String carpetaSDCard = Environment.getExternalStorageDirectory().getAbsolutePath(); File carpetaWifi = new File (carpetaSDCard + "/MonitorWifi"); carpetaWifi.mkdirs(); String rutaFichero = carpetaWifi + File.separator + txtFichero.getText().toString(); try { //NO FUNCIONA AÚN, USAR //FALTA CODIGO PARA GUARDAR EN FICHERO Toast.makeText(getApplicationContext(), "Datos Wifi guardados en fichero: " + rutaFichero, Toast.LENGTH_SHORT).show(); } catch (Exception ex) { //error, mostrar mensaje Toast.makeText(getApplicationContext(), "Error: " + ex.getMessage() + " " + rutaFichero, Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(getApplicationContext(), "Error: tarjeta SD no disponible o no escribible", Toast.LENGTH_SHORT).show(); } } else { //para guardar en carpeta de aplicación String rutaFichero = txtFichero.getText().toString(); try { OutputStreamWriter fichero = new OutputStreamWriter( openFileOutput(rutaFichero, Context.MODE_WORLD_WRITEABLE)); fichero.write(infoIP + infoSSID + infoBSSID + infoSSIDOculto + infoEstado + infoRSSID + infoMAC + infoVelocidad); fichero.flush(); fichero.close(); Toast.makeText(getApplicationContext(), "Datos Wifi guardados en fichero: " + rutaFichero, Toast.LENGTH_SHORT).show(); } catch (Exception ex) { //error, mostrar mensaje Toast.makeText(getApplicationContext(), "Error: " + ex.getMessage() + " " + rutaFichero, Toast.LENGTH_SHORT).show(); } } } }); //Botón para cerrar aplicación Android buttonCerrar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } }); //llamamos al método para mostrar los datos de la wifi mostrarEstadoWifi(); this.registerReceiver(this.myWifiReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } //en el evento "Cerrar aplicación" guardar los datos en fichero xml @Override public void onDestroy() { super.onDestroy(); guardarConfiguracion(); } //en el evento "Abrir aplicación" leemos los datos de //configuración del fichero xml @Override protected void onStart() { super.onStart(); cargarConfiguracion(); } //Evento que se produce si cambia el estado de conexión de la Wifi //con este evento, los datos de conexión se actualizarán en la aplicación //automáticamente al cambiar el estado de la Wifi private BroadcastReceiver myWifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent arg1) { // Auto-generated method stub NetworkInfo networkInfo = (NetworkInfo) arg1.getParcelableExtra( ConnectivityManager.EXTRA_NETWORK_INFO); if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { mostrarEstadoWifi(); } } }; //lee el estado de la Wifi en dispositivos Android y muestra el resultado private void mostrarEstadoWifi() { ConnectivityManager mAdministradorConexion = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo mInformacionRed = mAdministradorConexion.getNetworkInfo(ConnectivityManager.TYPE_WIFI); WifiManager mAdministradorWifi = (WifiManager)getSystemService(Context.WIFI_SERVICE); WifiInfo mInformacionWifi = mAdministradorWifi.getConnectionInfo(); if (mInformacionRed.isConnected()) { int myIp = mInformacionWifi.getIpAddress(); int intMyIp3 = myIp/0x1000000; int intMyIp3mod = myIp%0x1000000; int intMyIp2 = intMyIp3mod/0x10000; int intMyIp2mod = intMyIp3mod%0x10000; int intMyIp1 = intMyIp2mod/0x100; int intMyIp0 = intMyIp2mod%0x100; infoIP = "IP: " + String.valueOf(intMyIp0) + "." + String.valueOf(intMyIp1) + "." + String.valueOf(intMyIp2) + "." + String.valueOf(intMyIp3); infoEstado = "Estado: Conectado a red Wifi"; infoVelocidad = String.valueOf("Velocidad: " + mInformacionWifi.getLinkSpeed()) + " " + WifiInfo.LINK_SPEED_UNITS; infoSSID = "SSID: " + mInformacionWifi.getSSID(); infoBSSID = "BSSID: " + mInformacionWifi.getBSSID(); infoRSSID = "RSSI: " + mInformacionWifi.getRssi(); infoMAC = "MAC: " + mInformacionWifi.getMacAddress(); if (!mInformacionWifi.getHiddenSSID()) infoSSIDOculto = "SID oculto: No"; else infoSSIDOculto = "SID oculto: Sí"; textIP.setText(infoIP); textEstado.setText(infoEstado); textVelocidad.setText(infoVelocidad); textSSID.setText(infoSSID); textSIDOculto.setText(infoSSIDOculto); textBSSID.setText(infoBSSID); textRSSI.setText(infoRSSID); textMAC.setText(infoMAC); } else { infoIP = "IP: --"; infoEstado = "Estado: No conectado a Red Wifi"; infoVelocidad = "Velocidad: --"; infoSSID = "SSID: --"; infoSSIDOculto = "SSID oculto: --"; infoBSSID = "BSSID: --"; infoRSSID = "RSSI: --"; infoMAC = "MAC: --"; textEstado.setText(infoEstado); textIP.setText(infoIP); textVelocidad.setText(infoVelocidad); textSSID.setText(infoSSID); textSIDOculto.setText(infoSSIDOculto); textBSSID.setText(infoBSSID); textRSSI.setText(infoRSSID); textMAC.setText(infoMAC); } } //guardar configuración aplicación Android usando SharedPreferences public void guardarConfiguracion() { SharedPreferences prefs = getSharedPreferences("AjpdSoftMonitorWifi", Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("GuardarSDCard", opUbicacionFichero.isChecked()); editor.putString("Fichero", txtFichero.getText().toString()); editor.commit(); } //cargar configuración aplicación Android usando SharedPreferences public void cargarConfiguracion() { SharedPreferences prefs = getSharedPreferences("AjpdSoftMonitorWifi", Context.MODE_PRIVATE); txtFichero.setText(prefs.getString("Fichero", "wifi.txt")); opUbicacionFichero.setChecked(prefs.getBoolean("GuardarSDCard", true)); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Obtiene datos Wifi conectado dispositivo Android" android:layout_marginTop="10sp" /> <View android:layout_marginTop="10sp" android:layout_width="fill_parent" android:layout_height="3px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtEstado" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Estado:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtIP" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Dirección IP:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtVelocidad" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Velocidad:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtSSID" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="SSID:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtSSIDOculto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="SSID Oculto:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtBSSID" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="BSSID:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtRSSI" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Rssi:" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#e0e0e0"/> <TextView android:id="@+id/txtMAC" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="MAC:" /> <View android:layout_width="fill_parent" android:layout_height="3px" android:background="#e0e0e0"/> <TableLayout android:id="@+id/recipeButtons" android:background="#B0B0B0" android:padding="3dip" android:stretchColumns="0,1" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TableRow android:gravity="center"> <EditText android:text="Fichero" android:layout_height="wrap_content" android:layout_width="100px" android:id="@+id/txtFichero" android:hint="nombre fichero destino" android:inputType="text" android:maxLines="1" > </EditText> <CheckBox android:text="SD" android:id="@+id/opUbicacionFichero" android:layout_width="wrap_content" android:layout_height="wrap_content"> android:hint="Guardar en tarjeta SD" </CheckBox> <Button android:id="@+id/btGuardar" android:text="Guardar" /> </TableRow> </TableLayout> <TableLayout android:id="@+id/recipeButtons" android:background="#B0B0B0" android:padding="3dip" android:stretchColumns="0,1" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TableRow android:gravity="center"> <Button android:id="@+id/btRefrescar" android:text="Refrescar" /> <Button android:id="@+id/btCerrar" android:text="Cerrar" /> </TableRow> </TableLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="MonitorWifi.wifi" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MonitorWifi" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest> La descarga del código fuente completo y el fichero apk de esta aplicación Android (en Eclipse): Artículos relacionados
CréditosArtículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft. Anuncios
Enviado el Miércoles, 27 julio a las 15:18:34 por ajpdsoft
|
|