Synchronisierungsadapter ausführen

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.

In den vorherigen Lektionen in diesem Kurs haben Sie gelernt, wie Sie eine Synchronisierungsadapterkomponente erstellen, die Datenübertragungscode enthält, und wie Sie zusätzliche Komponenten hinzufügen, mit denen Sie den Synchronisierungsadapter an das System anschließen können. Sie haben jetzt alles, was Sie zum Installieren einer App mit einem Synchronisierungsadapter benötigen, aber über den Code, den Sie gesehen haben, wird der Synchronisierungsadapter nicht ausgeführt.

Sie sollten versuchen, den Synchronisierungsadapter nach einem Zeitplan oder indirekt durch ein Ereignis auszuführen. Angenommen, der Synchronisierungsadapter soll nach einem regelmäßigen Zeitplan ausgeführt werden, entweder nach einem bestimmten Zeitraum oder zu einer bestimmten Tageszeit. Sie können den Synchronisierungsadapter auch bei Änderungen an den auf dem Gerät gespeicherten Daten ausführen. Sie sollten den Synchronisierungsadapter nicht als direkte Folge einer Nutzeraktion ausführen, da Sie so nicht den vollen Nutzen der Planungsfähigkeiten des Synchronisierungsadapter-Frameworks nutzen können. Du solltest es beispielsweise vermeiden, auf deiner Benutzeroberfläche eine Aktualisierungsschaltfläche bereitzustellen.

Sie haben folgende Möglichkeiten, den Synchronisierungsadapter auszuführen:

Wenn sich Serverdaten ändern
Führen Sie den Synchronisierungsadapter als Antwort auf eine Nachricht von einem Server aus, die darauf hinweist, dass sich die serverbasierten Daten geändert haben. Mit dieser Option können Sie Daten vom Server auf das Gerät aktualisieren, ohne durch eine Serverabfrage die Leistung zu beeinträchtigen oder die Akkulaufzeit zu verschwenden.
Wenn sich Gerätedaten ändern
Führen Sie einen Synchronisierungsadapter aus, wenn sich Daten auf dem Gerät ändern. Mit dieser Option können geänderte Daten vom Gerät an einen Server gesendet werden. Dies ist besonders nützlich, wenn Sie dafür sorgen müssen, dass immer die neuesten Gerätedaten auf dem Server verfügbar sind. Diese Option lässt sich einfach implementieren, wenn Sie Daten tatsächlich bei Ihrem Contentanbieter speichern. Wenn Sie einen Stub-Inhaltsanbieter verwenden, kann es schwieriger sein, Datenänderungen zu erkennen.
In regelmäßigen Abständen
Führen Sie einen Synchronisierungsadapter nach Ablauf eines von Ihnen festgelegten Intervalls oder täglich zu einer bestimmten Zeit aus.
On demand
Führen Sie den Synchronisierungsadapter als Reaktion auf eine Nutzeraktion aus. Für eine optimale Nutzererfahrung sollten Sie sich jedoch in erster Linie auf eine der eher automatisierten Optionen verlassen. Durch die Verwendung automatischer Optionen sparen Sie Akku- und Netzwerkressourcen.

Im weiteren Verlauf dieser Lektion werden die einzelnen Optionen ausführlicher beschrieben.

Synchronisierungsadapter ausführen, wenn sich Serverdaten ändern

Wenn Ihre App Daten von einem Server überträgt und sich die Serverdaten häufig ändern, können Sie mit einem Synchronisierungsadapter Downloads als Reaktion auf Datenänderungen durchführen. Um den Synchronisierungsadapter auszuführen, muss der Server eine spezielle Nachricht an einen BroadcastReceiver in Ihrer App senden. Rufen Sie als Antwort auf diese Nachricht ContentResolver.requestSync() auf, um dem Synchronisierungsadapter-Framework zu signalisieren, dass Ihr Synchronisierungsadapter ausgeführt wird.

Google Cloud Messaging (GCM) stellt sowohl die Server- als auch die Gerätekomponenten bereit, die für das Funktionieren dieses Nachrichtensystems erforderlich sind. Die Verwendung von GCM zum Auslösen von Übertragungen ist zuverlässiger und effizienter als die Statusabfrage durch Server. Während für das Abfragen eine Service erforderlich ist, die immer aktiv ist, verwendet GCM ein BroadcastReceiver, das aktiviert wird, wenn eine Nachricht eingeht. Während die Abfrage in regelmäßigen Intervallen Akkuleistung verbraucht, auch wenn keine Updates verfügbar sind, sendet GCM Nachrichten nur bei Bedarf.

