একটি সিঙ্ক অ্যাডাপ্টার তৈরি করুন

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

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

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

এই পাঠটি আপনাকে দেখায় কিভাবে এই উপাদানগুলিকে সংজ্ঞায়িত করতে হয়।

একটি সিঙ্ক অ্যাডাপ্টার ক্লাস তৈরি করুন

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

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

সিঙ্ক অ্যাডাপ্টার উপাদান তৈরি করতে, AbstractThreadedSyncAdapter প্রসারিত করে এবং এর কনস্ট্রাক্টর লিখে শুরু করুন। স্ক্র্যাচ থেকে আপনার সিঙ্ক অ্যাডাপ্টার উপাদান তৈরি করা হলে প্রতিবার সেটআপ কাজগুলি চালানোর জন্য কনস্ট্রাক্টর ব্যবহার করুন, ঠিক যেমন আপনি একটি কার্যকলাপ সেট আপ করতে Activity.onCreate() ব্যবহার করেন। উদাহরণস্বরূপ, যদি আপনার অ্যাপ ডেটা সঞ্চয় করার জন্য কোনো বিষয়বস্তু প্রদানকারীকে ব্যবহার করে, তাহলে একটি ContentResolver ইন্সট্যান্স পেতে কনস্ট্রাক্টর ব্যবহার করুন। যেহেতু parallelSyncs আর্গুমেন্টকে সমর্থন করার জন্য Android প্ল্যাটফর্ম সংস্করণ 3.0-এ কনস্ট্রাক্টরের দ্বিতীয় ফর্ম যোগ করা হয়েছে, তাই সামঞ্জস্য বজায় রাখার জন্য আপনাকে কনস্ট্রাক্টরের দুটি ফর্ম তৈরি করতে হবে।

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

নিম্নলিখিত উদাহরণ আপনাকে দেখায় কিভাবে AbstractThreadedSyncAdapter এবং এর কনস্ট্রাক্টরগুলি বাস্তবায়ন করতে হয়:

কোটলিন

/**
 * Handle the transfer of data between a server and an
 * app, using the Android sync adapter framework.
 */
class SyncAdapter @JvmOverloads constructor(
        context: Context,
        autoInitialize: Boolean,
        /**
         * Using a default argument along with @JvmOverloads
         * generates constructor for both method signatures to maintain compatibility
         * with Android 3.0 and later platform versions
         */
        allowParallelSyncs: Boolean = false,
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        val mContentResolver: ContentResolver = context.contentResolver
) : AbstractThreadedSyncAdapter(context, autoInitialize, allowParallelSyncs) {
    ...
}

জাভা

/**
 * Handle the transfer of data between a server and an
 * app, using the Android sync adapter framework.
 */
public class SyncAdapter extends AbstractThreadedSyncAdapter {
    ...
    // Global variables
    // Define a variable to contain a content resolver instance
    ContentResolver contentResolver;
    /**
     * Set up the sync adapter
     */
    public SyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        contentResolver = context.getContentResolver();
    }
    ...
    /**
     * Set up the sync adapter. This form of the
     * constructor maintains compatibility with Android 3.0
     * and later platform versions
     */
    public SyncAdapter(
            Context context,
            boolean autoInitialize,
            boolean allowParallelSyncs) {
        super(context, autoInitialize, allowParallelSyncs);
        /*
         * If your app uses a content resolver, get an instance of it
         * from the incoming Context
         */
        contentResolver = context.getContentResolver();
        ...
    }

ডেটা ট্রান্সফার কোড যোগ করুন

সিঙ্ক অ্যাডাপ্টার উপাদান স্বয়ংক্রিয়ভাবে ডেটা স্থানান্তর করে না। পরিবর্তে, এটি আপনার ডেটা ট্রান্সফার কোডকে এনক্যাপসুলেট করে, যাতে সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্ক আপনার অ্যাপ থেকে জড়িত না হয়ে পটভূমিতে ডেটা স্থানান্তর চালাতে পারে। যখন ফ্রেমওয়ার্কটি আপনার অ্যাপ্লিকেশনের ডেটা সিঙ্ক করার জন্য প্রস্তুত হয়, তখন এটি আপনার প্রয়োগের পদ্ধতি onPerformSync()

