Cómo crear un proveedor de contenido de stub

El framework del adaptador de sincronización está diseñado para funcionar con datos del dispositivo administrados por el framework flexible y seguro del proveedor de contenido. Por esta razón, el framework del adaptador de sincronización espera que una app que usa el framework ya haya definido un proveedor de contenido para sus datos locales. Si el framework del adaptador de sincronización intenta ejecutar el adaptador de sincronización y tu app no tiene un proveedor de contenido, fallará el adaptador de sincronización.

Si estás desarrollando una nueva app que transfiere datos de un servidor al dispositivo, procura almacenar los datos locales en un proveedor de contenido. Además de su importancia para los adaptadores de sincronización, los proveedores de contenido ofrecen una variedad de beneficios de seguridad y están diseñados específicamente para administrar el almacenamiento de datos en sistemas Android. Para obtener más información sobre cómo crear un proveedor de contenido, consulta Cómo crear un proveedor de contenido.

Sin embargo, si ya almacenas datos locales de otra forma, aún puedes usar un adaptador de sincronización para controlar la transferencia de datos. Para satisfacer el requisito del framework del adaptador de sincronización para un proveedor de contenido, agrega un proveedor de contenido de stub a tu app. Un proveedor de stub implementa la clase de proveedor de contenido, pero todos sus métodos obligatorios muestran null o 0. Si agregas un proveedor de stub, puedes usar un adaptador de sincronización para transferir datos desde cualquier mecanismo de almacenamiento que elijas.

Si ya tienes un proveedor de contenido en la app, no necesitas un proveedor de contenido de stub. En ese caso, puedes omitir esta lección y continuar con Cómo crear un adaptador de sincronización. Si aún no tienes un proveedor de contenido, en esta lección, se muestra cómo agregar un proveedor de contenido de stub que te permita conectar el adaptador de sincronización al framework.

Cómo agregar un proveedor de contenido de stub

Para crear un proveedor de contenido de stub para la app, extiende la clase ContentProvider y cancela los métodos obligatorios. En el siguiente fragmento, se muestra cómo crear el proveedor de stub:

Kotlin

/*
 * Define an implementation of ContentProvider that stubs out
 * all methods
 */
class StubProvider : ContentProvider() {
    /*
     * Always return true, indicating that the
     * provider loaded correctly.
     */
    override fun onCreate(): Boolean  = true

    /*
     * Return no type for MIME type
     */
    override fun getType(uri: Uri): String?  = null

    /*
     * query() always returns no results
     *
     */
    override fun query(
            uri: Uri,
            projection: Array<String>,
            selection: String,
            selectionArgs: Array<String>,
            sortOrder: String
    ): Cursor?  = null

    /*
     * insert() always returns null (no URI)
     */
    override fun insert(uri: Uri, values: ContentValues): Uri? = null

    /*
     * delete() always returns "no rows affected" (0)
     */
    override fun delete(uri: Uri, selection: String, selectionArgs: Array<String>): Int = 0

    /*
     * update() always returns "no rows affected" (0)
     */
    override fun update(
            uri: Uri,
            values: ContentValues,
            selection: String,
            selectionArgs: Array<String>
    ): Int = 0
}

Java

/*
 * Define an implementation of ContentProvider that stubs out
 * all methods
 */
public class StubProvider extends ContentProvider {
    /*
     * Always return true, indicating that the
     * provider loaded correctly.
     */
    @Override
    public boolean onCreate() {
        return true;
    }
    /*
     * Return no type for MIME type
     */
    @Override
    public String getType(Uri uri) {
        return null;
    }
    /*
     * query() always returns no results
     *
     */
    @Override
    public Cursor query(
            Uri uri,
            String[] projection,
            String selection,
            String[] selectionArgs,
            String sortOrder) {
        return null;
    }
    /*
     * insert() always returns null (no URI)
     */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }
    /*
     * delete() always returns "no rows affected" (0)
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }
    /*
     * update() always returns "no rows affected" (0)
     */
    public int update(
            Uri uri,
            ContentValues values,
            String selection,
            String[] selectionArgs) {
        return 0;
    }
}

Cómo declarar el proveedor en el manifiesto

El framework del adaptador de sincronización verifica que tu app tenga un proveedor de contenido. Para ello, comprueba que tu app haya declarado un proveedor en su manifiesto. Para declarar el proveedor de stub en el manifiesto, agrega un elemento <provider> con los siguientes atributos:

android:name="com.example.android.datasync.provider.StubProvider"
Especifica el nombre completo de la clase que implementa el proveedor de contenido de stub.
android:authorities="com.example.android.datasync.provider"
Es una autoridad de URI que identifica al proveedor de contenido de stub. Usa este valor como nombre del paquete de tu app con la string ".provider" adjunta. Aunque declaras tu proveedor de stub en el sistema, ningún elemento intentará acceder al proveedor.
android:exported="false"
Determina si otras apps pueden acceder al proveedor de contenido. Para tu proveedor de contenido de stub, establece el valor en false, ya que no es necesario permitir que otras apps lo vean. Este valor no afecta la interacción entre el framework del adaptador de sincronización y el proveedor de contenido.
android:syncable="true"
Establece una marca que indique que se puede sincronizar el proveedor. Si estableces esta marca en true, no tienes que llamar a setIsSyncable() en tu código. La marca permite que el framework del adaptador de sincronización realice transferencias de datos con el proveedor de contenido, pero las transferencias solo ocurren si las haces de manera explícita.

En el siguiente fragmento, se muestra cómo agregar el elemento <provider> al manifiesto de la app:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.network.sync.BasicSyncAdapter"
    android:versionCode="1"
    android:versionName="1.0" >
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    ...
    <provider
        android:name="com.example.android.datasync.provider.StubProvider"
        android:authorities="com.example.android.datasync.provider"
        android:exported="false"
        android:syncable="true"/>
    ...
    </application>
</manifest>

Ahora que creaste las dependencias que requiere el framework del adaptador de sincronización, puedes crear el componente que encapsula tu código de transferencia de datos. Este componente se denomina adaptador de sincronización. En la siguiente lección, se muestra cómo agregarlo a la app.