Utilizando la clase ContentProvider

Los proveedores de contenidos (content providers) son uno de los bloques constructivos más importantes de Android. Nos van a permitir acceder a información proporcionada por otras aplicaciones, o a la inversa, compartir nuestra información con otras aplicaciones.

Tras describir los principios en los que se basan los ContentProviders, pasaremos a demostrar como acceder a ContentProviders creados por otras aplicaciones. Esta operación resulta muy útil dado que te permitirá tener acceso a información interesante, como la lista de contactos, el registro de llamadas o los ficheros multimedia almacenados en el dispositivo. Terminaremos este apartado mostrando cómo crear tu propio ContentProvider, de forma que otras aplicaciones puedan acceder a tu información.

Conceptos básicos:

El modelo de datos

La forma en la que un ContentProvider almacena la información es un aspecto de diseño interno, de forma que podríamos utilizar cualquiera de los métodos descritos en este capítulo. No obstante, cuando hagamos una consulta al ContentProvider se devolverá un objeto de tipo Cursor. Esto hace que la forma más práctica para almacenar la información sea en una base de datos.

Utilizando términos del modelo de bases de datos, un ContentProvider proporciona sus datos a través de una tabla simple, donde cada fila es un registro y cada columna es un tipo de datos con un significado particular. Por ejemplo, el ContentProvider que utilizaremos en el siguiente ejemplo se llama CallLog, y permite acceder al registro de llamadas del teléfono. La información que nos proporciona tiene la estructura que se muestra a continuación:

 

_id

date

number

Duration

Type

1

12/10/10  16:10

555123123

65

INCOMING_TYPE

3

12/11/10  20:42

555453455

356

OUTGOING_TYPE

4

13/11/10  12:15

555123123

90

MISSED_TYPE

5

14/11/10  22:10

555783678

542

OUTGOING_TYPE

 

Tabla 8: Ejemplo de estructura de datos de un ContentProvider.

Cada registro incluye el campo numérico _id que lo identifica de forma única. Como veremos a continuación podremos utilizar este campo para identificar una llamada en concreto.

La forma de acceder a la información de un ContentProvider es muy similar al proceso descrito para las bases de datos. Es decir, vamos a poder realizar una consulta (incluso utilizando el lenguaje SQL), tras la cual se nos proporcionará un objeto de tipo Cursor. Este objeto, contiene una información con una estructura similar a la mostrada en la tabla anterior.

 

Las URI

Para acceder a un ContentProvider en particular va a ser necesario identificarlo con una URI. Una URI (ver estándar RFC 2396) es una cadena de texto que permite identificar un recurso de información. Suele utilizarse frecuentemente en Internet, por ejemplo para acceder a una página web. Una URI está formada por cuatro partes, tal y como se muestra a continuación:

<standard_prefix>://<authority>/<data_path>/<id>

La parte <standard_prefix> de todos los ContentProvider ha de ser siempre content. En el primer ejemplo de este apartado, utilizaremos un ContentProvider donde Android almacena el registro de llamadas. Para acceder a este ContentProvider utilizaremos la siguiente URI:

content://call_log/calls

En la Tabla 9 encontrarás otros ejemplos de URI que te permitirán acceder a otras informaciones almacenadas en Android.

Para acceder a un elemento concreto has de indicar un <id> en la URI. Por ejemplo, si te interesa solo acceder a la llamada con identificador 4 (normalmente corresponderá a la cuarta llamada de la lista), has de indicar:

content://call_log/calls/4

Un mismo ContentProvider puede contener múltiples conjuntos de datos identificados por diferentes URI. Por ejemplo para acceder a los ficheros multimedia almacenados en el móvil utilizaremos el ContentProvider MediaStore, utilizando algunos de los siguientes ejemplos de URI:

 

content://media/internal/images

content://media/external/video/5

content://media/*/audio

 

Cada ContentProvider suele definir constantes con sus correspondientes URI.

Por ejemplo, android.provider.CallLog.Calls.CONTENT_URI corresponde con content://call_log/calls.

Y la constante:

android.provider.MediaStore.Audio.Media.INTERNAL_CONTENT_URI.

Corresponde con content://media/internal/audio.