আপনার প্রধান অ্যাপ কোড থেকে সিঙ্ক অ্যাডাপ্টার কম্পোনেন্টে ডেটা স্থানান্তর করার সুবিধার জন্য, সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্কটি নিম্নোক্ত আর্গুমেন্ট সহ onPerformSync() কল করে:

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

নিচের স্নিপেটটি onPerformSync() এর সামগ্রিক গঠন দেখায়:

কোটলিন

/*
 * Specify the code you want to run in the sync adapter. The entire
 * sync adapter runs in a background thread, so you don't have to set
 * up your own background processing.
 */
override fun onPerformSync(
        account: Account,
        extras: Bundle,
        authority: String,
        provider: ContentProviderClient,
        syncResult: SyncResult
) {
    /*
     * Put the data transfer code here.
     */
}

জাভা

/*
 * Specify the code you want to run in the sync adapter. The entire
 * sync adapter runs in a background thread, so you don't have to set
 * up your own background processing.
 */
@Override
public void onPerformSync(
        Account account,
        Bundle extras,
        String authority,
        ContentProviderClient provider,
        SyncResult syncResult) {
    /*
     * Put the data transfer code here.
     */
}

যদিও onPerformSync() এর প্রকৃত বাস্তবায়ন আপনার অ্যাপের ডেটা সিঙ্ক্রোনাইজেশন প্রয়োজনীয়তা এবং সার্ভার সংযোগ প্রোটোকলের জন্য নির্দিষ্ট, সেখানে কিছু সাধারণ কাজ রয়েছে যা আপনার বাস্তবায়ন করা উচিত:

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

দ্রষ্টব্য: সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্ক একটি ব্যাকগ্রাউন্ড থ্রেডে onPerformSync() এ চলে, তাই আপনাকে আপনার নিজস্ব ব্যাকগ্রাউন্ড প্রসেসিং সেট আপ করতে হবে না।

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

ফ্রেমওয়ার্কে সিঙ্ক অ্যাডাপ্টার আবদ্ধ করুন

আপনার কাছে এখন আপনার ডেটা ট্রান্সফার কোড একটি সিঙ্ক অ্যাডাপ্টার উপাদানে এনক্যাপসুলেট করা আছে, কিন্তু আপনাকে আপনার কোডে অ্যাক্সেস সহ ফ্রেমওয়ার্ক প্রদান করতে হবে। এটি করার জন্য, আপনাকে একটি আবদ্ধ Service তৈরি করতে হবে যা সিঙ্ক অ্যাডাপ্টার উপাদান থেকে ফ্রেমওয়ার্কে একটি বিশেষ অ্যান্ড্রয়েড বাইন্ডার অবজেক্ট পাস করে। এই বাইন্ডার অবজেক্টের সাহায্যে, ফ্রেমওয়ার্ক onPerformSync() মেথড চালু করতে পারে এবং এতে ডেটা পাঠাতে পারে।

পরিষেবার onCreate() পদ্ধতিতে আপনার সিঙ্ক অ্যাডাপ্টার উপাদানটিকে সিঙ্গলটন হিসাবে ইনস্ট্যান্টিয়েট করুন। onCreate() এ কম্পোনেন্টটি ইনস্ট্যান্টিয়েট করার মাধ্যমে, আপনি পরিষেবাটি শুরু না হওয়া পর্যন্ত এটি তৈরি করা পিছিয়ে দেন, যা ঘটে যখন ফ্রেমওয়ার্কটি প্রথমে আপনার ডেটা স্থানান্তর চালানোর চেষ্টা করে। সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্ক ট্রিগার বা শিডিউলিংয়ের প্রতিক্রিয়ায় আপনার সিঙ্ক অ্যাডাপ্টারের একাধিক এক্সিকিউশন সারিবদ্ধ করে রাখলে আপনাকে একটি থ্রেড-নিরাপদ পদ্ধতিতে উপাদানটি ইনস্ট্যান্টিয়েট করতে হবে।

