Senkronizasyon bağdaştırıcısı çalıştırma

Not: Arka planda işleme özelliklerinin çoğu için önerilen çözüm olarak WorkManager'ı öneriyoruz. Size en uygun çözümü öğrenmek için lütfen arka planda işleme kılavuzuna göz atın.

Bu sınıfın önceki derslerinde, veri aktarım kodunu içeren bir senkronizasyon adaptörü bileşeninin nasıl oluşturulacağını ve senkronizasyon adaptörünü sisteme bağlamanızı sağlayan ek bileşenlerin nasıl ekleneceğini öğrendiniz. Artık senkronizasyon bağdaştırıcısı içeren bir uygulama yüklemek için ihtiyacınız olan her şeye sahipsiniz, ancak gördüğünüz kodların hiçbiri aslında senkronizasyon bağdaştırıcısını çalıştırmıyor.

Senkronizasyon bağdaştırıcınızı bir programa göre veya bir etkinliğin dolaylı sonucu olarak çalıştırmayı denemelisiniz. Örneğin, senkronizasyon bağdaştırıcınızın belirli bir süre sonra veya günün belirli bir saatinde düzenli bir şekilde çalışmasını isteyebilirsiniz. Cihazda depolanan verilerde değişiklikler olduğunda da senkronizasyon adaptörünüzü çalıştırmak isteyebilirsiniz. Senkronizasyon bağdaştırıcınızı bir kullanıcı işleminin doğrudan sonucu olarak çalıştırmaktan kaçınmalısınız. Bunu yaptığınızda senkronizasyon bağdaştırıcısı çerçevesinin planlama özelliğinden tam olarak yararlanamazsınız. Örneğin, kullanıcı arayüzünde yenileme düğmesi eklemekten kaçınmalısınız.

Senkronizasyon bağdaştırıcınızı çalıştırmak için aşağıdaki seçenekleri kullanabilirsiniz:

Sunucu verileri değiştiğinde
Sunucu tabanlı verilerin değiştiğini belirten bir mesaja yanıt olarak senkronizasyon bağdaştırıcısını çalıştırın. Bu seçenek, performansı düşürmeden veya sunucuyu yoklayarak pil ömrünü harcamadan sunucudan cihaza verileri yenilemenize olanak tanır.
Cihaz verileri değiştiğinde
Cihazdaki veriler değiştiğinde bir senkronizasyon adaptörü çalıştırın. Bu seçenek, değiştirilmiş verileri cihazdan bir sunucuya göndermenize olanak tanır ve özellikle sunucunun her zaman en güncel cihaz verilerine sahip olmasını sağlamanız gerektiğinde yararlı olur. İçerik sağlayıcınızda gerçekten veri depoluyorsanız bu seçeneğin uygulanması oldukça kolaydır. Bir saplama içeriği sağlayıcısı kullanıyorsanız veri değişikliklerini algılamak daha zor olabilir.
Düzenli aralıklarla
Seçtiğiniz aralığın süresi dolduktan sonra senkronizasyon bağdaştırıcısını çalıştırın veya her gün belirli bir zamanda çalıştırın.
İstek üzerine
Kullanıcı işlemine yanıt olarak senkronizasyon bağdaştırıcısını çalıştırın. Ancak en iyi kullanıcı deneyimini sağlamak için öncelikli olarak daha otomatik seçeneklerden birini kullanmalısınız. Otomatik seçenekleri kullanarak pil ve ağ kaynaklarından tasarruf edersiniz.

Bu dersin geri kalanında, bu seçenekler her biri ayrıntılı olarak açıklanmaktadır.

Sunucu verileri değiştiğinde senkronizasyon bağdaştırıcısını çalıştırma

Uygulamanız bir sunucudan veri aktarıyorsa ve sunucu verileri sık sık değişiyorsa veri değişikliklerine yanıt olarak indirme işlemi yapmak için bir senkronizasyon bağdaştırıcısı kullanabilirsiniz. Senkronizasyon bağdaştırıcısını çalıştırmak için sunucunun uygulamanızdaki bir BroadcastReceiver öğesine özel bir mesaj göndermesini sağlayın. Bu mesaja yanıt olarak, senkronizasyon bağdaştırıcısı çerçevesine senkronizasyon bağdaştırıcınızı çalıştırmak üzere sinyal vermek için ContentResolver.requestSync() çağrısı yapın.

Google Cloud Messaging (GCM), bu mesajlaşma sisteminin çalışması için ihtiyacınız olan hem sunucu hem de cihaz bileşenlerini sağlar. Aktarımları tetiklemek için GCM'yi kullanmak, durum için yoklama sunucularına göre daha güvenilir ve daha verimlidir. Yoklama işlemi için her zaman etkin olan bir Service gerekirken GCM tarafından, ileti geldiğinde etkinleştirilen bir BroadcastReceiver kullanılır. Düzenli aralıklarla yoklama yaparken, herhangi bir güncelleme olmasa bile pil gücünü kullanır. GCM tarafından yalnızca gerektiğinde mesaj gönderilir.

