Synchronisierungsadapter erstellen

Hinweis:Wir empfehlen WorkManager. ist die empfohlene Lösung für die meisten Anwendungsfälle der Hintergrundverarbeitung. Bitte beachten Sie die Leitfaden zur Hintergrundverarbeitung, um zu erfahren, welche Lösung für Sie am besten geeignet ist.

Die Komponente des Synchronisierungsadapters in Ihrer Anwendung kapselt den Code für die Aufgaben, die übertragen werden zwischen dem Gerät und einem Server. Basierend auf der Planung und den Triggern, die Sie in Ihrer App ausgeführt hat, führt das Framework des Synchronisierungsadapters den Code in der Komponente des Synchronisierungsadapters aus. So fügen Sie ein Komponente zum Synchronisieren von Adaptern mit Ihrer App haben, müssen Sie die folgenden Teile hinzufügen:

Adapterklasse für die Synchronisierung.
Eine Klasse, die Ihren Datenübertragungscode in einer Schnittstelle einschließt, die mit dem Synchronisierungsadapter kompatibel ist Framework.
Gebunden: Service.
Eine Komponente, die es dem Framework des Synchronisierungsadapters ermöglicht, den Code in Ihrem Synchronisierungsadapter auszuführen .
XML-Metadatendatei des Synchronisierungsadapters.
Eine Datei mit Informationen zu Ihrem Synchronisierungsadapter. Das Framework liest diese Datei finden Sie weitere Informationen zum Laden und Planen der Datenübertragung.
Deklarationen im App-Manifest.
XML, die den gebundenen Dienst deklariert und auf die Synchronisierung vonadapterspezifischen Metadaten verweist.

In dieser Lektion erfahren Sie, wie Sie diese Elemente definieren.

Synchronisierungsadapterklasse erstellen

In diesem Teil der Lektion erfahren Sie, wie Sie die Synchronisationsadapterklasse erstellen, die die Datenübertragungscode. Zum Erstellen der Klasse gehört das Erweitern der Basisklasse des Synchronisierungsadapters, Konstruktoren für die Klasse und implementieren die Methode, mit der Sie die Datenübertragung definieren. Aufgaben.

Adapterklasse für die Basissynchronisierung erweitern

Um die Komponente des Synchronisierungsadapters zu erstellen, erweitern Sie AbstractThreadedSyncAdapter und schreibt seine Konstruktoren. Verwenden Sie die Methode Konstruktoren, die jedes Mal Einrichtungsaufgaben ausführen, wenn Ihre Synchronisierungsadapterkomponente erstellt wird wie Sie Activity.onCreate() verwenden, um ein Aktivitäten. Wenn Ihre Anwendung beispielsweise einen Contentanbieter zum Speichern von Daten verwendet, verwenden Sie die Konstruktoren. um eine ContentResolver-Instanz abzurufen. Da eine zweite Form des Konstruktor wurde in Version 3.0 der Android-Plattform hinzugefügt, um den parallelSyncs zu unterstützen -Arguments, müssen Sie zwei Formen des Konstruktors erstellen, um die Kompatibilität aufrechtzuerhalten.

Hinweis: Das Framework des Synchronisierungsadapters funktioniert mit dem Synchronisierungsadapter. bei denen es sich um Singleton-Instanzen handelt. Die Instanziierung der Komponente des Synchronisierungsadapters ist abgedeckt. erfahren Sie im Abschnitt Binden Sie den Synchronisierungsadapter an das Framework ein.

Das folgende Beispiel zeigt, wie Sie AbstractThreadedSyncAdapter und ihre Konstruktoren:

Kotlin

/**
 * Handle the transfer of data between a server and an
 * app, using the Android sync adapter framework.
 */
class SyncAdapter @JvmOverloads constructor(
        context: Context,
        autoInitialize: Boolean,
        /**
         * Using a default argument along with @JvmOverloads
         * generates constructor for both method signatures to maintain compatibility
         * with Android 3.0 and later platform versions
         */
        allowParallelSyncs: Boolean = false,
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        val mContentResolver: ContentResolver = context.contentResolver
) : AbstractThreadedSyncAdapter(context, autoInitialize, allowParallelSyncs) {
    ...
}

Java

/**
 * Handle the transfer of data between a server and an
 * app, using the Android sync adapter framework.
 */