উদাহরণস্বরূপ, নিম্নলিখিত স্নিপেট আপনাকে দেখায় যে কীভাবে একটি ক্লাস তৈরি করতে হয় যা বাউন্ড Service প্রয়োগ করে, আপনার সিঙ্ক অ্যাডাপ্টার উপাদানকে ইনস্ট্যান্টিয়েট করে এবং অ্যান্ড্রয়েড বাইন্ডার অবজেক্ট পায়:

কোটলিন

package com.example.android.syncadapter
/**
 * Define a Service that returns an [android.os.IBinder] for the
 * sync adapter class, allowing the sync adapter framework to call
 * onPerformSync().
 */
class SyncService : Service() {
    /*
     * Instantiate the sync adapter object.
     */
    override fun onCreate() {
        /*
         * Create the sync adapter as a singleton.
         * Set the sync adapter as syncable
         * Disallow parallel syncs
         */
        synchronized(sSyncAdapterLock) {
            sSyncAdapter = sSyncAdapter ?: SyncAdapter(applicationContext, true)
        }
    }

    /**
     * Return an object that allows the system to invoke
     * the sync adapter.
     *
     */
    override fun onBind(intent: Intent): IBinder {
        /*
         * Get the object that allows external processes
         * to call onPerformSync(). The object is created
         * in the base class code when the SyncAdapter
         * constructors call super()
         *
         * We should never be in a position where this is called before
         * onCreate() so the exception should never be thrown
         */
        return sSyncAdapter?.syncAdapterBinder ?: throw IllegalStateException()
    }

    companion object {
        // Storage for an instance of the sync adapter
        private var sSyncAdapter: SyncAdapter? = null
        // Object to use as a thread-safe lock
        private val sSyncAdapterLock = Any()
    }
}

জাভা

package com.example.android.syncadapter;
/**
 * Define a Service that returns an <code><a href="/reference/android/os/IBinder.html">IBinder</a></code> for the
 * sync adapter class, allowing the sync adapter framework to call
 * onPerformSync().
 */
public class SyncService extends Service {
    // Storage for an instance of the sync adapter
    private static SyncAdapter sSyncAdapter = null;
    // Object to use as a thread-safe lock
    private static final Object sSyncAdapterLock = new Object();
    /*
     * Instantiate the sync adapter object.
     */
    @Override
    public void onCreate() {
        /*
         * Create the sync adapter as a singleton.
         * Set the sync adapter as syncable
         * Disallow parallel syncs
         */
        synchronized (sSyncAdapterLock) {
            if (sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
            }
        }
    }
    /**
     * Return an object that allows the system to invoke
     * the sync adapter.
     *
     */
    @Override
    public IBinder onBind(Intent intent) {
        /*
         * Get the object that allows external processes
         * to call onPerformSync(). The object is created
         * in the base class code when the SyncAdapter
         * constructors call super()
         */
        return sSyncAdapter.getSyncAdapterBinder();
    }
}

দ্রষ্টব্য: একটি সিঙ্ক অ্যাডাপ্টারের জন্য একটি আবদ্ধ পরিষেবার আরও বিশদ উদাহরণ দেখতে, নমুনা অ্যাপটি দেখুন৷

ফ্রেমওয়ার্ক দ্বারা প্রয়োজনীয় অ্যাকাউন্ট যোগ করুন

সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্কের জন্য প্রতিটি সিঙ্ক অ্যাডাপ্টারের একটি অ্যাকাউন্টের ধরন থাকা প্রয়োজন৷ আপনি প্রমাণীকরণকারী মেটাডেটা ফাইল যুক্ত করুন বিভাগে অ্যাকাউন্টের প্রকারের মান ঘোষণা করেছেন। এখন আপনাকে অ্যান্ড্রয়েড সিস্টেমে এই অ্যাকাউন্ট টাইপ সেট আপ করতে হবে। অ্যাকাউন্টের ধরন সেট আপ করতে, একটি স্থানধারক অ্যাকাউন্ট যোগ করুন যা addAccountExplicitly() কল করে অ্যাকাউন্টের ধরন ব্যবহার করে।

পদ্ধতিটি কল করার সর্বোত্তম স্থান হল আপনার অ্যাপের খোলার কার্যকলাপের onCreate() পদ্ধতিতে। নিম্নলিখিত কোড স্নিপেট আপনাকে দেখায় কিভাবে এটি করতে হয়:

কোটলিন

...
// Constants
// The authority for the sync adapter's content provider
const val AUTHORITY = "com.example.android.datasync.provider"
// An account type, in the form of a domain name
const val ACCOUNT_TYPE = "example.com"
// The account name
const val ACCOUNT = "placeholderaccount"
...
class MainActivity : FragmentActivity() {

    // Instance fields
    private lateinit var mAccount: Account
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
       ...
        // Create the placeholder account
        mAccount = createSyncAccount()
       ...
    }
    ...
    /**
     * Create a new placeholder account for the sync adapter
     */
    private fun createSyncAccount(): Account {
        val accountManager = getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
        return Account(ACCOUNT, ACCOUNT_TYPE).also { newAccount ->
            /*
             * Add the account and account type, no password or user data
             * If successful, return the Account object, otherwise report an error.
             */
            if (accountManager.addAccountExplicitly(newAccount, null, null)) {
                /*
                 * If you don't set android:syncable="true" in
                 * in your <provider> element in the manifest,
                 * then call context.setIsSyncable(account, AUTHORITY, 1)
                 * here.
                 */
            } else {
                /*
                 * The account exists or some other error occurred. Log this, report it,
                 * or handle it internally.
                 */
            }
        }
    }
    ...
}

জাভা

public class MainActivity extends FragmentActivity {
    ...
    ...
    // Constants
    // The authority for the sync adapter's content provider
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // An account type, in the form of a domain name
    public static final String ACCOUNT_TYPE = "example.com";
    // The account name
    public static final String ACCOUNT = "placeholderaccount";
    // Instance fields
    Account mAccount;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Create the placeholder account
        mAccount = CreateSyncAccount(this);
        ...
    }
    ...
    /**
     * Create a new placeholder account for the sync adapter
     *
     * @param context The application context
     */
    public static Account CreateSyncAccount(Context context) {
        // Create the account type and default account
        Account newAccount = new Account(
                ACCOUNT, ACCOUNT_TYPE);
        // Get an instance of the Android account manager
        AccountManager accountManager =
                (AccountManager) context.getSystemService(
                        ACCOUNT_SERVICE);
        /*
         * Add the account and account type, no password or user data
         * If successful, return the Account object, otherwise report an error.
         */
        if (accountManager.addAccountExplicitly(newAccount, null, null)) {
            /*
             * If you don't set android:syncable="true" in
             * in your <provider> element in the manifest,
             * then call context.setIsSyncable(account, AUTHORITY, 1)
             * here.
             */
        } else {
            /*
             * The account exists or some other error occurred. Log this, report it,
             * or handle it internally.
             */
        }
    }
    ...
}

সিঙ্ক অ্যাডাপ্টার মেটাডেটা ফাইল যোগ করুন

