اجرا کردن وفق‌دهنده همگام‌سازی

توجه: WorkManager را به‌عنوان راهکار توصیه‌شده برای اکثر موارد استفاده از پردازش پس‌زمینه‌ای توصیه می‌کنیم. لطفاً به راهنمای پردازش پس‌زمینه مراجعه کنید تا ببینید کدام راه‌حل برای شما مناسب‌تر است.

در درس‌های قبلی این کلاس، با نحوه ایجاد مؤلفه وفق‌دهنده همگام‌سازی که کد انتقال داده را کپسوله می‌کند و نحوه افزودن مؤلفه‌های اضافی که به شما امکان می‌دهد وفق‌دهنده همگام‌سازی را به سیستم متصل کنید آشنا شدید. اکنون هرآنچه را که برای نصب برنامه‌ای که شامل وفق‌دهنده همگام‌سازی است نیاز دارید دراختیار دارید، اما هیچ‌کدام از کدهایی که دیده‌اید درواقع وفق‌دهنده همگام‌سازی را اجرا نمی‌کند.

باید سعی کنید وفق‌دهنده همگام‌سازی را براساس زمان‌بندی یا به‌عنوان نتیجه غیرمستقیم برخی رویدادها اجرا کنید. برای مثال، ممکن است بخواهید وفق‌دهنده همگام‌سازی شما طبق زمان‌بندی منظمی اجرا شود، یا پس‌از مدت زمان مشخصی یا در زمان خاصی از روز. همچنین ممکن است بخواهید وفق‌دهنده همگام‌سازی‌تان را وقتی اجرا کنید که تغییراتی در داده‌های ذخیره‌شده در دستگاه ایجاد می‌شود. باید از اجرای وفق‌دهنده همگام‌سازی به‌عنوان نتیجه مستقیم کنش کاربر اجتناب کنید، زیرا با انجام این کار، از مزیت کامل توانایی زمان‌بندی چارچوب وفق‌دهنده همگام‌سازی بهره‌مند نمی‌شوید. برای مثال، باید از ارائه دکمه بازآوری در میانای کاربر خودداری کنید.

گزینه‌های زیر را برای اجرای وفق‌دهنده همگام‌سازی دارید:

وقتی داده‌های سرور تغییر می‌کند
وفق‌دهنده همگام‌سازی را در پاسخ به پیامی از سرور اجرا کنید، که نشان می‌دهد داده‌های مبتنی بر سرور تغییر کرده است. این گزینه به شما امکان می‌دهد داده‌ها را از سرور به دستگاه بازآوری کنید بدون اینکه با نظرسنجی از سرور، عملکرد را کاهش دهید یا عمر باتری را هدر دهید.
وقتی داده‌های دستگاه تغییر می‌کند
وقتی داده‌ها در دستگاه تغییر می‌کند، وفق‌دهنده همگام‌سازی را اجرا کنید. این گزینه به شما امکان می‌دهد داده‌های اصلاح‌شده را از دستگاه به سرور ارسال کنید، و به‌ویژه اگر لازم باشد مطمئن شوید که سرور همیشه جدیدترین داده‌های دستگاه را دارد مفید است. اگر واقعاً داده‌ها را در ارائه‌دهنده محتوایتان ذخیره می‌کنید، پیاده‌سازی این گزینه ساده است. اگر از ارائه‌دهنده محتوای ساختگی استفاده می‌کنید، تشخیص تغییرات داده ممکن است دشوارتر باشد.
در فواصل زمانی منظم
وفق‌دهنده همگام‌سازی را پس‌از انقضای بازه زمانی انتخابی‌تان اجرا کنید، یا آن را در زمان مشخصی در هر روز اجرا کنید.
در صورت درخواست
وفق‌دهنده همگام‌سازی را در پاسخ به کنش کاربر اجرا کنید. بااین‌حال، برای ارائه بهترین تجربه کاربری، باید عمدتاً به یکی از گزینه‌های خودکارتر تکیه کنید. بااستفاده از گزینه‌های خودکارشده، در مصرف باتری و منابع شبکه صرفه‌جویی می‌کنید.

بقیه این درس هریک از گزینه‌ها را با جزئیات بیشتر شرح می‌دهد.