Hinweis: Wenn Sie GCM verwenden, um Ihren Synchronisierungsadapter über eine Übertragung an alle Geräte, auf denen Ihre App installiert ist, auszulösen, denken Sie daran, dass diese die Nachricht ungefähr zur gleichen Zeit empfangen. Dies kann dazu führen, dass mehrere Instanzen Ihres Synchronisierungsadapters gleichzeitig ausgeführt werden, was zu einer Server- und Netzwerküberlastung führt. Um diese Situation für eine Übertragung an alle Geräte zu vermeiden, sollten Sie das Starten des Synchronisierungsadapters für einen Zeitraum aufschieben, der für jedes Gerät eindeutig ist.

Das folgende Code-Snippet zeigt, wie requestSync() als Antwort auf eine eingehende GCM-Nachricht ausgeführt wird:

Kotlin

...
// Constants
// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Account type
const val ACCOUNT_TYPE = "com.example.android.datasync"
// Account
const val ACCOUNT = "default_account"
// Incoming Intent key for extended data
const val KEY_SYNC_REQUEST = "com.example.android.datasync.KEY_SYNC_REQUEST"
...
class GcmBroadcastReceiver : BroadcastReceiver() {
    ...
    override fun onReceive(context: Context, intent: Intent) {
        // Get a GCM object instance
        val gcm: GoogleCloudMessaging = GoogleCloudMessaging.getInstance(context)
        // Get the type of GCM message
        val messageType: String? = gcm.getMessageType(intent)
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE == messageType
            && intent.getBooleanExtra(KEY_SYNC_REQUEST, false)) {
            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null)
            ...
        }
        ...
    }
    ...
}

Java

public class GcmBroadcastReceiver extends BroadcastReceiver {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Account type
    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
    // Account
    public static final String ACCOUNT = "default_account";
    // Incoming Intent key for extended data
    public static final String KEY_SYNC_REQUEST =
            "com.example.android.datasync.KEY_SYNC_REQUEST";
    ...
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get a GCM object instance
        GoogleCloudMessaging gcm =
                GoogleCloudMessaging.getInstance(context);
        // Get the type of GCM message
        String messageType = gcm.getMessageType(intent);
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)
            &&
            intent.getBooleanExtra(KEY_SYNC_REQUEST)) {
            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null);
            ...
        }
        ...
    }
    ...
}

Synchronisierungsadapter ausführen, wenn sich die Daten des Contentanbieters ändern

Wenn Ihre App Daten bei einem Contentanbieter erhebt und Sie den Server bei jeder Aktualisierung des Anbieters aktualisieren möchten, können Sie Ihre App so einrichten, dass der Synchronisierungsadapter automatisch ausgeführt wird. Dazu registrieren Sie einen Beobachter für den Inhaltsanbieter. Wenn sich Daten in Ihrem Contentanbieter ändern, ruft das Framework des Contentanbieters den Beobachter auf. Rufen Sie im Beobachter requestSync() auf, um dem Framework mitzuteilen, dass Ihr Synchronisierungsadapter ausgeführt werden soll.

Hinweis: Wenn Sie einen Stub-Inhaltsanbieter verwenden, liegen im Inhaltsanbieter keine Daten vor und onChange() wird nie aufgerufen. In diesem Fall müssen Sie einen eigenen Mechanismus bereitstellen, um Änderungen an Gerätedaten zu erkennen. Dieser Mechanismus ist auch für den Aufruf von requestSync() verantwortlich, wenn sich die Daten ändern.

Erweitern Sie die Klasse ContentObserver und implementieren Sie beide Formen der Methode onChange(), um einen Beobachter für Ihren Inhaltsanbieter zu erstellen. Rufen Sie in onChange() requestSync() auf, um den Synchronisierungsadapter zu starten.

Übergeben Sie den Beobachter als Argument in einem Aufruf von registerContentObserver(), um ihn zu registrieren. Bei diesem Aufruf müssen Sie auch einen Inhalts-URI für die Daten übergeben, die Sie sich ansehen möchten. Das Contentanbieter-Framework vergleicht diesen Watch-URI mit Inhalts-URIs, die als Argumente an ContentResolver-Methoden übergeben werden, die Ihren Anbieter ändern, z. B. ContentResolver.insert(). Bei einer Übereinstimmung wird Ihre Implementierung von ContentObserver.onChange() aufgerufen.

