একটি সিঙ্ক অ্যাডাপ্টার চালান

দ্রষ্টব্য: আমরা বেশিরভাগ ব্যাকগ্রাউন্ড প্রসেসিং ব্যবহারের ক্ষেত্রে প্রস্তাবিত সমাধান হিসাবে WorkManager-কে সুপারিশ করেছি। কোন সমাধান আপনার জন্য সবচেয়ে ভালো কাজ করে তা জানতে অনুগ্রহ করে পটভূমি প্রক্রিয়াকরণ নির্দেশিকা পড়ুন।

এই ক্লাসের পূর্ববর্তী পাঠগুলিতে, আপনি শিখেছেন কীভাবে একটি সিঙ্ক অ্যাডাপ্টার উপাদান তৈরি করতে হয় যা ডেটা স্থানান্তর কোডকে এনক্যাপসুলেট করে এবং কীভাবে অতিরিক্ত উপাদানগুলি যোগ করতে হয় যা আপনাকে সিস্টেমে সিঙ্ক অ্যাডাপ্টার প্লাগ করতে দেয়৷ একটি সিঙ্ক অ্যাডাপ্টার অন্তর্ভুক্ত করে এমন একটি অ্যাপ ইনস্টল করার জন্য আপনার কাছে এখন সবকিছুই আছে, কিন্তু আপনি যে কোডটি দেখেছেন তার কোনোটিই আসলে সিঙ্ক অ্যাডাপ্টার চালায় না।

আপনার একটি সময়সূচীর উপর ভিত্তি করে বা কোনো ইভেন্টের পরোক্ষ ফলাফল হিসাবে আপনার সিঙ্ক অ্যাডাপ্টার চালানোর চেষ্টা করা উচিত। উদাহরণস্বরূপ, আপনি আপনার সিঙ্ক অ্যাডাপ্টারকে একটি নিয়মিত সময়সূচীতে চলতে চাইতে পারেন, হয় একটি নির্দিষ্ট সময়ের পরে বা দিনের একটি নির্দিষ্ট সময়ে৷ ডিভাইসে সঞ্চিত ডেটাতে পরিবর্তন হলে আপনি আপনার সিঙ্ক অ্যাডাপ্টার চালাতে চাইতে পারেন। ব্যবহারকারীর ক্রিয়াকলাপের সরাসরি ফলাফল হিসাবে আপনার সিঙ্ক অ্যাডাপ্টার চালানো এড়াতে হবে, কারণ এটি করার মাধ্যমে আপনি সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্কের সময় নির্ধারণের ক্ষমতার সম্পূর্ণ সুবিধা পাবেন না৷ উদাহরণস্বরূপ, আপনার ইউজার ইন্টারফেসে একটি রিফ্রেশ বোতাম প্রদান করা এড়ানো উচিত।

আপনার সিঙ্ক অ্যাডাপ্টার চালানোর জন্য আপনার কাছে নিম্নলিখিত বিকল্প রয়েছে:

যখন সার্ভার ডেটা পরিবর্তন হয়
একটি সার্ভার থেকে একটি বার্তার প্রতিক্রিয়া হিসাবে সিঙ্ক অ্যাডাপ্টার চালান, এটি নির্দেশ করে যে সার্ভার-ভিত্তিক ডেটা পরিবর্তিত হয়েছে৷ এই বিকল্পটি আপনাকে সার্ভার থেকে ডিভাইসে ডেটা রিফ্রেশ করার অনুমতি দেয় কর্মক্ষমতা হ্রাস না করে বা সার্ভারে ভোট দিয়ে ব্যাটারির জীবন নষ্ট না করে।
যখন ডিভাইসের ডেটা পরিবর্তন হয়
ডিভাইসে ডেটা পরিবর্তন হলে একটি সিঙ্ক অ্যাডাপ্টার চালান। এই বিকল্পটি আপনাকে ডিভাইস থেকে একটি সার্ভারে পরিবর্তিত ডেটা পাঠাতে দেয়, এবং বিশেষ করে উপযোগী যদি আপনি নিশ্চিত করতে চান যে সার্ভারে সর্বদা সর্বশেষ ডিভাইস ডেটা থাকে। আপনি যদি সত্যিই আপনার সামগ্রী প্রদানকারীতে ডেটা সঞ্চয় করেন তবে এই বিকল্পটি কার্যকর করা সহজ। আপনি যদি একটি অসম্পূর্ণ বিষয়বস্তু প্রদানকারী ব্যবহার করেন, তাহলে ডেটা পরিবর্তন সনাক্ত করা আরও কঠিন হতে পারে।
নিয়মিত বিরতিতে
আপনার বেছে নেওয়া একটি ব্যবধানের মেয়াদ শেষ হওয়ার পরে একটি সিঙ্ক অ্যাডাপ্টার চালান বা প্রতিদিন একটি নির্দিষ্ট সময়ে এটি চালান।
চাহিদা অনুযায়ী
ব্যবহারকারীর কর্মের প্রতিক্রিয়া হিসাবে সিঙ্ক অ্যাডাপ্টারটি চালান। যাইহোক, সর্বোত্তম ব্যবহারকারীর অভিজ্ঞতা প্রদানের জন্য আপনাকে প্রাথমিকভাবে আরও স্বয়ংক্রিয় বিকল্পগুলির মধ্যে একটির উপর নির্ভর করতে হবে। স্বয়ংক্রিয় বিকল্পগুলি ব্যবহার করে, আপনি ব্যাটারি এবং নেটওয়ার্ক সংস্থানগুলি সংরক্ষণ করেন৷