اجرای وفق‌دهنده همگام‌سازی هنگام تغییر داده‌های سرور

اگر برنامه‌تان داده‌ها را از سرور منتقل می‌کند و داده‌های سرور مکرراً تغییر می‌کند، می‌توانید از وفق‌دهنده همگام‌سازی برای بارگیری در پاسخ به تغییرات داده‌ها استفاده کنید. برای اجرای وفق‌دهنده همگام‌سازی، سرور باید پیام ویژه‌ای به BroadcastReceiver در برنامه‌تان ارسال کند. در پاسخ به این پیام، ContentResolver.requestSync() را فراخوانی کنید تا به چارچوب وفق‌دهنده همگام‌سازی علامت دهد که وفق‌دهنده همگام‌سازی شما را اجرا کند.

سیستم پیام‌رسانی Google Cloud (GCM) هم مؤلفه‌های سرور و هم مؤلفه‌های دستگاه را که برای کار کردن این سیستم پیام‌رسانی نیاز دارید ارائه می‌دهد. استفاده از GCM برای راه‌اندازی انتقال‌ها نسبت به نظرسنجی از سرورها برای وضعیت، قابل‌اطمینان‌تر و کارآمدتر است. درحالی‌که نظرسنجی به Service نیاز دارد که همیشه فعال است، GCM از BroadcastReceiver استفاده می‌کند که وقتی پیامی می‌رسد فعال می‌شود. درحالی‌که نظرسنجی در فواصل منظم حتی اگر به‌روزرسانی دردسترس نباشد از شارژ باتری استفاده می‌کند، GCM فقط درصورت نیاز پیام ارسال می‌کند.

توجه: اگر از GCM برای راه‌اندازی وفق‌دهنده همگام‌سازی ازطریق پخش به همه دستگاه‌هایی که برنامه‌تان در آن‌ها نصب شده است استفاده می‌کنید، به‌خاطر داشته باشید که آن‌ها پیام شما را تقریباً در یک زمان دریافت می‌کنند. این وضعیت می‌تواند باعث شود چند نمونه از وفق‌دهنده همگام‌سازی شما به‌طور هم‌زمان اجرا شود و درنتیجه سرور و شبکه اضافه‌بار داشته باشند. برای جلوگیری از این وضعیت برای همه‌فرستی به همه دستگاه‌ها، باید شروع وفق‌دهنده همگام‌سازی را برای دوره‌ای که برای هر دستگاه منحصربه‌فرد است به‌تعویق بیندازید.

تکه‌کد زیر نحوه اجرای requestSync() را در پاسخ به پیام GCM ورودی نشان می‌دهد:

کاتلین

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

جاوا

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

اجرای وفق‌دهنده همگام‌سازی هنگام تغییر داده‌های ارائه‌دهنده محتوا

اگر برنامه‌تان داده‌ها را در ارائه‌دهنده محتوا جمع‌آوری می‌کند و می‌خواهید هرزمان که ارائه‌دهنده را به‌روز می‌کنید، سرور را به‌روز کنید، می‌توانید برنامه‌تان را طوری تنظیم کنید که وفق‌دهنده همگام‌سازی را به‌طور خودکار اجرا کند. برای انجام این کار، یک ناظر برای ارائه‌دهنده محتوا ثبت می‌کنید. وقتی داده‌ها در ارائه‌دهنده محتوا تغییر می‌کند، چارچوب ارائه‌دهنده محتوا ناظر را فرامی‌خواند. در ناظر، requestSync() را فراخوانی کنید تا به چارچوب بگویید وفق‌دهنده همگام‌سازی شما را اجرا کند.

توجه: اگر از ارائه‌دهنده محتوای تهی استفاده می‌کنید، هیچ داده‌ای در ارائه‌دهنده محتوا ندارید و onChange() هرگز فراخوانی نمی‌شود. در این حالت، باید سازوکار خودتان را برای شناسایی تغییرات در داده‌های دستگاه ارائه دهید. این سازوکار همچنین مسئول فراخوانی requestSync() هنگام تغییر داده‌ها است.

برای ایجاد ناظر برای ارائه‌دهنده محتوایتان، کلاس ContentObserver را گسترش دهید و هر دو شکل روش onChange() آن را پیاده‌سازی کنید. در onChange()، requestSync() را برای شروع وفق‌دهنده همگام‌سازی فراخوانی کنید.