Not: Uygulamanızın yüklü olduğu tüm cihazlara yapılan bir yayın aracılığıyla senkronizasyon bağdaştırıcınızı tetiklemek için GCM'yi kullanıyorsanız mesajınızın yaklaşık olarak aynı zamanda aldıklarını unutmayın. Bu durum, senkronizasyon bağdaştırıcınızın birden fazla örneğinin aynı anda çalışmasına ve dolayısıyla sunucu ve ağda aşırı yük oluşmasına neden olabilir. Tüm cihazlara yayın yapıldığında bu durumu önlemek için senkronizasyon bağdaştırıcısının başlangıcını her cihazda benzersiz bir süreye ertelemeyi düşünmeniz gerekir.

Aşağıdaki kod snippet'i, gelen bir GCM mesajına yanıt olarak requestSync() hizmetinin nasıl çalıştırılacağını gösterir:

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

İçerik sağlayıcı verileri değiştiğinde senkronizasyon adaptörünü çalıştır

Uygulamanız bir içerik sağlayıcıda veri topluyorsa ve sağlayıcıyı her güncellediğinizde sunucuyu güncellemek istiyorsanız uygulamanızı senkronizasyon bağdaştırıcınızı otomatik olarak çalıştıracak şekilde ayarlayabilirsiniz. Bunu yapmak için içerik sağlayıcı için bir gözlemci kaydedersiniz. İçerik sağlayıcınızdaki veriler değiştiğinde, içerik sağlayıcı çerçevesi gözlemciyi çağırır. Gözlemcide, çerçeveye senkronizasyon bağdaştırıcınızı çalıştırmasını bildirmek için requestSync() çağrısı yapın.

Not: Kaba içerik sağlayıcı kullanıyorsanız içerik sağlayıcıda hiç veriniz olmaz ve onChange() hiçbir zaman çağrılmaz. Bu durumda, cihaz verilerindeki değişiklikleri algılamak için kendi mekanizmanızı sağlamanız gerekir. Bu mekanizma, veriler değiştiğinde requestSync() çağrısından da sorumludur.

İçerik sağlayıcınız için bir gözlemci oluşturmak istiyorsanız ContentObserver sınıfını genişletin ve onChange() yönteminin her iki biçimini de uygulayın. onChange() ürününde, senkronizasyon bağdaştırıcısını başlatmak için requestSync() çağrısı yapın.

Gözlemciyi kaydetmek için registerContentObserver() çağrısında bağımsız değişken olarak iletin. Bu çağrıda, izlemek istediğiniz veriler için bir içerik URI'si iletmeniz de gerekir. İçerik sağlayıcı çerçevesi, bu izleme URI'sini sağlayıcınızı değiştiren ContentResolver yöntemlerine (ör. ContentResolver.insert()) bağımsız değişken olarak aktarılan içerik URI'leriyle karşılaştırır. Eşleşme varsa ContentObserver.onChange() uygulamanız çağrılır.

Aşağıdaki kod snippet'i, bir tablo değiştiğinde requestSync() çağrısı yapan bir ContentObserver öğesini nasıl tanımlayacağınızı gösterir:

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

Senkronizasyon bağdaştırıcısını düzenli aralıklarla çalıştırma

Senkronizasyon bağdaştırıcınızı çalıştırmalar arasında beklenecek bir süre ayarlayarak, günün belirli saatlerinde çalıştırarak ya da her ikisini birden yaparak düzenli aralıklarla çalıştırabilirsiniz. Senkronizasyon bağdaştırıcınızı düzenli aralıklarla çalıştırmak, sunucunuzun güncelleme aralığıyla yaklaşık olarak eşleşmenize olanak tanır.

Benzer şekilde, senkronizasyon bağdaştırıcınızı gece çalışacak şekilde planlayarak sunucunuz nispeten boştayken cihazdan veri yükleyebilirsiniz. Çoğu kullanıcı geceleri güçlerini açık ve fişe takılı bıraktığından bu saat genellikle uygun olur. Ayrıca cihaz, senkronizasyon adaptörünüzle aynı anda diğer görevleri çalıştırmıyordur. Ancak bu yaklaşımı benimserseniz her cihazın veri aktarımını biraz farklı bir zamanda tetiklediğinden emin olmanız gerekir. Tüm cihazlar senkronizasyon bağdaştırıcınızı aynı anda çalıştırıyorsa sunucu ve hücresel sağlayıcı veri ağlarınızda aşırı yüklenmeye yol açmış olabilirsiniz.