Das folgende Code-Snippet zeigt, wie Sie ein ContentObserver definieren, das requestSync() aufruft, wenn sich eine Tabelle ändert:

Kotlin

// Constants
// Content provider scheme
const val SCHEME = "content://"
// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Path for the content provider table
const val TABLE_PATH = "data_table"
...
class MainActivity : FragmentActivity() {
    ...
    // A content URI for the content provider's data table
    private lateinit var uri: Uri
    // A content resolver for accessing the provider
    private lateinit var mResolver: ContentResolver
    ...
    inner class TableObserver(...) : ContentObserver(...) {
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         * This method signature is provided for compatibility with
         * older platforms.
         */
        override fun onChange(selfChange: Boolean) {
            /*
             * Invoke the method signature available as of
             * Android platform version 4.1, with a null URI.
             */
            onChange(selfChange, null)
        }

        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         */
        override fun onChange(selfChange: Boolean, changeUri: Uri?) {
            /*
             * Ask the framework to run your sync adapter.
             * To maintain backward compatibility, assume that
             * changeUri is null.
             */
            ContentResolver.requestSync(account, AUTHORITY, null)
        }
        ...
    }
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Get the content resolver object for your app
        mResolver = contentResolver
        // Construct a URI that points to the content provider data table
        uri = Uri.Builder()
                .scheme(SCHEME)
                .authority(AUTHORITY)
                .path(TABLE_PATH)
                .build()
        /*
         * Create a content observer object.
         * Its code does not mutate the provider, so set
         * selfChange to "false"
         */
        val observer = TableObserver(false)
        /*
         * Register the observer for the data table. The table's path
         * and any of its subpaths trigger the observer.
         */
        mResolver.registerContentObserver(uri, true, observer)
        ...
    }
    ...
}

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider scheme
    public static final String SCHEME = "content://";
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Path for the content provider table
    public static final String TABLE_PATH = "data_table";
    // Account
    public static final String ACCOUNT = "default_account";
    // Global variables
    // A content URI for the content provider's data table
    Uri uri;
    // A content resolver for accessing the provider
    ContentResolver mResolver;
    ...
    public class TableObserver extends ContentObserver {
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         * This method signature is provided for compatibility with
         * older platforms.
         */
        @Override
        public void onChange(boolean selfChange) {
            /*
             * Invoke the method signature available as of
             * Android platform version 4.1, with a null URI.
             */
            onChange(selfChange, null);
        }
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         */
        @Override
        public void onChange(boolean selfChange, Uri changeUri) {
            /*
             * Ask the framework to run your sync adapter.
             * To maintain backward compatibility, assume that
             * changeUri is null.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null);
        }
        ...
    }
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Get the content resolver object for your app
        mResolver = getContentResolver();
        // Construct a URI that points to the content provider data table
        uri = new Uri.Builder()
                  .scheme(SCHEME)
                  .authority(AUTHORITY)
                  .path(TABLE_PATH)
                  .build();
        /*
         * Create a content observer object.
         * Its code does not mutate the provider, so set
         * selfChange to "false"
         */
        TableObserver observer = new TableObserver(false);
        /*
         * Register the observer for the data table. The table's path
         * and any of its subpaths trigger the observer.
         */
        mResolver.registerContentObserver(uri, true, observer);
        ...
    }
    ...
}

Synchronisierungsadapter regelmäßig ausführen

Sie können den Synchronisierungsadapter regelmäßig ausführen. Legen Sie dazu eine Zeitspanne zwischen den Ausführungen fest, führen Sie ihn zu bestimmten Tageszeiten aus oder legen Sie beides fest. Wenn Sie den Synchronisierungsadapter regelmäßig ausführen, können Sie ungefähr das Aktualisierungsintervall Ihres Servers anpassen.

Ebenso können Sie Daten vom Gerät hochladen, wenn Ihr Server relativ inaktiv ist. Dazu planen Sie den Synchronisierungsadapter so, dass er nachts ausgeführt wird. Die meisten Nutzer lassen ihr Gerät nachts eingeschaltet und ans Stromnetz angeschlossen, sodass diese Zeit normalerweise verfügbar ist. Außerdem führt das Gerät keine anderen Aufgaben gleichzeitig mit Ihrem Synchronisierungsadapter aus. Wenn Sie so vorgehen, müssen Sie jedoch darauf achten, dass jedes Gerät eine Datenübertragung zu einem etwas anderen Zeitpunkt auslöst. Wenn auf allen Geräten der Synchronisierungsadapter gleichzeitig ausgeführt wird, ist es wahrscheinlich, dass Ihre Server- und Mobilfunkanbieter-Datennetzwerke überlastet werden.