برای ثبت ناظر، آن را به‌عنوان آرگومان در تماس با registerContentObserver() ارسال کنید. در این فراخوانی، باید شناسه منبع یکسان محتوا را نیز برای داده‌هایی که می‌خواهید تماشا کنید ارسال کنید. چارچوب ارائه‌دهنده محتوا این شناسه منبع یکسان تماشا را با شناسه‌های منبع یکسان محتوا که به‌عنوان آرگومان به روش‌های ContentResolver که ارائه‌دهنده شما را اصلاح می‌کنند (مانند ContentResolver.insert()) ارسال شده‌اند مقایسه می‌کند. اگر مطابقت وجود داشته باشد، پیاده‌سازی شما از ContentObserver.onChange() فراخوانده می‌شود.

تکه‌کد زیر به شما نشان می‌دهد که چگونه یک ContentObserver تعریف کنید که هنگام تغییر جدول، requestSync() را فراخوانی کند:

کاتلین

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

جاوا

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

اجرای دوره‌ای وفق‌دهنده همگام‌سازی

می‌توانید وفق‌دهنده همگام‌سازی را با تنظیم مدت زمان انتظار بین اجراها، یا با اجرای آن در زمان‌های خاصی از روز، یا هر دو، به‌صورت دوره‌ای اجرا کنید. اجرای دوره‌ای وفق‌دهنده همگام‌سازی به شما امکان می‌دهد تقریباً با فاصله زمانی به‌روزرسانی سرورتان مطابقت داشته باشید.

به‌طور مشابه، می‌توانید داده‌ها را از دستگاه بارگذاری کنید وقتی سرور شما نسبتاً آزاد است، با زمان‌بندی وفق‌دهنده همگام‌سازی برای اجرا در شب. اکثر کاربران دستگاهشان را در شب روشن و به برق متصل می‌گذارند، بنابراین این زمان معمولاً دردسترس است. علاوه‌براین، دستگاه هم‌زمان با وفق‌دهنده همگام‌سازی شما، تکالیف دیگری را اجرا نمی‌کند. اما اگر این رویکرد را اتخاذ کنید، باید مطمئن شوید که هر دستگاه انتقال داده را در زمان کمی متفاوت راه‌اندازی می‌کند. اگر همه دستگاه‌ها به‌طور هم‌زمان وفق‌دهنده همگام‌سازی شما را اجرا کنند، احتمالاً بار اضافی بر سرور و شبکه‌های داده ارائه‌دهنده تلفن همراه شما تحمیل خواهد شد.

به‌طور کلی، اگر کاربران شما به به‌روزرسانی‌های فوری نیاز نداشته باشند اما انتظار داشته باشند که به‌روزرسانی‌های منظم دریافت کنند، اجراهای دوره‌ای منطقی است. اجراهای دوره‌ای همچنین زمانی منطقی است که بخواهید توازنی بین دردسترس بودن داده‌های به‌روز و کارایی اجراهای کوچک‌تر وفق‌دهنده همگام‌سازی برقرار کنید که از منابع دستگاه بیش‌ازحد استفاده نمی‌کنند.

برای اجرای وفق‌دهنده همگام‌سازی در فواصل زمانی منظم، addPeriodicSync() را فراخوانی کنید. این کار وفق‌دهنده همگام‌سازی شما را زمان‌بندی می‌کند تا پس‌از گذشت مدت زمان مشخصی اجرا شود. ازآنجایی‌که چارچوب وفق‌دهنده همگام‌سازی باید اجراهای دیگر وفق‌دهنده همگام‌سازی را درنظر بگیرد و سعی می‌کند کارایی باتری را به حداکثر برساند، زمان سپری‌شده ممکن است چند ثانیه متفاوت باشد. همچنین، اگر شبکه دردسترس نباشد، چارچوب وفق‌دهنده همگام‌سازی شما را اجرا نخواهد کرد.

