martes, 7 de octubre de 2014

Content Provider

Un Content Provider es el mecanismo proporcionado por la plataforma Android para permitir compartir información entre aplicaciones. Una aplicación que desee que toda o parte de la información que gestiona esté disponible de una forma controlada, homogénea y estandarizada para el resto de aplicaciones del sistema deberá proporcionar un Content Provider. Este mecanismo es utilizado por muchas de las aplicaciones estándar de un dispositivo Android, como por ejemplo la lista de contactos o el calendario.

Compatibilidad

v1

Lo mínimo necesario

Una clase que herede de ContentProvider
public class UsuarioProvider extends ContentProvider{
      
       //Tabla de la Base de datos
       private static final String TABLA = "Usuario";
       //Autoridad del Provider, debe coincidir con el Manifest
       public static final String AUTHORITY = "es.hubiqus.contentp";
            
       //Auxiliar: operaciones con la base de datos
       private DBOpenHelper dbOpen;

       //Definición del CONTENT_URI base
       public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/" + TABLA);
            
       //UriMatcher
       private static final int USUARIO = 1;
       private static final int USUARIO_ID = 2;
       private static final UriMatcher uriMatcher;
            
       //Inicializar el UriMatcher
       static {
             uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
             //Acceso genérico a la tabla
//ej: content://es.hubiqus.contentp/Usuario"
             uriMatcher.addURI(AUTHORITY, TABLA, USUARIO);
             //Acceso directo a un usuario
//ej: content://es.hubiqus.contentp/Usuario/1"
             uriMatcher.addURI(AUTHORITY, TABLA + "/#", USUARIO_ID);
       }
            
       //Clase interna para declarar las constantes de columna
       public static final class Columns implements BaseColumns {
             private Columns() {}
            
             //Nombres de columnas
             public static final String COL_ID = "id";
             public static final String COL_USER = "usuario";
public static final String COL_PASS = "clave";
       }

     @Override
       public boolean onCreate() {      
       this.dbOpen =
DBOpenHelper.getInstance(this.getContext());
             return true;
       }

       //Operaciones

@Override
       public Cursor query(Uri uri, String[] projection,
       String selection, String[] args, String sortOrder) {       
       //Si es una consulta a un ID concreto construir el WHERE
            String where = selection;
             if (uriMatcher.match(uri) == PROVINCIA_ID) {
where = "id=" + uri.getLastPathSegment();
             }

             SQLiteDatabase db = dbOpen.getWritableDatabase();
             Cursor c = db.query(TABLA, projection, where,
                                   selectionArgs, null, null, sortOrder);
                   
             return c;
       }
            
       @Override
       public Uri insert(Uri uri, ContentValues values) {
             long regId = -1;
                   
             SQLiteDatabase db = dbOpen.getWritableDatabase();    
             regId = db.insert(TABLA, null, values);
                   
             return ContentUris.withAppendedId(CONTENT_URI, regId);
       }

            
       @Override
       public int update(Uri uri, ContentValues values,
String selection, String[] selectionArgs) {
             //Si es una consulta a un ID concreto construir el WHERE
             String where = selection;
             if (uriMatcher.match(uri) == USUARIO_ID){
                    where = "id=" + uri.getLastPathSegment();
             }
                   
             SQLiteDatabase db = dbOpen.getWritableDatabase();    

             return db.update(TABLA, values, where, selectionArgs);
       }
            
       @Override
       public int delete(Uri uri, String selection, String[] args) {            
             //Si es una consulta a un ID concreto construir el WHERE
             String where = selection;
             if (uriMatcher.match(uri) == USUARIO_ID){
               where = "_id=" + uri.getLastPathSegment();
             }
                   
             SQLiteDatabase db = dbOpen.getWritableDatabase();
                   
             return db.delete(TABLA, where, selectionArgs);
       }

       @Override
       public String getType(Uri uri) {
                   
             int match = uriMatcher.match(uri);
                   
             //Devuelve el tipo MIME en función de la URI solicitada
             switch (match) {
       case USUARIO:
return "vnd.android.cursor.dir/vnd.hubiqus.contentp.usuario";
                      
             case USUARIO_ID:                 
return "vnd.android.cursor.item/vnd.hubiqus.contentp.usuario";
                                       
             default:
          return null;
             }
       }

}

Declarar el Content Provider en el Manifest.
<provider android:name="es.hubiqus.sqlite.data.UsuarioProvider"
                    android:authorities="es.hubiqus.contentp"/>

Clientes de Content Provider

Para poder utilizar el Content Provider desde otra aplicación habrá que invocarlo con la URI declarada para el mismo:
private static final String
CONTENT_URI = "content://es.hubiqus.contentp/Usuario";
      
public List<Usuario> listar() {
       List<Usuario> res = new ArrayList<Usuario>();

       Cursor c = null;
            
       try {
ContentResolver client = context.getContentResolver();
String[] columnas = { "id", "user" };
      
c = client.query(Uri.parse(CONTENT_URI), columnas,
null, null, null);
            

       } catch (Exception ex){
             ex.printStackTrace();
       } finally {
             if (c != null) {
                    c.close();
             }
                   
       }

       return res;
}

En Android existen una serie de Content Providers nativos para permitir acceso a información del sistema de forma estandarizada (agenda, diccionario, galería, …). En este caso el acceso se realiza de una forma similar, simplemente es necesario conocer qué tipo de Content Provider se va a emplear, y establecer los permisos necesarios en el Manifest:
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>

public List<String> listar() {
       List<String> res = new ArrayList<String>();

       Cursor c = null;
            
       try {
       String[] columnas = { UserDictionary.Words.WORD };
             c = client.query(UserDictionary.Words.CONTENT_URI,
columnas, null, null, null);
                   
             …

       } catch (Exception ex){
             ex.printStackTrace();
       } finally {
             if (c != null) {
                    c.close();
             }
                   
       }

       return res;
}


Referencias

http://developer.android.com/guide/topics/providers/content-provider-creating.html

No hay comentarios:

Publicar un comentario