Создайте поставщика контента-заглушки

Фреймворк адаптера синхронизации предназначен для работы с данными устройства, управляемыми гибким и высокозащищенным фреймворком поставщика контента. Поэтому фреймворк адаптера синхронизации ожидает, что приложение, которое его использует, уже определило поставщика контента для своих локальных данных. Если фреймворк попытается запустить адаптер синхронизации, а в приложении нет поставщика контента, произойдет сбой адаптера.

Если вы разрабатываете новое приложение, которое передает данные с сервера на устройство, настоятельно рекомендуем хранить локальные данные в поставщике контента. Помимо того, что поставщики контента важны для адаптеров синхронизации, они обеспечивают безопасность и специально разработаны для управления хранением данных в системах Android. Подробнее о том, как создать поставщика контента…

Однако если вы уже храните локальные данные в другой форме, вы все равно можете использовать адаптер синхронизации для обработки передачи данных. Чтобы выполнить требование фреймворка адаптера синхронизации, добавьте в приложение фиктивный поставщик контента. Он реализует класс поставщика контента, но все его обязательные методы возвращают null или 0. Добавив поставщика-заглушку, вы сможете использовать адаптер синхронизации для передачи данных из любого выбранного вами механизма хранения.

Если в вашем приложении уже есть поставщик контента, то создавать фиктивного поставщика не нужно. В этом случае вы можете пропустить этот урок и перейти к уроку Создание адаптера синхронизации. Если у вас ещё нет поставщика контента, в этом уроке вы узнаете, как добавить поставщика контента-заглушку, который позволит подключить адаптер синхронизации к фреймворку.

Добавьте поставщика контента-заглушки

Чтобы создать фиктивный поставщик контента для приложения, расширьте класс ContentProvider и создайте заглушки для его обязательных методов. В следующем фрагменте кода показано, как создать поставщика-заглушку:

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;
    }
}

Объявите поставщика в манифесте

Фреймворк адаптера синхронизации проверяет, есть ли у вашего приложения поставщик контента, проверяя, объявило ли ваше приложение поставщика в манифесте приложения. Чтобы объявить поставщика-заглушку в манифесте, добавьте элемент <provider> со следующими атрибутами:

android:name="com.example.android.datasync.provider.StubProvider"
Указывает полное имя класса, который реализует поставщика контента-заглушки.
android:authorities="com.example.android.datasync.provider"
Центр сертификации URI, который идентифицирует поставщика контента-заглушки. В качестве значения укажите название пакета приложения, добавив к нему строку ".provider". Хотя вы объявляете системе о своем поставщике-заглушке, никто не пытается получить доступ к самому поставщику.
android:exported="false"
Определяет, могут ли другие приложения получать доступ к поставщику контента. Для поставщика контента-заглушки задайте значение false, поскольку другим приложениям не нужно видеть поставщика. Это значение не влияет на взаимодействие между фреймворком адаптера синхронизации и поставщиком контента.
android:syncable="true"
Устанавливает флаг, указывающий, что поставщик поддерживает синхронизацию. Если вы установите для этого флага значение true, вам не нужно будет вызывать setIsSyncable() в коде. Этот флаг позволяет фреймворку адаптера синхронизации передавать данные с помощью поставщика контента, но передача происходит только в том случае, если вы явно ее выполняете.

В следующем фрагменте кода показано, как добавить элемент <provider> в манифест приложения:

<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>

Теперь, когда вы создали зависимости, необходимые для фреймворка адаптера синхронизации, вы можете создать компонент, который инкапсулирует код передачи данных. Этот компонент называется адаптером синхронизации. В следующем уроке вы узнаете, как добавить этот компонент в приложение.