traspas
Transcripción
traspas
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Persistencia Sesión 2: Shared Preferences y proveedores de contenidos en Android © 20112012 Depto. Ciencia de la Computación e IA Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Puntos a tratar • Shared Preferences • Guardar y leer Shared Preferences • Actividades de preferencias • SharedPreferenceChangeListener • Proveedores de contenidos • Proveedores nativos • Proveedores propios • Content Resolvers Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 2 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Shared Preferences • Una de las técnicas de persistencia más simples en Android junto con los archivos • Basado en pares clavevalor • Posibles usos • Preferencias u opciones de la aplicación (el más habitual) • Almacenar estado de la interfaz gráfica • Comunicación entre actividades • Privados • Nunca compartidos entre diferentes aplicaciones • Almacenamiento de datos con la clase SharedPreferences • Booleanos, cadenas, enteros, etc. Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 3 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Guardar Shared Preferences • Obtener objeto SharedPreferences a partir del contexto de la aplicación mediante getSharedPreferneces // Obtenemos un editor para modificar las preferencias SharedPreferences.Editor editor = misSharedPreferences.edit(); // Guardamos nuevos valores en el objeto SharedPreferences editor.putBoolean("isTrue",true); editor.putFloat("unFloat",1.0); editor.putInt("numeroEntero",12); editor.putLong("otroNumero",2); editor.putString("unaCadena","valor"); // Guardamos los cambios editor.commit(); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 4 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Leer Shared Preferences • Diferentes métodos get para diferentes tipos de datos • Parámetros • Cadena identificativa de la clave • Valor por defecto public static String MIS_PREFS = "MIS_PREFS"; public void cargarPreferences() { // Obtener las preferencias almacenadas int modo = Activity.MODE_PRIVATE; SharedPreferences misSharedPreferences = getSharedPreferences(MIS_PREFS, modo); boolean isTrue = misSharedPreferences.getBoolean("isTrue",false); float unFloat = misSharedPreferences.getFloat("unFloat",0); int numeroEntero = misSharedPreferences.getInt("numeroEntero",0); long otroNumero = misSharedPreferences.getLong("otroNumero",0); String unaCadena = misSharedPreferences.getString("unaCadena",""); } Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 5 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Shared Preferences – interfaz gráfica • Plataforma basada en XML • Aspecto homogéneo con respecto al resto de aplicaciones del sistema • Elementos • Layout de la actividad de preferencias • Actividad de preferencias • Shared Preference Change Listener Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 6 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Layout de preferencias • Diferencias con layouts normales • Archivo XML guardado en /res/xml/ (y no en /res/layout/) • Componentes específicos • Elementos <?xml version="1.0" encoding="utf-8"?> • <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Mi categoría"> <CheckBoxPreference android:key="MI_CHECK_BOX" android:title="Preferencia Check Box" android:summary="Descripción de la preferencia Check Box" android:defaultValue="true" /> </PreferenceCategory> </PreferenceScreen> Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 7 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Layout de preferencias • Controles nativos • • • • CheckBoxPreference EditTextPreference ListPreference RingTonePreference • Posibilidad de componentes propios con subclases de Preference Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 8 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Actividad de preferencias • Definición • Subclase de PreferenceActivity • En onCreate, incluir: addPreferencesFromResource(R.xml.milayout); • Añadir al Manifest, como el resto de actividades • Uso • Lanzar con un Intent, como el resto de actividades • Valores almacenados en el contexto de la aplicación • Por lo tanto, se pueden obtener desde cualquier componente de la misma: Context contexto = getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(contexto); // PENDIENTE: hacer uso de métodos get para obtener los valores Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 9 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Shared Preference Change Listener • Interfaz que lanza un evento cuando una preferencia es modificada public class MiActividad extends Activity implements OnSharedPreferenceChangeListener { @Override public void onCreate(Bundle SavedInstanceState) { // Registramos este objeto OnSharedPreferenceChangeListener Context contexto = getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(contexto); prefs.registerOnSharedPreferenceChangeListener(this); } public void onSharedPreferenceChanged(SharedPreferences prefs, String clave) { // PENDIENTE: comprobar qué clave concreta ha cambiado y su nuevo // valor para modificar la interfaz de una actividad o el // comportamiento de algún componente } } Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 10 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Proveedores de contenidos • Interfaz estándar para publicar y consumir datos • Identificación de la fuente de datos mediante una URI • Dos tipos: • Nativos: proporcionados por el sistema para acceder a información del dispositivo • Propios: permiten a nuestra aplicación compartir información con el resto del sistema Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 11 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Proveedores de contenidos nativos • Ejemplos: Browser, CallLog, ContactsContract, MediaStore, Settings... • Necesario añadir permisos en el Manifest • Ejemplo: contactos <uses-permission android:name="android.permission.READ_CONTACTS"/> • Acceso a los datos del proveedor mediante un ContentResolver ContentResolver cr = getContentResolver(); Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); Persistencia ContentResolver.query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 12 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Notificación de cambios • Asociamos campos del cursor con elementos de la interfaz por medio de un adaptador ListView lv = (ListView)findViewById(R.id.ListView01); SimpleCursorAdapter adapter = new SimpleCursorAdapter( getApplicationContext(), R.layout.textviewlayout, cursor, new String[]{ ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, new int[]{ R.id.TextView1, R.id.TextView2}); lv.setAdapter(adapter); • Reaccionar ante la notificación de cambios cursor.setNotificationUri(cr, ContactsContract.Contacts.CONTENT_URI); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 13 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Proveedores de contenidos propios • Subclase de ContentProvider • Sobrecargamos onCreate para inicializar la fuente de datos (normalmente una base de datos SQLite) public class MiProveedor extends ContentProvider { @Override public boolean onCreate() { // Inicializar la base de datos return true; } } • Proporcionamos una URI publica: content://[NOMBRE_PAQUETE].provider.[NOMBRE_APLICACION]/[RUTA_DATOS] • Dos alternativas (patrón UriMatcher para determinar tipo petición) • Consulta múltiple: content://es.ua.jtech.miaplicacion/elementos • Consulta única: content://es.ua.jtech.miaplicacion/elementos/5 Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 14 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles UriMatcher public class MiProveedor extends ContentProvider { private static final String miURI = "content://es.ua.jtech.android.provider.miaplicacion/elementos"; public static final Uri CONTENT_URI = Uri.parse(miUri); @Override public boolean onCreate() { … } private static final int TODAS_FILAS = 1; private static final int UNA_FILA = 2; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI("es.ua.jtech.android.provider.miaplicacion", "elementos",TODAS_FILAS); uriMatcher.addURI("es.ua.jtech.android.provider.miaplicacion", "elementos/#",UNA_FILA); } } Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 15 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Interfaz de consultas 1 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) { switch(UriMatcher.match(uri)) { case UNA_FILA: // numeroFila = uri.getPathSegments().get(1)); } return null; } @Override public Uri insert(Uri _uri, ContentValues _valores) { long idFila = [ ... Añadir un nuevo elemento ... ] if (idFila > 0) return ContentUris.withAppendendId(CONTENT_URI, idFila); throw new SQLException("No se pudo añadir un nuevo elemento a " + _uri); } Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 16 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Interfaz de consultas 2 @Override public int delete(Uri uri, String where, String[] whereArgs) { switch(uriMatcher.match(uri)) { case TODAS_FILAS: case UNA_FILA: default: throw new IllegalArgumentException("URI no soportada: " + uri); } } @Override public int update(Uri uir, ContentValues valores, String where, String[] whereArgs) { switch(uriMatcher.match(uri)) { case TODAS_FILAS: case UNA_FILA: default: throw new IllegalArgumentException("URI no soportada: " + uri); } } Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 17 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Últimos pasos • Sobrecargar getType para devolver identificador del tipo de datos manejado por nuestro proveedor de contenidos @Override public String getType(Uri _uri) { switch (uriMatcher.match(_uri)) { case TODAS_FILAS: return "vnd.es.ua.jtech.android.cursor.dir/miproveedorcontent"; case UNA_FILA: return "vnd.es.ua.jtech.android.cursor.item/miproveedorcontent"; default: throw new IllegalArgumentException("URI no soportada: " + _uri); } } • Registrar el proveedor de contenidos en el Manifest <provider android:name="MiProveedor" android:authorities="es.ua.jtech.android.miaplicacion"/> Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 18 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Content Resolvers • El contexto de la aplicación siempre almacena una instancia de la clase ContentResolver • Función: operar con proveedores de contenidos • getContentResolver – requiere una URI como parámetro • Parámetros método query • • • • • Persistencia La URI del proveedor de contenidos Proyección: columnas a incluir en los resultados Cláusula where Matriz de cadenas: argumentos para la cláusula anterior Cadena que describa la ordenación de los elementos © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 19 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Content Resolvers • Ejemplo ContentResolver cr = getContentResolver(); // Devolver todas las filas Cursor todasFilas = cr.query(MiProveedor.CONTENT_URI, null, null, null, null); // Devolver todas columnas de las filas para las que la columna 3 // tiene un valor determinado, ordenadas según el valor de la columna 5 String where = COL3 + "=" + valor; String orden = COL5; Cursor algunasFilas = cr.query(MiProveedor.CONTENT_URI, null, where, null, orden); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 20 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Inserción // Obtener el Content Resolver ContentResolver cr = getContentResolver(); // Crear una nueva fila de valores a insertar ContentValues nuevosValores = new ContentValues(); // Asignar valores a cada columna nuevosValores.put(NOMBRE_COLUMNA, nuevoValor); [ ... Repetir para cada columna ... ] Uri miFilaUri = cr.insert(MiProveedor.CONTENT_URI, nuevosValores); // Insertamos ahora una matriz de nuevas filas ContentValues[] arrayValores = new ContentValues[5]; // PENDIENTE: rellenar el array con los valores correspondientes int count = cr.bulkInsert(MiProveedor.CONTENT_URI, arrayValores); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 21 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Borrado ContentResolver cr = getContentResolver(); // Eliminar una fila específica cr.delete(miFilaUri, null, null); // Eliminar las primeras cinco filas String where = "_id < 5"; cr.delete(MiProveedor.CONTENT_URI, where, null); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 22 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Actualización ContentValues nuevosValores = new ContentValues(); // Utilizamos el objeto ContentValues para especificar en qué columnas // queremos que se produzca un cambio, y cuál debe ser el nuevo valor // de dichas columnas nuevosValues.put(NOMBRE_COLUMNA, nuevoValor); // Aplicamos los cambios a las primeras cinco filas String where = "_id < 5"; getContentResolver().update(MiProveedor.CONTENT_URI, nuevosValores, where, null); Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 23 Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles ¿Preguntas...? Persistencia © 20112012 Depto. Ciencia de la Computación e IA ContentProviders 24