public class SyncAdapter extends AbstractThreadedSyncAdapter {
    ...
    // Global variables
    // Define a variable to contain a content resolver instance
    ContentResolver contentResolver;
    /**
     * Set up the sync adapter
     */
    public SyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        contentResolver = context.getContentResolver();
    }
    ...
    /**
     * Set up the sync adapter. This form of the
     * constructor maintains compatibility with Android 3.0
     * and later platform versions
     */
    public SyncAdapter(
            Context context,
            boolean autoInitialize,
            boolean allowParallelSyncs) {
        super(context, autoInitialize, allowParallelSyncs);
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        contentResolver = context.getContentResolver();
        ...
    }

Datenübertragungscode hinzufügen

Die Komponente des Synchronisierungsadapters führt nicht automatisch eine Datenübertragung durch. Stattdessen werden sie kapselt Ihren Datenübertragungscode, sodass das Framework des Synchronisierungsadapters die Datenübertragung im Hintergrund, ohne Beteiligung der App. Wenn das Framework bereit ist Zum Synchronisieren der Daten Ihrer Anwendung wird die Implementierung der -Methode aufgerufen. onPerformSync()

Um die Übertragung von Daten vom Code Ihrer App an die Komponente des Synchronisierungsadapters zu erleichtern, ruft das Framework des Synchronisierungsadapters onPerformSync() mit dem folgende Argumente:

Konto
Ein Account-Objekt, das dem Ereignis zugeordnet ist, das ausgelöst wurde Synchronisierungsadapter verwenden. Falls Ihr Server keine Konten verwendet, müssen Sie nicht das Informationen in diesem Objekt.
Extras
Ein Bundle mit Flags, die von dem Ereignis gesendet wurden, das die Synchronisierung ausgelöst hat Adapter.
Fachkompetenz
Die Befugnis eines Contentanbieters im System. Ihre App muss Zugriff auf diesem Anbieter. In der Regel entspricht die Befugnis einem Contentanbieter in Ihrer eigenen App.
Contentanbieter-Client
Eine ContentProviderClient für den Contentanbieter, auf den das Autoritätsargument sein könnten. Ein ContentProviderClient ist eine einfache öffentliche zu einem Contentanbieter. Es hat die gleichen Grundfunktionen wie ein ContentResolver Wenn Sie Daten mit einem Contentanbieter speichern für Ihre App möchten, können Sie mit diesem Objekt eine Verbindung zum Anbieter herstellen. Andernfalls können Sie die .
Synchronisierungsergebnis
Ein SyncResult-Objekt, mit dem Sie Informationen an die Synchronisierung senden Adapter-Framework.

Das folgende Snippet zeigt die Gesamtstruktur onPerformSync():

Kotlin

/*
 * Specify the code you want to run in the sync adapter. The entire
 * sync adapter runs in a background thread, so you don't have to set
 * up your own background processing.
 */
override fun onPerformSync(
        account: Account,
        extras: Bundle,
        authority: String,
        provider: ContentProviderClient,
        syncResult: SyncResult
) {
    /*
     * Put the data transfer code here.
     */
}

Java

/*
 * Specify the code you want to run in the sync adapter. The entire
 * sync adapter runs in a background thread, so you don't have to set
 * up your own background processing.
 */
@Override
public void onPerformSync(
        Account account,
        Bundle extras,
        String authority,
        ContentProviderClient provider,
        SyncResult syncResult) {
    /*
     * Put the data transfer code here.
     */
}

Während die Implementierung onPerformSync() ist spezifisch für Anforderungen an die Datensynchronisierung und die Serververbindungsprotokolle Ihrer App haben, gibt es einige allgemeine Aufgaben, die Ihre Implementierung ausführen sollte:

Verbindung zu einem Server herstellen
Auch wenn Sie zu Beginn der Datenübertragung davon ausgehen können, dass das Netzwerk verfügbar ist, Sync Adapter-Framework stellt nicht automatisch eine Verbindung zu einem Server her.
Daten herunter- und hochladen
Ein Synchronisierungsadapter automatisiert keine Datenübertragungsaufgaben. Zum Herunterladen Daten von einem Server abrufen und bei einem Contentanbieter speichern, müssen Sie den Code angeben, fordert die Daten an, lädt sie herunter und fügt sie beim Anbieter ein. Ähnliches gilt, wenn Sie Daten an einen Server senden, aus einer Datei, einer Datenbank oder einem Anbieter auslesen die erforderliche Upload-Anfrage. Außerdem müssen Sie mit Netzwerkfehlern umgehen, Datenübertragung läuft.
Umgang mit Datenkonflikten oder Bestimmung der Aktualität der Daten
Ein Synchronisierungsadapter handhabt Konflikte zwischen Daten auf dem Server und Daten nicht automatisch. auf dem Gerät. Außerdem erkennt er nicht automatisch, ob die Daten auf dem Server neuer sind als auf dem Gerät gespeichert werden oder umgekehrt. Stattdessen müssen Sie Ihre eigenen Algorithmen mit dieser Situation umgehen kann.
Bereinigen Sie Ihre Daten.
Trennen Sie immer Verbindungen zu einem Server und bereinigen Sie temporäre Dateien und Caches am Ende der Ihrer Datenübertragung.

