Synchronisierungsadapter erstellen

Hinweis: WorkManager wird als empfohlene Lösung für die meisten Anwendungsfälle der Hintergrundverarbeitung empfohlen. Im Leitfaden zur Hintergrundverarbeitung erfahren Sie, welche Lösung für Sie am besten geeignet ist.

Die Synchronisierungsadapterkomponente in Ihrer App enthält den Code für die Aufgaben, bei denen Daten zwischen dem Gerät und einem Server übertragen werden. Je nach Zeitplan und Triggern, die Sie in der App angeben, führt das Framework für den Synchronisierungsadapter den Code in der Synchronisierungsadapterkomponente aus. Um Ihrer App eine Synchronisierungsadapterkomponente hinzuzufügen, müssen Sie Folgendes hinzufügen:

Synchronisierungsadapterklasse.
Eine Klasse, die Ihren Datenübertragungscode in eine Schnittstelle einbindet, die mit dem Synchronisierungsadapter-Framework kompatibel ist.
Gebunden: Service.
Eine Komponente, die es dem Synchronisierungsadapter-Framework ermöglicht, den Code in Ihrer Synchronisierungsadapterklasse auszuführen.
XML-Metadatendatei des Adapters synchronisieren.
Eine Datei mit Informationen zu Ihrem Synchronisierungsadapter. Das Framework liest diese Datei, um zu ermitteln, wie Sie Ihre Datenübertragung laden und planen.
Erklärungen im App-Manifest
Eine XML-Datei, 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 Synchronisierungsadapterklasse erstellen, die den Datenübertragungscode enthält. Das Erstellen der Klasse umfasst das Erweitern der Basisklasse des Synchronisierungsadapters, das Definieren von Konstruktoren für die Klasse und das Implementieren der Methode, mit der Sie die Datenübertragungsaufgaben definieren.

Basissynchronisierungsadapterklasse erweitern

Wenn Sie die Synchronisierungsadapterkomponente erstellen möchten, erweitern Sie zuerst AbstractThreadedSyncAdapter und schreiben Sie ihre Konstruktoren. Mit den Konstruktoren können Sie jedes Mal Einrichtungsaufgaben ausführen, wenn Ihre Synchronisierungsadapterkomponente von Grund auf neu erstellt wird. Das funktioniert genauso wie mit Activity.onCreate(), um eine Aktivität einzurichten. Wenn Ihre Anwendung beispielsweise zum Speichern von Daten einen Contentanbieter verwendet, rufen Sie mit den Konstruktoren eine ContentResolver-Instanz ab. Da in Version 3.0 der Android-Plattform eine zweite Form des Konstruktors hinzugefügt wurde, um das Argument parallelSyncs zu unterstützen, müssen Sie zwei Formen des Konstruktors erstellen, um die Kompatibilität aufrechtzuerhalten.

Hinweis: Das Synchronisierungsadapter-Framework wurde für die Zusammenarbeit mit Synchronisierungsadapterkomponenten entwickelt, die Singleton-Instanzen sind. Die Instanziierung der Synchronisierungsadapterkomponente wird im Abschnitt Synchronisierungsadapter an das Framework binden ausführlicher behandelt.

Das folgende Beispiel zeigt, wie Sie AbstractThreadedSyncAdapter und seine Konstruktoren implementieren:

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 Synchronisierungsadapterkomponente führt nicht automatisch eine Datenübertragung durch. Stattdessen wird der Datenübertragungscode gekapselt, sodass das Synchronisierungsadapter-Framework die Datenübertragung im Hintergrund ohne Einbeziehung Ihrer App ausführen kann. Wenn das Framework zum Synchronisieren der Daten Ihrer Anwendung bereit ist, ruft es Ihre Implementierung der Methode onPerformSync() auf.

Das Synchronisierungsadapter-Framework ruft onPerformSync() mit den folgenden Argumenten auf, um die Übertragung von Daten vom Haupt-App-Code zur Synchronisierungsadapterkomponente zu erleichtern:

Konto
Ein Account-Objekt, das dem Ereignis zugeordnet ist, das den Synchronisierungsadapter ausgelöst hat. Wenn Ihr Server keine Konten verwendet, müssen Sie die Informationen in diesem Objekt nicht verwenden.
Extras
Eine Bundle mit Flags, die von dem Ereignis gesendet wurden, das den Synchronisierungsadapter ausgelöst hat.
Autor
Die Autorisierung eines Contentanbieters im System. Ihre App muss Zugriff auf diesen Anbieter haben. In der Regel entspricht die Autorisierung einem Contentanbieter in Ihrer eigenen App.
Client des Contentanbieters
Ein ContentProviderClient für den Contentanbieter, auf den das Argument „author“ verweist. Ein ContentProviderClient ist eine einfache öffentliche Schnittstelle für einen Inhaltsanbieter. Es hat die gleiche grundlegende Funktionalität wie ein ContentResolver-Objekt. Wenn Sie einen Contentanbieter zum Speichern von Daten für Ihre App verwenden, können Sie mit diesem Objekt eine Verbindung zum Anbieter herstellen. Andernfalls können Sie sie ignorieren.
Ergebnis der Synchronisierung
Ein SyncResult-Objekt, mit dem Sie Informationen an das Framework für den Synchronisierungsadapter senden.

Das folgende Snippet zeigt die Gesamtstruktur von 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 tatsächliche Implementierung von onPerformSync() spezifisch für die Datensynchronisierungsanforderungen und Serververbindungsprotokolle Ihrer Anwendung ist, gibt es einige allgemeine Aufgaben, die die Implementierung ausführen sollte:

Verbindung zu einem Server herstellen
Auch wenn Sie davon ausgehen können, dass das Netzwerk zu Beginn der Datenübertragung verfügbar ist, stellt das Framework für den Synchronisierungsadapter nicht automatisch eine Verbindung zu einem Server her.
Daten herunter- und hochladen
Mit einem Synchronisierungsadapter werden keine Datenübertragungsaufgaben automatisiert. Wenn Sie Daten von einem Server herunterladen und bei einem Contentanbieter speichern möchten, müssen Sie den Code angeben, der die Daten anfordert, herunterlädt und in den Anbieter einfügt. Ebenso müssen Sie Daten, die Sie an einen Server senden möchten, aus einer Datei, einer Datenbank oder einem Anbieter auslesen und die erforderliche Uploadanfrage senden. Außerdem müssen Sie Netzwerkfehler beheben, die während der Datenübertragung auftreten.
Umgang mit Datenkonflikten oder Ermitteln, wie aktuell die Daten sind
Ein Synchronisierungsadapter behebt nicht automatisch Konflikte zwischen Daten auf dem Server und Daten auf dem Gerät. Außerdem wird nicht automatisch erkannt, ob die Daten auf dem Server neuer sind als die Daten auf dem Gerät oder umgekehrt. Stattdessen müssen Sie Ihre eigenen Algorithmen für diese Situation bereitstellen.
Bereinigen Sie Ihre Daten.
Trennen Sie immer die Verbindungen zu einem Server und bereinigen Sie am Ende der Datenübertragung temporäre Dateien und Caches.

Hinweis: Das Framework für den Synchronisierungsadapter führt onPerformSync() in einem Hintergrundthread aus, sodass Sie keine eigene Hintergrundverarbeitung einrichten müssen.

Zusätzlich zu den Synchronisierungsaufgaben sollten Sie versuchen, Ihre regulären netzwerkbezogenen Aufgaben zu kombinieren und zu onPerformSync() hinzuzufügen. Indem Sie alle Ihre Netzwerkaufgaben auf diese Methode konzentrieren, sparen Sie die Akkuleistung, die zum Starten und Beenden der Netzwerkschnittstellen benötigt wird. Wenn Sie mehr darüber erfahren möchten, wie Sie den Netzwerkzugriff effizienter gestalten, lesen Sie den Trainingskurs Daten übertragen, ohne den Akku zu entleeren. In diesem Kurs werden verschiedene Aufgaben für den Netzwerkzugriff beschrieben, die Sie in Ihren Datenübertragungscode aufnehmen können.

Synchronisierungsadapter an das Framework binden

Sie haben jetzt Ihren Datenübertragungscode in eine Synchronisierungsadapterkomponente gekapselt, müssen jedoch dem Framework Zugriff auf Ihren Code gewähren. Dazu müssen Sie ein gebundenes Service erstellen, das ein spezielles Android-Binder-Objekt von der Synchronisierungsadapterkomponente an das Framework übergibt. Mit diesem Binder-Objekt kann das Framework die Methode onPerformSync() aufrufen und Daten an sie übergeben.

Instanziieren Sie Ihre Synchronisierungsadapterkomponente als Singleton in der onCreate()-Methode des Dienstes. Wenn Sie die Komponente in onCreate() instanziieren, verzögern Sie ihre Erstellung, bis der Dienst gestartet wird. Dies geschieht, wenn das Framework zum ersten Mal versucht, die Datenübertragung auszuführen. Sie müssen die Komponente Thread-sicher instanziieren, falls das Framework für den Synchronisierungsadapter mehrere Ausführungen des Synchronisierungsadapters als Reaktion auf Trigger oder Planung in die Warteschlange stellt.