এই পাঠের বাকি অংশে প্রতিটি বিকল্পকে আরও বিস্তারিতভাবে বর্ণনা করা হয়েছে।

সার্ভার ডেটা পরিবর্তন হলে সিঙ্ক অ্যাডাপ্টার চালান

যদি আপনার অ্যাপ কোনো সার্ভার থেকে ডেটা স্থানান্তর করে এবং সার্ভারের ডেটা ঘন ঘন পরিবর্তিত হয়, আপনি ডেটা পরিবর্তনের প্রতিক্রিয়া হিসেবে ডাউনলোড করতে একটি সিঙ্ক অ্যাডাপ্টার ব্যবহার করতে পারেন। সিঙ্ক অ্যাডাপ্টার চালানোর জন্য, সার্ভারকে আপনার অ্যাপের একটি BroadcastReceiver এ একটি বিশেষ বার্তা পাঠাতে বলুন৷ এই বার্তার প্রতিক্রিয়া হিসাবে, আপনার সিঙ্ক অ্যাডাপ্টার চালানোর জন্য সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্ককে সংকেত দিতে ContentResolver.requestSync() কল করুন৷

Google ক্লাউড মেসেজিং (GCM) এই মেসেজিং সিস্টেমটিকে কাজ করার জন্য আপনার প্রয়োজনীয় সার্ভার এবং ডিভাইস উভয় উপাদানই প্রদান করে৷ ট্রান্সফার ট্রিগার করতে GCM ব্যবহার করা স্ট্যাটাসের জন্য পোলিং সার্ভারের চেয়ে বেশি নির্ভরযোগ্য এবং আরও দক্ষ। ভোটদানের জন্য একটি Service প্রয়োজন যা সর্বদা সক্রিয় থাকে, GCM একটি BroadcastReceiver ব্যবহার করে যা একটি বার্তা এলে সক্রিয় হয়। নিয়মিত বিরতিতে ভোটদানের সময় ব্যাটারি পাওয়ার ব্যবহার করা হয় এমনকি কোনো আপডেট পাওয়া না গেলেও, GCM শুধুমাত্র প্রয়োজনের সময় বার্তা পাঠায়।

দ্রষ্টব্য: আপনি যদি আপনার অ্যাপ ইনস্টল করা আছে এমন সমস্ত ডিভাইসে একটি সম্প্রচারের মাধ্যমে আপনার সিঙ্ক অ্যাডাপ্টার ট্রিগার করতে GCM ব্যবহার করেন, মনে রাখবেন যে তারা প্রায় একই সময়ে আপনার বার্তা গ্রহণ করে। এই পরিস্থিতির কারণে আপনার সিঙ্ক অ্যাডাপ্টারের একাধিক উদাহরণ একই সময়ে চালানো হতে পারে, যার ফলে সার্ভার এবং নেটওয়ার্ক ওভারলোড হতে পারে। সমস্ত ডিভাইসে সম্প্রচারের জন্য এই পরিস্থিতি এড়াতে, আপনার প্রতিটি ডিভাইসের জন্য অনন্য সময়ের জন্য সিঙ্ক অ্যাডাপ্টারের শুরু স্থগিত করার কথা বিবেচনা করা উচিত।

নিম্নলিখিত কোড স্নিপেট আপনাকে দেখায় কিভাবে একটি আগত GCM বার্তার প্রতিক্রিয়া হিসাবে requestSync() চালাতে হয়:

কোটলিন

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