Periyodik çalıştırmalar genel olarak kullanıcılarınızın anlık güncellemelere ihtiyaç duymayıp düzenli olarak güncelleme yapmasını bekliyorsa anlamlıdır. Periyodik çalıştırmalar, güncel verilerin kullanılabilirliğini, cihaz kaynaklarını aşırı kullanmayan küçük senkronizasyon bağdaştırıcı çalıştırmalarının verimliliğiyle dengelemek istediğinizde de mantıklıdır.

Senkronizasyon bağdaştırıcınızı düzenli aralıklarla çalıştırmak için addPeriodicSync() numaralı telefonu arayın. Bu işlem, senkronizasyon bağdaştırıcınızı belirli bir süre sonra çalışacak şekilde programlar. Senkronizasyon adaptörü çerçevesinin diğer senkronizasyon adaptörü yürütmelerini de hesaba katması ve pil verimliliğini en üst düzeye çıkarmaya çalışması gerektiğinden, geçen süre birkaç saniye farklılık gösterebilir. Ayrıca ağ yoksa çerçeve, senkronizasyon bağdaştırıcınızı çalıştırmaz.

addPeriodicSync() politikasının, senkronizasyon bağdaştırıcısını günün belirli bir saatinde çalıştırmadığına dikkat edin. Senkronizasyon adaptörünüzü her gün yaklaşık olarak aynı saatte çalıştırmak için tetikleyici olarak yinelenen bir alarm kullanın. Tekrarlanan alarmlar, AlarmManager referans dokümanlarında daha ayrıntılı açıklanmıştır. Bazı farklılıklara sahip günün saati tetikleyicileri ayarlamak için setInexactRepeating() yöntemini kullanıyorsanız senkronizasyon bağdaştırıcısının farklı cihazlardan çalıştığından emin olmak için yine de başlangıç zamanını rastgele hale getirmeniz gerekir.

addPeriodicSync() yöntemi setSyncAutomatically() öğesini devre dışı bırakmaz. Bu nedenle, nispeten kısa bir süre içinde birden fazla senkronizasyon işlemi alabilirsiniz. Ayrıca addPeriodicSync() çağrısında yalnızca birkaç senkronizasyon bağdaştırıcısı kontrol bayrağına izin verilir. İzin verilmeyen işaretler addPeriodicSync() için başvurulan dokümanlarda açıklanmaktadır.

Aşağıdaki kod snippet'inde, periyodik senkronizasyon bağdaştırıcısı çalıştırmalarının nasıl planlanacağı gösterilmektedir:

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

Senkronizasyon bağdaştırıcısını isteğe bağlı olarak çalıştırma

Senkronizasyon bağdaştırıcınızı bir kullanıcı isteğine yanıt olarak çalıştırmak, senkronizasyon bağdaştırıcısını çalıştırmak için en az tercih edilen stratejidir. Çerçeve, senkronizasyon adaptörlerini bir programa göre çalıştırırken pil gücünden tasarruf etmek için özel olarak tasarlanmıştır. Veri değişikliklerine yanıt olarak senkronizasyon gerçekleştiren seçenekler, yeni verileri sağlamak için güç kullanıldığından, pil gücünü verimli bir şekilde kullanır.

Buna karşılık, kullanıcıların istek üzerine senkronizasyon çalıştırabilmesi, senkronizasyonun kendi başına çalışması anlamına gelir. Bu da ağ ve güç kaynaklarının verimsiz bir şekilde kullanılmasına neden olur. Ayrıca, istek üzerine senkronizasyon sağlanması, verilerin değiştiğine dair bir kanıt olmasa bile kullanıcıların senkronizasyon isteğinde bulunmasına neden olur. Verileri yenilemeyen bir senkronizasyon çalıştırmak, pil gücünün etkisiz bir kullanımıdır. Genel olarak uygulamanız, senkronizasyonu tetiklemek için diğer sinyalleri kullanmalıdır ya da kullanıcı girişi olmadan düzenli aralıklarla planlamalıdır.

Ancak senkronizasyon bağdaştırıcısını isteğe bağlı olarak çalıştırmaya devam etmek istiyorsanız manuel senkronizasyon bağdaştırıcısı bayraklarını ayarlayıp ContentResolver.requestSync() yöntemini çağırın.

Aşağıdaki işaretlerle isteğe bağlı aktarımlar çalıştırın:

SYNC_EXTRAS_MANUAL
Manuel senkronizasyonu zorunlu kılar. Senkronizasyon bağdaştırıcısı çerçevesi, setSyncAutomatically() tarafından ayarlanan işaret gibi mevcut ayarları yoksayar.
SYNC_EXTRAS_EXPEDITED
Senkronizasyonun hemen başlatılmasını sağlar. Bu seçeneği ayarlamazsanız kısa bir süre içinde çok sayıda istek planlayarak pil kullanımını optimize etmeye çalıştığından sistem, senkronizasyon isteğini çalıştırmadan önce birkaç saniye bekleyebilir.

Aşağıdaki kod snippet'i, düğme tıklamasına yanıt olarak requestSync() çağrısının nasıl yapılacağını gösterir:

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