Das folgende Snippet zeigt beispielsweise, wie Sie eine Klasse erstellen, die das gebundene Service implementiert, Ihre Synchronisierungsadapterkomponente instanziiert und das Android-Binder-Objekt abruft:

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:Ein detaillierteres Beispiel eines gebundenen Dienstes für einen Synchronisierungsadapter finden Sie in der Beispiel-App.

Für das Framework erforderliches Konto hinzufügen

Im Synchronisierungsadapter-Framework muss jeder Synchronisierungsadapter einen Kontotyp haben. Sie haben den Wert des Kontotyps im Abschnitt Authenticator-Metadatendatei hinzufügen deklariert. Jetzt müssen Sie diesen Kontotyp im Android-System einrichten. Fügen Sie zum Einrichten des Kontotyps ein Platzhalterkonto hinzu, das den Kontotyp verwendet. Rufen Sie dazu addAccountExplicitly() auf.

Am besten rufen Sie die Methode in der Methode onCreate() der Öffnungsaktivität Ihrer App auf. Das folgende Code-Snippet zeigt, wie das funktioniert:

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.
             */
        }
    }
    ...
}

Datei mit Metadaten für den Synchronisierungsadapter hinzufügen

Damit Sie die Synchronisierungsadapterkomponente mit dem Framework verbinden können, müssen Sie dem Framework Metadaten zur Verfügung stellen, die die Komponente beschreiben und zusätzliche Flags angeben. Die Metadaten geben den Kontotyp an, den Sie für Ihren Synchronisierungsadapter erstellt haben, eine Contentanbieter-Zertifizierungsstelle für Ihre App, steuern einen Teil der Systembenutzeroberfläche für Synchronisierungsadapter und deklarieren andere Flags für die Synchronisierung. Geben Sie diese Metadaten in einer speziellen XML-Datei an, die im Verzeichnis /res/xml/ Ihres Anwendungsprojekts gespeichert ist. Sie können der Datei einen beliebigen Namen geben. Normalerweise heißt sie aber syncadapter.xml.

Diese XML-Datei enthält das einzelne XML-Element <sync-adapter> mit den folgenden Attributen:

android:contentAuthority
Die URI-Zertifizierungsstelle für Ihren Contentanbieter. Wenn Sie in der vorherigen Lektion Stub-Contentanbieter erstellen einen Stub-Contentanbieter für Ihre Anwendung erstellt haben, verwenden Sie den Wert, den Sie für das Attribut android:authorities im Element <provider> angegeben haben, das Sie Ihrem App-Manifest hinzugefügt haben. Dieses Attribut wird im Abschnitt Anbieter im Manifest deklarieren ausführlicher beschrieben.
Wenn Sie mit Ihrem Synchronisierungsadapter Daten von einem Contentanbieter auf einen Server übertragen, sollte dieser Wert mit der Content-URI-Zertifizierungsstelle übereinstimmen, die Sie für diese Daten verwenden. Dieser Wert ist auch eine der Zertifizierungsstellen, die Sie im Attribut android:authorities des Elements <provider> angeben, das Ihren Anbieter in Ihrem App-Manifest deklariert.
android:accountType
Der für das Synchronisierungsadapter-Framework erforderliche Kontotyp. Der Wert muss mit dem Wert des Kontotyps übereinstimmen, den Sie beim Erstellen der Authenticator-Metadatendatei angegeben haben, wie im Abschnitt Authenticator-Metadatendatei hinzufügen beschrieben. Es ist auch der Wert, den Sie im Code-Snippet im Abschnitt Vom Framework erforderliches Konto hinzufügen für die Konstante ACCOUNT_TYPE angegeben haben.
Einstellungsattribute
android:userVisible
Legt die Sichtbarkeit des Kontotyps des Synchronisierungsadapters fest. Standardmäßig sind das Kontosymbol und das mit dem Kontotyp verknüpfte Label im Bereich Konten der Einstellungen des Systems sichtbar. Ihr Synchronisierungsadapter sollte daher unsichtbar sein, es sei denn, Sie haben einen Kontotyp oder eine Domain, die sich leicht mit Ihrer App verknüpfen lässt. Wenn Sie Ihren Kontotyp unsichtbar machen, können Sie Nutzern trotzdem erlauben, Ihren Synchronisierungsadapter über eine Benutzeroberfläche in einer der Aktivitäten Ihrer App zu steuern.
android:supportsUploading
Ermöglicht das Hochladen von Daten in die Cloud. Lege dafür false fest, wenn deine App nur Daten herunterlädt.
android:allowParallelSyncs
Ermöglicht die gleichzeitige Ausführung mehrerer Instanzen Ihrer Synchronisierungsadapterkomponente. Verwenden Sie diese Option, wenn Ihre Anwendung mehrere Nutzerkonten unterstützt und mehrere Nutzer gleichzeitig Daten übertragen können. Dieses Flag hat keine Auswirkungen, wenn Sie nie mehrere Datenübertragungen ausführen.
android:isAlwaysSyncable
Gibt dem Synchronisierungsadapter-Framework an, dass es den Synchronisierungsadapter jederzeit ausführen kann. Wenn Sie programmatisch steuern möchten, wann Ihr Synchronisierungsadapter ausgeführt wird, setzen Sie dieses Flag auf false und rufen Sie dann requestSync() auf, um den Synchronisierungsadapter auszuführen. Weitere Informationen zum Ausführen eines Synchronisierungsadapters finden Sie in der Lektion Synchronisierungsadapter ausführen.

