Criar um provedor de conteúdo stub

O framework do adaptador de sincronização foi desenvolvido para funcionar com dados de dispositivos gerenciados pelo framework flexível e altamente seguro do provedor de conteúdo. Por esse motivo, o framework do adaptador de sincronização espera que um app que o utiliza já tenha definido um provedor de conteúdo para os dados locais. Se o framework tentar executar o adaptador de sincronização e o app não tiver um provedor de conteúdo, o adaptador de sincronização falhará.

Se você estiver desenvolvendo um novo app que transfere dados de um servidor para o dispositivo, considere a possibilidade de armazenar os dados locais em um provedor de conteúdo. Além da importância deles para os adaptadores de sincronização, os provedores de conteúdo oferecem uma variedade de benefícios de segurança e são especificamente projetados para gerenciar o armazenamento de dados em sistemas Android. Para saber mais sobre a criação de um provedor de conteúdo, consulte Como criar um provedor de conteúdo.

No entanto, se você já estiver armazenando dados locais de outra forma, ainda poderá usar um adaptador de sincronização para gerenciar a transferência de dados. Para satisfazer ao requisito do framework do adaptador de sincronização para um provedor de conteúdo, adicione um provedor de conteúdo stub ao app. Um provedor stub implementa a classe do provedor de conteúdo, mas todos os métodos correspondentes necessários retornam null ou 0. Se você adicionar um provedor stub, poderá usar um adaptador de sincronização para transferir dados de qualquer mecanismo de armazenamento escolhido.

Se você já tem um provedor de conteúdo no app, não é necessário ter um stub. Nesse caso, você pode pular esta lição e avançar para a lição Como criar um adaptador de sincronização. Se você ainda não tem um provedor de conteúdo, esta lição mostrará como adicionar um provedor de conteúdo stub que permite conectar o adaptador de sincronização ao framework.

Adicionar um provedor de conteúdo stub

Para criar um provedor de conteúdo stub para o app, estenda a classe ContentProvider e crie stubs para os métodos necessários. O snippet a seguir mostra como criar o provedor 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;
        }
    }
    

Declarar o provedor no manifesto

O framework do adaptador de sincronização confirma se o app tem um provedor de conteúdo, verificando se o app declarou um provedor no manifesto do app. Para declarar o provedor stub no manifesto, adicione um elemento <provider> com os seguintes atributos:

android:name="com.example.android.datasync.provider.StubProvider"
Especifica o nome totalmente qualificado da classe que implementa o provedor de conteúdo stub.
android:authorities="com.example.android.datasync.provider"
Uma autoridade de URI que identifica o provedor de conteúdo stub. Use esse valor como o nome do pacote do app com a string "provider" anexada a ele. Mesmo que você esteja declarando seu provedor de stub para o sistema, nada tentará acessar o próprio provedor.
android:exported="false"
Determina se outros apps podem acessar o provedor de conteúdo. Para seu provedor de conteúdo stub, defina o valor como false, uma vez que não é necessário permitir que outros apps o vejam. Esse valor não afeta a interação entre o framework do adaptador de sincronização e o provedor de conteúdo.
android:syncable="true"
Define uma sinalização que indica que o provedor é sincronizável. Se você definir essa sinalização como true, não será necessário chamar setIsSyncable() no seu código. A sinalização permite que o framework do adaptador de sincronização faça transferências de dados com o provedor de conteúdo, mas elas só ocorrerão se você fizer isso explicitamente.

O snippet a seguir mostra como adicionar o elemento <provider> ao manifesto do 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>
    

Agora que você criou as dependências exigidas pelo framework do adaptador de sincronização, poderá criar o componente que encapsula o código de transferência de dados. Esse componente é chamado de "adaptador de sincronização". A próxima lição mostra como adicionar esse componente ao app.