Hinweis: Das Framework für den Synchronisierungsadapter wird ausgeführt. onPerformSync() am Hintergrund-Thread, sodass Sie keine eigene Hintergrundverarbeitung einrichten müssen.

Zusätzlich zu den Synchronisierungsaufgaben sollten Sie versuchen, Ihre regulären Aufgaben im Zusammenhang mit Ihrem Netzwerk onPerformSync() Indem Sie alle Ihre Netzwerkaufgaben auf diese Methode bündeln, schonen Sie die Akkuleistung, die zum Starten und Beenden der Netzwerkschnittstellen erforderlich sind. Weitere Informationen zum Erhöhen des Netzwerkzugriffs finden Sie im Kurs Daten ohne zu viel Akkuleistung übertragen. In diesem Kurs werden verschiedene Netzwerkzugriffe beschrieben. Aufgaben, die Sie in Ihren Datenübertragungscode aufnehmen können.

Synchronisierungsadapter an das Framework binden

Der Datenübertragungscode ist jetzt in eine Synchronisierungsadapterkomponente gekapselt, um dem Framework Zugriff auf Ihren Code zu gewähren. Dazu müssen Sie eine Grenze erstellen. Service, das ein spezielles Android-Binder-Objekt vom Synchronisierungsadapter übergibt Komponente zum Framework hinzu. Mit diesem Binder-Objekt kann das Framework die Methode Methode onPerformSync() und Daten an sie übergeben.

Instanziieren Sie die Komponente des Synchronisierungsadapters als Singleton im onCreate()-Methode des Dienstes. Durch Instanziieren der Komponente in onCreate(), stellen Sie bis der Dienst gestartet wird. Dies geschieht, wenn das Framework zum ersten Mal versucht, Ihre Datenübertragung. Sie müssen die Komponente threadsicher instanziieren, falls die Synchronisierung -Adapter-Framework stellt mehrere Ausführungen Ihres Synchronisierungsadapters als Reaktion auf Trigger oder Terminplanung.

Das folgende Snippet zeigt beispielsweise, wie Sie eine Klasse erstellen, die das Tag Service gebunden, instanziiert die Komponente des Synchronisierungsadapters und ruft den Android-Binder-Objekt:

Kotlin

package com.example.android.syncadapter
/**
 * Define a Service that returns an [android.os.IBinder] for the
 * sync adapter class, allowing the sync adapter framework to call
 * onPerformSync().
 */
class SyncService : Service() {
    /*
     * Instantiate the sync adapter object.
     */
    override fun onCreate() {
        /*
         * Create the sync adapter as a singleton.
         * Set the sync adapter as syncable
         * Disallow parallel syncs
         */
        synchronized(sSyncAdapterLock) {
            sSyncAdapter = sSyncAdapter ?: SyncAdapter(applicationContext, true)
        }
    }

    /**
     * Return an object that allows the system to invoke
     * the sync adapter.
     *
     */
    override fun onBind(intent: Intent): IBinder {
        /*
         * Get the object that allows external processes
         * to call onPerformSync(). The object is created
         * in the base class code when the SyncAdapter
         * constructors call super()
         *
         * We should never be in a position where this is called before
         * onCreate() so the exception should never be thrown
         */
        return sSyncAdapter?.syncAdapterBinder ?: throw IllegalStateException()
    }

    companion object {
        // Storage for an instance of the sync adapter
        private var sSyncAdapter: SyncAdapter? = null
        // Object to use as a thread-safe lock
        private val sSyncAdapterLock = Any()
    }
}

Java

package com.example.android.syncadapter;
/**
 * Define a Service that returns an <code><a href="/reference/android/os/IBinder.html">IBinder</a></code> for the
 * sync adapter class, allowing the sync adapter framework to call
 * onPerformSync().
 */