Das folgende Beispiel zeigt den XML-Code für einen Synchronisierungsadapter, der ein einzelnes Platzhalterkonto verwendet und nur Downloads ermöglicht.

<?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 Ihrer App die Synchronisierungsadapterkomponente hinzugefügt haben, müssen Sie Berechtigungen für die Verwendung der Komponente anfordern und die gebundene Service deklarieren, die Sie hinzugefügt haben.

Da die Synchronisierungsadapterkomponente Code ausführt, der Daten zwischen dem Netzwerk und dem Gerät überträgt, müssen Sie die Berechtigung für den Zugriff auf das Internet anfordern. Darüber hinaus muss Ihre App die Berechtigung zum Lesen und Schreiben der Synchronisierungsadaptereinstellungen anfordern, damit Sie den Synchronisierungsadapter programmatisch von anderen Komponenten in der App steuern können. Außerdem müssen Sie eine spezielle Berechtigung anfordern, damit Ihre App die Authentifizierungskomponente verwenden kann, die Sie in der Lektion Stub Authenticator erstellen erstellt haben.

Wenn du diese Berechtigungen anfordern möchtest, füge deinem App-Manifest Folgendes als untergeordnete Elemente von <manifest> hinzu:

android.permission.INTERNET
Mit dieser Einstellung kann der Code des Synchronisierungsadapters auf das Internet zugreifen, um Daten vom Gerät herunter- oder auf einen Server hochzuladen. Sie müssen diese Berechtigung nicht noch einmal hinzufügen, wenn Sie sie schon einmal angefordert haben.
android.permission.READ_SYNC_SETTINGS
Ermöglicht der App, die aktuellen Einstellungen des Synchronisierungsadapters zu lesen. Beispielsweise brauchen Sie diese Berechtigung, um getIsSyncable() aufzurufen.
android.permission.WRITE_SYNC_SETTINGS
Ermöglicht der App, die Einstellungen für den Synchronisierungsadapter zu steuern. Sie benötigen diese Berechtigung, um regelmäßige Synchronisierungsadapterausführungen mit addPeriodicSync() festzulegen. Diese Berechtigung ist für den Aufruf von requestSync() nicht erforderlich. Weitere Informationen zum Ausführen des Synchronisierungsadapters finden Sie 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>

Um schließlich das gebundene Service zu deklarieren, das das Framework für die Interaktion mit Ihrem Synchronisierungsadapter verwendet, fügen Sie Ihrem App-Manifest als untergeordnetes Element von <application> den folgenden XML-Code hinzu:

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

Das Element <intent-filter> richtet einen Filter ein, der von der Intent-Aktion android.content.SyncAdapter ausgelöst wird, die vom System zum Ausführen des Synchronisierungsadapters gesendet wird. Wenn der Filter ausgelöst wird, startet das System den von Ihnen erstellten gebundenen Dienst, in diesem Beispiel SyncService. Das Attribut android:exported="false" ermöglicht nur Ihrer App und dem System den Zugriff auf Service. Das Attribut android:process=":sync" weist das System an, Service in einem globalen freigegebenen Prozess namens sync auszuführen. Wenn Sie in Ihrer App mehrere Synchronisierungsadapter haben, können diese diesen Prozess teilen, was den Aufwand reduziert.

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

Sie haben jetzt alle Komponenten für Ihren Synchronisierungsadapter. In der nächsten Lektion erfahren Sie, wie Sie das Synchronisierungsadapter-Framework anweisen können, den Synchronisierungsadapter entweder als Reaktion auf ein Ereignis oder nach einem regelmäßigen Zeitplan auszuführen.