ফ্রেমওয়ার্কের মধ্যে আপনার সিঙ্ক অ্যাডাপ্টার উপাদান প্লাগ করতে, আপনাকে মেটাডেটা সহ ফ্রেমওয়ার্ক প্রদান করতে হবে যা উপাদানটির বর্ণনা দেয় এবং অতিরিক্ত পতাকা প্রদান করে। মেটাডেটা আপনার সিঙ্ক অ্যাডাপ্টারের জন্য আপনি যে অ্যাকাউন্ট তৈরি করেছেন তা নির্দিষ্ট করে, আপনার অ্যাপের সাথে যুক্ত একটি বিষয়বস্তু প্রদানকারী কর্তৃপক্ষ ঘোষণা করে, সিঙ্ক অ্যাডাপ্টারের সাথে সম্পর্কিত সিস্টেম ইউজার ইন্টারফেসের একটি অংশ নিয়ন্ত্রণ করে এবং অন্যান্য সিঙ্ক-সম্পর্কিত ফ্ল্যাগ ঘোষণা করে। আপনার অ্যাপ প্রকল্পের /res/xml/ ডিরেক্টরিতে সংরক্ষিত একটি বিশেষ XML ফাইলে এই মেটাডেটা ঘোষণা করুন। আপনি ফাইলটিকে যেকোনো নাম দিতে পারেন, যদিও এটিকে সাধারণত বলা হয় syncadapter.xml

এই XML ফাইলটিতে একটি একক XML উপাদান <sync-adapter> রয়েছে যার নিম্নলিখিত বৈশিষ্ট্য রয়েছে:

android:contentAuthority
আপনার বিষয়বস্তু প্রদানকারীর জন্য URI কর্তৃপক্ষ। আপনি যদি আগের পাঠে আপনার অ্যাপের জন্য একটি স্টাব সামগ্রী সরবরাহকারী তৈরি করে থাকেন, তাহলে আপনি আপনার অ্যাপ ম্যানিফেস্টে যোগ করা <provider> উপাদানটিতে android:authorities বৈশিষ্ট্যের জন্য নির্দিষ্ট করা মানটি ব্যবহার করুন। এই বৈশিষ্ট্যটি ম্যানিফেস্টে প্রদানকারী ঘোষণা করুন বিভাগে আরও বিশদে বর্ণনা করা হয়েছে।
আপনি যদি আপনার সিঙ্ক অ্যাডাপ্টারের সাথে একটি বিষয়বস্তু প্রদানকারী থেকে একটি সার্ভারে ডেটা স্থানান্তর করেন, তাহলে এই মানটি সেই ডেটার জন্য আপনি যে সামগ্রী URI কর্তৃপক্ষ ব্যবহার করছেন তার সমান হওয়া উচিত৷ এই মানটি আপনার অ্যাপ ম্যানিফেস্টে আপনার প্রদানকারীকে ঘোষণা করার <provider> উপাদানের android:authorities অ্যাট্রিবিউটে উল্লেখ করা কর্তৃপক্ষের মধ্যে একটি।
android:accountType
সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্কের জন্য প্রয়োজনীয় অ্যাকাউন্টের ধরন। আপনি প্রমাণীকরণকারী মেটাডেটা ফাইলটি তৈরি করার সময় আপনার দেওয়া অ্যাকাউন্টের প্রকারের মানটির মান অবশ্যই একই হতে হবে, যেমনটি প্রমাণীকরণকারী মেটাডেটা ফাইল যুক্ত করুন বিভাগে বর্ণিত হয়েছে। এটি সেই মানও যা আপনি স্থির ACCOUNT_TYPE এর জন্য নির্দিষ্ট করেছেন কোড স্নিপেট বিভাগে ফ্রেমওয়ার্ক দ্বারা প্রয়োজনীয় অ্যাকাউন্ট যোগ করুন
সেটিংস বৈশিষ্ট্য
android:userVisible
সিঙ্ক অ্যাডাপ্টারের অ্যাকাউন্টের প্রকারের দৃশ্যমানতা সেট করে। ডিফল্টরূপে, অ্যাকাউন্টের প্রকারের সাথে সম্পর্কিত অ্যাকাউন্ট আইকন এবং লেবেল সিস্টেমের সেটিংস অ্যাপ্লিকেশানের অ্যাকাউন্ট বিভাগে দৃশ্যমান হয়, তাই আপনার সিঙ্ক অ্যাডাপ্টারটিকে অদৃশ্য করা উচিত যদি না আপনার কাছে আপনার অ্যাপের সাথে সহজেই যুক্ত একটি অ্যাকাউন্টের প্রকার বা ডোমেন না থাকে। আপনি যদি আপনার অ্যাকাউন্টের ধরনকে অদৃশ্য করে দেন, তাহলেও আপনি ব্যবহারকারীদের আপনার অ্যাপের কোনো একটি ক্রিয়াকলাপে ব্যবহারকারী ইন্টারফেসের সাথে আপনার সিঙ্ক অ্যাডাপ্টার নিয়ন্ত্রণ করার অনুমতি দিতে পারেন।
android:supportsUploading
আপনাকে ক্লাউডে ডেটা আপলোড করার অনুমতি দেয়। আপনার অ্যাপ শুধুমাত্র ডেটা ডাউনলোড করলে এটি false সেট করুন।
android:allowParallelSyncs
আপনার সিঙ্ক অ্যাডাপ্টার উপাদানের একাধিক দৃষ্টান্তকে একই সময়ে চালানোর অনুমতি দেয়। এটি ব্যবহার করুন যদি আপনার অ্যাপ একাধিক ব্যবহারকারীর অ্যাকাউন্ট সমর্থন করে এবং আপনি একাধিক ব্যবহারকারীকে সমান্তরালভাবে ডেটা স্থানান্তর করার অনুমতি দিতে চান। আপনি একাধিক ডেটা স্থানান্তর না করলে এই পতাকার কোন প্রভাব নেই।
android:isAlwaysSyncable
সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্ককে নির্দেশ করে যে এটি আপনার নির্দিষ্ট করা যেকোনো সময় আপনার সিঙ্ক অ্যাডাপ্টার চালাতে পারে। আপনার সিঙ্ক অ্যাডাপ্টার কখন চলতে পারে আপনি যদি প্রোগ্রাম্যাটিকভাবে নিয়ন্ত্রণ করতে চান, তাহলে এই পতাকাটিকে false সেট করুন, এবং তারপর সিঙ্ক অ্যাডাপ্টার চালানোর জন্য requestSync() এ কল করুন৷ একটি সিঙ্ক অ্যাডাপ্টার চালানো সম্পর্কে আরও জানতে, একটি সিঙ্ক অ্যাডাপ্টার চালানোর পাঠটি দেখুন৷