public class SyncService extends Service {
    // Storage for an instance of the sync adapter
    private static SyncAdapter sSyncAdapter = null;
    // Object to use as a thread-safe lock
    private static final Object sSyncAdapterLock = new Object();
    /*
     * Instantiate the sync adapter object.
     */
    @Override
    public void onCreate() {
        /*
         * Create the sync adapter as a singleton.
         * Set the sync adapter as syncable
         * Disallow parallel syncs
         */
        synchronized (sSyncAdapterLock) {
            if (sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
            }
        }
    }
    /**
     * Return an object that allows the system to invoke
     * the sync adapter.
     *
     */
    @Override
    public IBinder onBind(Intent intent) {
        /*
         * Get the object that allows external processes
         * to call onPerformSync(). The object is created
         * in the base class code when the SyncAdapter
         * constructors call super()
         */
        return sSyncAdapter.getSyncAdapterBinder();
    }
}

Hinweis:Wenn Sie ein detaillierteres Beispiel eines gebundenen Dienstes für einen Synchronisierungsadapter sehen möchten, sehen Sie sich die Beispiel-App an.

Für das Framework erforderliches Konto hinzufügen

Für das Framework des Synchronisierungsadapters muss jeder Synchronisierungsadapter einen Kontotyp haben. Sie haben erklärt im Bereich „Kontotyp“ Fügen Sie die Authenticator-Metadatendatei hinzu. Jetzt müssen Sie diesen Kontotyp in der Android-System. Fügen Sie zum Einrichten des Kontotyps ein Platzhalterkonto hinzu, für das der Kontotyp verwendet wird indem du addAccountExplicitly() anrufst.

Rufen Sie die Methode am besten im onCreate()-Methode des öffnen. Das folgende Code-Snippet zeigt, wie das geht:

Kotlin

...
// Constants
// The authority for the sync adapter's content provider
const val AUTHORITY = "com.example.android.datasync.provider"
// An account type, in the form of a domain name
const val ACCOUNT_TYPE = "example.com"
// The account name
const val ACCOUNT = "placeholderaccount"
...
class MainActivity : FragmentActivity() {

    // Instance fields
    private lateinit var mAccount: Account
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
       ...
        // Create the placeholder account
        mAccount = createSyncAccount()
       ...
    }
    ...
    /**
     * Create a new placeholder account for the sync adapter
     */
    private fun createSyncAccount(): Account {
        val accountManager = getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
        return Account(ACCOUNT, ACCOUNT_TYPE).also { newAccount ->
            /*
             * Add the account and account type, no password or user data
             * If successful, return the Account object, otherwise report an error.
             */
            if (accountManager.addAccountExplicitly(newAccount, null, null)) {
                /*
                 * If you don't set android:syncable="true" in
                 * in your <provider> element in the manifest,
                 * then call context.setIsSyncable(account, AUTHORITY, 1)
                 * here.
                 */
            } else {
                /*
                 * The account exists or some other error occurred. Log this, report it,
                 * or handle it internally.
                 */
            }
        }
    }
    ...
}

Java

public class MainActivity extends FragmentActivity {
    ...
    ...
    // Constants
    // The authority for the sync adapter's content provider
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // An account type, in the form of a domain name
    public static final String ACCOUNT_TYPE = "example.com";
    // The account name
    public static final String ACCOUNT = "placeholderaccount";
    // Instance fields
    Account mAccount;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Create the placeholder account
        mAccount = CreateSyncAccount(this);
        ...
    }
    ...
    /**
     * Create a new placeholder account for the sync adapter
     *
     * @param context The application context
     */
    public static Account CreateSyncAccount(Context context) {
        // Create the account type and default account
        Account newAccount = new Account(
                ACCOUNT, ACCOUNT_TYPE);
        // Get an instance of the Android account manager
        AccountManager accountManager =
                (AccountManager) context.getSystemService(
                        ACCOUNT_SERVICE);
        /*
         * Add the account and account type, no password or user data
         * If successful, return the Account object, otherwise report an error.
         */
        if (accountManager.addAccountExplicitly(newAccount, null, null)) {
            /*
             * If you don't set android:syncable="true" in
             * in your <provider> element in the manifest,
             * then call context.setIsSyncable(account, AUTHORITY, 1)
             * here.
             */
        } else {
            /*
             * The account exists or some other error occurred. Log this, report it,
             * or handle it internally.
             */
        }
    }
    ...
}