توجه داشته باشید که addPeriodicSync() وفق‌دهنده همگام‌سازی را در زمان خاصی از روز اجرا نمی‌کند. برای اجرای وفق‌دهنده همگام‌سازی تقریباً در زمان یکسان در هر روز، از زنگ تکرارشونده به‌عنوان راه‌انداز استفاده کنید. زنگ‌های تکرارشونده با جزئیات بیشتر در سند مرجع AlarmManager شرح داده شده‌اند. اگر از روش setInexactRepeating() برای تنظیم راه‌اندازهای زمان روز که دارای برخی تغییرات هستند استفاده می‌کنید، همچنان باید زمان شروع را تصادفی کنید تا مطمئن شوید که اجرای وفق‌دهنده همگام‌سازی از دستگاه‌های مختلف به‌صورت متناوب انجام می‌شود.

روش addPeriodicSync() setSyncAutomatically() را غیرفعال نمی‌کند، بنابراین ممکن است در مدت زمان نسبتاً کوتاهی چندین اجرای همگام‌سازی دریافت کنید. همچنین، فقط چند پرچم کنترل وفق‌دهنده همگام‌سازی در فراخوانی به addPeriodicSync() مجاز است؛ پرچم‌هایی که مجاز نیستند در اسناد مرجع برای addPeriodicSync() شرح داده شده‌اند.

تکه‌کد زیر نحوه زمان‌بندی کردن اجرای دوره‌ای وفق‌دهنده همگام‌سازی را نشان می‌دهد:

کاتلین

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

جاوا

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

اجرای وفق‌دهنده همگام‌سازی به‌محض درخواست

اجرای وفق‌دهنده همگام‌سازی در پاسخ به درخواست کاربر، کمترین اولویت را در بین استراتژی‌های اجرای وفق‌دهنده همگام‌سازی دارد. این چارچوب به‌طور خاص برای صرفه‌جویی در مصرف باتری طراحی شده است وقتی وفق‌دهنده‌های همگام‌سازی را طبق زمان‌بندی اجرا می‌کند. گزینه‌هایی که همگام‌سازی را در پاسخ به تغییرات داده اجرا می‌کنند، به‌طور مؤثری از شارژ باتری استفاده می‌کنند، زیرا شارژ برای ارائه داده‌های جدید استفاده می‌شود.

درمقابل، اگر به کاربران اجازه دهید همگام‌سازی را به‌صورت درخواستی اجرا کنند، همگام‌سازی به‌صورت خودکار اجرا می‌شود که استفاده ناکارآمدی از منابع شبکه و برق است. همچنین، ارائه همگام‌سازی درصورت درخواست باعث می‌شود کاربران حتی اگر شواهدی مبنی بر تغییر داده‌ها وجود نداشته باشد، درخواست همگام‌سازی کنند و اجرای همگام‌سازی‌ای که داده‌ها را بازآوری نمی‌کند، استفاده ناکارآمد از شارژ باتری است. به‌طور کلی، برنامه‌تان باید از سیگنال‌های دیگر برای راه‌اندازی همگام‌سازی استفاده کند یا آن‌ها را در فواصل منظم، بدون ورودی کاربر، زمان‌بندی کند.

بااین‌حال، اگر همچنان می‌خواهید وفق‌دهنده همگام‌سازی را به‌صورت درخواستی اجرا کنید، پرچم‌های وفق‌دهنده همگام‌سازی را برای اجرای وفق‌دهنده همگام‌سازی دستی تنظیم کنید، سپس ContentResolver.requestSync() را فراخوانی کنید.

انتقال‌های درخواستی را با پرچم‌های زیر اجرا کنید:

SYNC_EXTRAS_MANUAL
همگام‌سازی دستی را اجباری می‌کند. چارچوب وفق‌دهنده همگام‌سازی تنظیمات موجود را نادیده می‌گیرد، مثل پرچم تنظیم‌شده توسط setSyncAutomatically().
SYNC_EXTRAS_EXPEDITED
همگام‌سازی را مجبور می‌کند فوراً شروع شود. اگر این را تنظیم نکنید، ممکن است سیستم چند ثانیه قبل‌از اجرای درخواست همگام‌سازی صبر کند، زیرا سعی می‌کند با زمان‌بندی درخواست‌های متعدد در مدت‌زمان کوتاه، مصرف باتری را بهینه‌سازی کند.

تکه‌کد زیر نحوه فراخوانی requestSync() را در پاسخ به کلیک دکمه نشان می‌دهد:

کاتلین

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

جاوا

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