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
© 2011­2012 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
© 2011­2012 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 clave­valor
• 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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)
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 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
© 2011­2012 Depto. Ciencia de la Computación e IA
ContentProviders ­ 23
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
¿Preguntas...?
Persistencia
© 2011­2012 Depto. Ciencia de la Computación e IA
ContentProviders ­ 24

Documentos relacionados