নিম্নলিখিত উদাহরণটি একটি সিঙ্ক অ্যাডাপ্টারের জন্য XML দেখায় যা একটি একক স্থানধারক অ্যাকাউন্ট ব্যবহার করে এবং শুধুমাত্র ডাউনলোড করে।

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:contentAuthority="com.example.android.datasync.provider"
        android:accountType="com.android.example.datasync"
        android:userVisible="false"
        android:supportsUploading="false"
        android:allowParallelSyncs="false"
        android:isAlwaysSyncable="true"/>

ম্যানিফেস্টে সিঙ্ক অ্যাডাপ্টার ঘোষণা করুন

একবার আপনি আপনার অ্যাপে সিঙ্ক অ্যাডাপ্টার কম্পোনেন্ট যোগ করলে, আপনাকে কম্পোনেন্ট ব্যবহার করার জন্য অনুমতির জন্য অনুরোধ করতে হবে এবং আপনার যোগ করা আবদ্ধ Service ঘোষণা করতে হবে।

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

এই অনুমতিগুলির অনুরোধ করতে, <manifest> এর চাইল্ড উপাদান হিসাবে আপনার অ্যাপ ম্যানিফেস্টে নিম্নলিখিতগুলি যুক্ত করুন:

android.permission.INTERNET
সিঙ্ক অ্যাডাপ্টার কোডটিকে ইন্টারনেট অ্যাক্সেস করার অনুমতি দেয় যাতে এটি ডিভাইস থেকে সার্ভারে ডেটা ডাউনলোড বা আপলোড করতে পারে৷ আপনি যদি আগে অনুরোধ করে থাকেন তাহলে আপনাকে আবার এই অনুমতি যোগ করার দরকার নেই৷
android.permission.READ_SYNC_SETTINGS
আপনার অ্যাপটিকে বর্তমান সিঙ্ক অ্যাডাপ্টার সেটিংস পড়ার অনুমতি দেয়৷ উদাহরণস্বরূপ, getIsSyncable() কল করার জন্য আপনার এই অনুমতির প্রয়োজন।
android.permission.WRITE_SYNC_SETTINGS
আপনার অ্যাপকে সিঙ্ক অ্যাডাপ্টার সেটিংস নিয়ন্ত্রণ করার অনুমতি দেয়। addPeriodicSync() ব্যবহার করে পর্যায়ক্রমিক সিঙ্ক অ্যাডাপ্টার রান সেট করতে আপনার এই অনুমতির প্রয়োজন। requestSync() কল করার জন্য এই অনুমতির প্রয়োজন নেই । সিঙ্ক অ্যাডাপ্টার চালানো সম্পর্কে আরও জানতে, একটি সিঙ্ক অ্যাডাপ্টার চালানো দেখুন।