Metadatendatei des Sync Adapters hinzufügen

Um die Komponente des Synchronisierungsadapters in das Framework einzubetten, müssen Sie das Framework bereitstellen. mit Metadaten, die die Komponente beschreiben und zusätzliche Flags bereitstellen. Die Metadaten geben dem Kontotyp, den Sie für Ihren Synchronisierungsadapter erstellt haben, eine Inhaltsanbieter-Autorität erklärt. die mit Ihrer App verknüpft sind, einen Teil der Systembenutzeroberfläche für Synchronisierungsadapter steuert, und deklariert andere synchronisierbare Flags. Deklariere diese Metadaten in einer speziellen XML-Datei, die unter das Verzeichnis /res/xml/ in Ihrem Anwendungsprojekt. Sie können der Datei einen beliebigen Namen geben, obwohl es normalerweise syncadapter.xml heißt.

Diese XML-Datei enthält ein einzelnes XML-Element <sync-adapter> mit dem folgende Attribute:

android:contentAuthority
Die URI-Befugnis für Ihren Contentanbieter. Wenn Sie einen Stub-Content-Anbieter für für Ihre App in der vorherigen Lektion Stub-Contentanbieter erstellen. Verwenden Sie den Wert, den Sie für das Attribut android:authorities im <provider>-Element, das Sie Ihrem App-Manifest hinzugefügt haben. Dieses Attribut ist die im Abschnitt Anbieter im Manifest deklarieren
Wenn Sie mit Ihrem Synchronisierungsadapter Daten von einem Contentanbieter auf einen Server übertragen, sollte mit der Inhalts-URI übereinstimmen, die Sie für diese Daten verwenden. Dieser Wert ist auch eine der Behörden, die Sie in den android:authorities des <provider>-Elements, mit dem dein Anbieter in deinem App-Manifest deklariert ist.
android:accountType
Der Kontotyp, der für das Framework des Synchronisierungsadapters erforderlich ist. Der Wert muss identisch sein als Wert für den Kontotyp, den Sie beim Erstellen der Authenticator-Metadatendatei angegeben haben. wie im Abschnitt Authenticator-Metadatendatei hinzufügen beschrieben. Es ist auch der Wert, den Sie für den Konstante ACCOUNT_TYPE im Code-Snippet im Abschnitt Fügen Sie das vom Framework erforderliche Konto hinzu.
Attribute für Einstellungen
android:userVisible
Legt die Sichtbarkeit des Kontotyps des Synchronisierungsadapters fest. Standardmäßig enthält der Parameter Das Kontosymbol und das Label, das dem Kontotyp zugeordnet ist, sind in der Konten in der App "Einstellungen" des Systems. Nehmen Sie daher die Synchronisierung vor. Adapter ist unsichtbar, es sei denn, Sie haben einen Kontotyp oder eine Domain, der bzw. die sich einfach mit Ihrer App. Wenn Sie Ihren Kontotyp unsichtbar machen, können Sie Nutzern trotzdem Folgendes erlauben: Sie können Ihren Synchronisierungsadapter über eine Benutzeroberfläche in einer der Aktivitäten Ihrer App steuern.
android:supportsUploading
Ermöglicht das Hochladen von Daten in die Cloud. Lege hier false fest, wenn deine App nur und lädt Daten herunter.
android:allowParallelSyncs
Ermöglicht die gleichzeitige Ausführung mehrerer Instanzen Ihrer Synchronisierungsadapterkomponente. Verwende diese Option, wenn deine App mehrere Nutzerkonten unterstützt und du mehrere Daten parallel zu übertragen. Dieses Flag hat keine Auswirkungen, wenn Sie mehrere Datenübertragungen erfordern.
android:isAlwaysSyncable
Gibt an das Framework des Sync-Adapters an, dass es Ihren Synchronisierungsadapter jederzeit ausführen kann Uhrzeit angegeben haben. Wenn Sie programmatisch steuern möchten, wann Adapter ausgeführt werden kann, setzen Sie dieses Flag auf false und rufen Sie dann requestSync() zum Ausführen von Sync Adapter. Weitere Informationen zum Ausführen eines Synchronisierungsadapters finden Sie in der entsprechenden Synchronisierungsadapter ausführen

Das folgende Beispiel zeigt die XML für einen Synchronisierungsadapter, der ein einzelnes Platzhalterkonto und nur Downloads.

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:contentAuthority="com.example.android.datasync.provider"
        android:accountType="com.android.example.datasync"
        android:userVisible="false"
        android:supportsUploading="false"
        android:allowParallelSyncs="false"
        android:isAlwaysSyncable="true"/>