Im Allgemeinen sind regelmäßige Ausführungen sinnvoll, wenn Ihre Nutzer keine sofortigen Updates benötigen, aber regelmäßige Aktualisierungen erwarten. Regelmäßige Ausführungen sind auch sinnvoll, wenn Sie die Verfügbarkeit aktueller Daten mit der Effizienz kleinerer Synchronisierungsadapterausführungen ausgleichen möchten, die die Geräteressourcen nicht übermäßig beanspruchen.

Rufen Sie addPeriodicSync() auf, um den Synchronisierungsadapter in regelmäßigen Abständen auszuführen. Dadurch wird die Ausführung des Synchronisierungsadapters nach einer bestimmten Zeit geplant. Da das Synchronisierungsadapter-Framework andere Synchronisierungsadapterausführungen berücksichtigen muss und versucht, die Akkueffizienz zu maximieren, kann die verstrichene Zeit um einige Sekunden variieren. Außerdem führt das Framework den Synchronisierungsadapter nicht aus, wenn das Netzwerk nicht verfügbar ist.

Beachten Sie, dass addPeriodicSync() den Synchronisierungsadapter nicht zu einer bestimmten Tageszeit ausführt. Wenn der Synchronisierungsadapter jeden Tag etwa zur gleichen Zeit ausgeführt werden soll, können Sie einen sich wiederholenden Wecker als Auslöser verwenden. Wiederkehrende Alarme werden in der Referenzdokumentation zu AlarmManager ausführlicher beschrieben. Wenn Sie die Methode setInexactRepeating() verwenden, um tageszeitbedingte Trigger festzulegen, die eine gewisse Schwankung aufweisen, sollten Sie die Startzeit trotzdem zufällig festlegen, damit die Synchronisierungsadapter von verschiedenen Geräten gestaffelt ausgeführt werden.

Die Methode addPeriodicSync() deaktiviert setSyncAutomatically() nicht, sodass Sie in relativ kurzer Zeit mehrere Synchronisierungsläufe erhalten können. Außerdem sind in einem Aufruf von addPeriodicSync() nur einige Steuer-Flags für den Synchronisierungsadapter zulässig. Welche Flags nicht zulässig sind, werden in der Dokumentation zu addPeriodicSync() beschrieben.

Das folgende Code-Snippet zeigt, wie Sie regelmäßige Synchronisierungsadapterausführungen planen:

Kotlin

// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Account
const val ACCOUNT = "default_account"
// Sync interval constants
const val SECONDS_PER_MINUTE = 60L
const val SYNC_INTERVAL_IN_MINUTES = 60L
const val SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE
...
class MainActivity : FragmentActivity() {
    ...
    // A content resolver for accessing the provider
    private lateinit var mResolver: ContentResolver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Get the content resolver for your app
        mResolver = contentResolver
        /*
         * Turn on periodic syncing
         */
        ContentResolver.addPeriodicSync(
                mAccount,
                AUTHORITY,
                Bundle.EMPTY,
                SYNC_INTERVAL)
        ...
    }
    ...
}

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Account
    public static final String ACCOUNT = "default_account";
    // Sync interval constants
    public static final long SECONDS_PER_MINUTE = 60L;
    public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
    public static final long SYNC_INTERVAL =
            SYNC_INTERVAL_IN_MINUTES *
            SECONDS_PER_MINUTE;
    // Global variables
    // A content resolver for accessing the provider
    ContentResolver mResolver;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Get the content resolver for your app
        mResolver = getContentResolver();
        /*
         * Turn on periodic syncing
         */
        ContentResolver.addPeriodicSync(
                mAccount,
                AUTHORITY,
                Bundle.EMPTY,
                SYNC_INTERVAL);
        ...
    }
    ...
}

Synchronisierungsadapter bei Bedarf ausführen