নিম্নলিখিত স্নিপেট দেখায় কিভাবে অনুমতি যোগ করতে হয়:

<manifest>
...
    <uses-permission
            android:name="android.permission.INTERNET"/>
    <uses-permission
            android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission
            android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission
            android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
...
</manifest>

পরিশেষে, ফ্রেমওয়ার্ক আপনার সিঙ্ক অ্যাডাপ্টারের সাথে ইন্টারঅ্যাক্ট করার জন্য যে আবদ্ধ Service ব্যবহার করে তা ঘোষণা করতে, <application> এর একটি চাইল্ড উপাদান হিসাবে আপনার অ্যাপ ম্যানিফেস্টে নিম্নলিখিত XML যোগ করুন:

        <service
                android:name="com.example.android.datasync.SyncService"
                android:exported="false"
                android:process=":sync">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data android:name="android.content.SyncAdapter"
                    android:resource="@xml/syncadapter" />
        </service>

<intent-filter> > উপাদানটি একটি ফিল্টার সেট আপ করে যা ইন্টেন্ট অ্যাকশন android.content.SyncAdapter দ্বারা ট্রিগার হয়, সিঙ্ক অ্যাডাপ্টার চালানোর জন্য সিস্টেম দ্বারা পাঠানো হয়। ফিল্টারটি ট্রিগার করা হলে, সিস্টেমটি আপনার তৈরি করা আবদ্ধ পরিষেবা শুরু করে, যা এই উদাহরণে SyncService । অ্যাট্রিবিউট android:exported="false" শুধুমাত্র আপনার অ্যাপ এবং সিস্টেমকে Service অ্যাক্সেস করতে দেয়। অ্যাট্রিবিউট android:process=":sync" সিস্টেমকে sync নামে একটি গ্লোবাল শেয়ার্ড প্রক্রিয়ায় Service চালাতে বলে৷ আপনার অ্যাপে একাধিক সিঙ্ক অ্যাডাপ্টার থাকলে তারা এই প্রক্রিয়াটি ভাগ করতে পারে, যা ওভারহেড হ্রাস করে।

<meta-data> উপাদানটি আপনার পূর্বে তৈরি করা সিঙ্ক অ্যাডাপ্টার মেটাডেটা XML ফাইলের নাম প্রদান করে। android:name বৈশিষ্ট্যটি নির্দেশ করে যে এই মেটাডেটাটি সিঙ্ক অ্যাডাপ্টার ফ্রেমওয়ার্কের জন্য। android:resource উপাদানটি মেটাডেটা ফাইলের নাম নির্দিষ্ট করে।

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