Synchronisierungsadapter im Manifest deklarieren

Nachdem Sie die Komponente des Synchronisierungsadapters zu Ihrer App hinzugefügt haben, müssen Sie Berechtigungen anfordern. die mit der Komponente zusammenhängen, und Sie müssen die gebundene Service die Sie hinzugefügt haben.

Da der Synchronisierungsadapter Code ausführt, der Daten zwischen dem Netzwerk und dem müssen Sie die Berechtigung für den Internetzugriff anfordern. Außerdem muss Ihre App um die Berechtigung zum Lesen und Schreiben der Einstellungen des Synchronisierungsadapters anzufordern, damit Sie die Synchronisierung steuern können -Adapter von anderen Komponenten in Ihrer App programmatisch aus. Außerdem müssen Sie ein eine spezielle Berechtigung, mit der Ihre App die von Ihnen erstellte Authenticator-Komponente verwenden kann in der Lektion Stub-Authenticator erstellen.

Füge deinem App-Manifest Folgendes als untergeordnete Elemente von hinzu, um diese Berechtigungen anzufordern: <manifest>:

android.permission.INTERNET
Ermöglicht dem Synchronisierungsadaptercode, auf das Internet zuzugreifen, um Daten herunter- oder hochzuladen vom Gerät an einen Server übertragen. Sie müssen diese Berechtigung nicht noch einmal hinzufügen, zuvor angefordert haben.
android.permission.READ_SYNC_SETTINGS
Ermöglicht Ihrer App, die aktuellen Einstellungen des Synchronisierungsadapters zu lesen. Zum Beispiel benötigen Sie diese Berechtigung, um getIsSyncable() aufzurufen.
android.permission.WRITE_SYNC_SETTINGS
Ermöglicht Ihrer App, die Einstellungen des Synchronisierungsadapters zu steuern. Du benötigst diese Berechtigung, um Legen Sie regelmäßige Synchronisierungsausführungen mit addPeriodicSync() fest. Diese Berechtigung ist nicht erforderlich, um requestSync() Weitere Informationen über Weitere Informationen unter Synchronisierungsadapter ausführen

Das folgende Snippet zeigt, wie die Berechtigungen hinzugefügt werden:

<manifest>
...
    <uses-permission
            android:name="android.permission.INTERNET"/>
    <uses-permission
            android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission
            android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission
            android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
...
</manifest>

Schließlich wird zum Deklarieren der gebundenen Service, die das Framework verwendet, um mit dem Synchronisierungsadapter interagieren, fügen Sie den folgenden XML-Code als untergeordnetes Element zu Ihrem App-Manifest hinzu von <application>:

        <service
                android:name="com.example.android.datasync.SyncService"
                android:exported="false"
                android:process=":sync">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data android:name="android.content.SyncAdapter"
                    android:resource="@xml/syncadapter" />
        </service>

Die <intent-filter> wird ein Filter eingerichtet, der von der Intent-Aktion ausgelöst wird. android.content.SyncAdapter: Wird vom System zum Ausführen des Synchronisierungsadapters gesendet. Wenn der Filter ausgelöst wird, startet das System den von Ihnen erstellten gebundenen Dienst, der in diesem Beispiel SyncService Das Attribut android:exported="false" dass nur Ihre App und das System auf die Service. Das Attribut android:process=":sync" weist das System an, die Service in einem globalen freigegebenen Prozess mit dem Namen sync Wenn Sie mehrere Synchronisierungsadapter in Ihrer App haben, können diese diesen Prozess gemeinsam nutzen. wodurch der Aufwand reduziert wird.

Die <meta-data> -Element stellt den Namen der Metadaten-XML-Datei des Sync Adapters bereit, die Sie zuvor erstellt haben. Die android:name -Attribut gibt an, dass diese Metadaten für das Synchronisierungsadapter-Framework bestimmt sind. Die android:resource -Element gibt den Namen der Metadatendatei an.

Sie haben jetzt alle Komponenten für Ihren Synchronisierungsadapter. In der nächsten Lektion erfahren Sie, weisen Sie das Framework des Sync Adapters an, Ihren Synchronisierungsadapter auszuführen, entweder als Reaktion auf ein Ereignis oder auf nach einem regelmäßigen Zeitplan.