Das Ausführen des Synchronisierungsadapters als Reaktion auf eine Nutzeranfrage ist die am wenigsten empfohlene Strategie zum Ausführen eines Synchronisierungsadapters. Das Framework wurde speziell dafür entwickelt, den Akku zu schonen, wenn Synchronisierungsadapter gemäß einem Zeitplan ausgeführt werden. Optionen, die als Reaktion auf Datenänderungen eine Synchronisierung durchführen, verbrauchen Strom effektiv, da der Strom für die Bereitstellung neuer Daten verwendet wird.

Wenn Nutzern dagegen ermöglicht wird, eine Synchronisierung bei Bedarf auszuführen, bedeutet dies, dass die Synchronisierung von selbst ausgeführt wird, was eine ineffiziente Nutzung von Netzwerk- und Energieressourcen bedeutet. Bei einer Synchronisierung bei Bedarf können Nutzer auch dann eine Synchronisierung anfordern, wenn es keine Anzeichen dafür gibt, dass sich die Daten geändert haben. Bei einer Synchronisierung, bei der keine Daten aktualisiert werden, wird der Akku ineffizient verbraucht. Im Allgemeinen sollte Ihre Anwendung entweder andere Signale zum Auslösen einer Synchronisierung verwenden oder sie in regelmäßigen Abständen ohne Nutzereingabe planen.

Wenn Sie den Synchronisierungsadapter jedoch weiterhin bei Bedarf ausführen möchten, legen Sie die Flags für den Synchronisierungsadapter für eine manuelle Ausführung fest und rufen Sie dann ContentResolver.requestSync() auf.

Führen Sie On-Demand-Übertragungen mit den folgenden Flags aus:

SYNC_EXTRAS_MANUAL
Erzwingt eine manuelle Synchronisierung. Das Framework für den Synchronisierungsadapter ignoriert die vorhandenen Einstellungen, z. B. das von setSyncAutomatically() festgelegte Flag.
SYNC_EXTRAS_EXPEDITED
Erzwingt einen sofortigen Start der Synchronisierung. Wenn Sie diese Einstellung nicht festlegen, wartet das System möglicherweise mehrere Sekunden, bevor die Synchronisierungsanfrage ausgeführt wird, da versucht wird, den Akkuverbrauch zu optimieren, indem viele Anfragen in kurzer Zeit geplant werden.

Das folgende Code-Snippet zeigt, wie requestSync() als Reaktion auf einen Klick auf eine Schaltfläche aufgerufen wird:

Kotlin

// Constants
// Content provider authority
val AUTHORITY = "com.example.android.datasync.provider"
// Account type
val ACCOUNT_TYPE = "com.example.android.datasync"
// Account
val ACCOUNT = "default_account"
...
class MainActivity : FragmentActivity() {
    ...
    // Instance fields
    private lateinit var mAccount: Account
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        /*
         * Create the placeholder account. The code for CreateSyncAccount
         * is listed in the lesson Creating a Sync Adapter
         */

        mAccount = createSyncAccount()
        ...
    }

    /**
     * Respond to a button click by calling requestSync(). This is an
     * asynchronous operation.
     *
     * This method is attached to the refresh button in the layout
     * XML file
     *
     * @param v The View associated with the method call,
     * in this case a Button
     */
    fun onRefreshButtonClick(v: View) {
        // Pass the settings flags by inserting them in a bundle
        val settingsBundle = Bundle().apply {
            putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true)
            putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true)
        }
        /*
         * Request the sync for the default account, authority, and
         * manual sync settings
         */
        ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle)
    }

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY =
            "com.example.android.datasync.provider";
    // Account type
    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
    // Account
    public static final String ACCOUNT = "default_account";
    // Instance fields
    Account mAccount;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        /*
         * Create the placeholder account. The code for CreateSyncAccount
         * is listed in the lesson Creating a Sync Adapter
         */

        mAccount = CreateSyncAccount(this);
        ...
    }
    /**
     * Respond to a button click by calling requestSync(). This is an
     * asynchronous operation.
     *
     * This method is attached to the refresh button in the layout
     * XML file
     *
     * @param v The View associated with the method call,
     * in this case a Button
     */
    public void onRefreshButtonClick(View v) {
        // Pass the settings flags by inserting them in a bundle
        Bundle settingsBundle = new Bundle();
        settingsBundle.putBoolean(
                ContentResolver.SYNC_EXTRAS_MANUAL, true);
        settingsBundle.putBoolean(
                ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
        /*
         * Request the sync for the default account, authority, and
         * manual sync settings
         */
        ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);
    }