إنشاء محوّل مزامنة

ملاحظة: ننصح باستخدام WorkManager. كحل موصى به لمعظم حالات استخدام المعالجة في الخلفية. يُرجى الرجوع إلى دليل المعالجة في الخلفية لمعرفة الحلّ الأنسب لك.

يضم مكون محوّل المزامنة في تطبيقك رمزًا للمهام التي يتم نقلها البيانات بين الجهاز والخادم. استنادًا إلى الجدولة والمشغلات التي تقدمها في لتطبيقك، فإن إطار عمل محول المزامنة يشغّل الرمز في مكوّن محوّل المزامنة. لإضافة مكوِّن محول المزامنة مع تطبيقك، فيجب إضافة الأجزاء التالية:

فئة محوّل المزامنة.
يشير هذا المصطلح إلى فئة تضم رمز نقل البيانات في واجهة متوافقة مع محوّل المزامنة. إطار العمل.
مرتبط Service.
يشير هذا المصطلح إلى مكوِّن يسمح لإطار عمل محوّل المزامنة بتشغيل الرمز في محوّل المزامنة. الصف.
ملف البيانات الوصفية بتنسيق XML لمحوّل المزامنة.
ملف يحتوي على معلومات حول محوّل المزامنة يقرأ إطار العمل هذا الملف التعرّف على كيفية تحميل وجدولة عملية نقل البيانات.
نماذج البيانات في بيان التطبيق
ملف XML الذي يعرّف عن الخدمة المرتبطة ويشير إلى مزامنة البيانات الوصفية الخاصة بالمحوّل.

يوضح لك هذا الدرس كيفية تحديد هذه العناصر.

إنشاء صف لمحوّل المزامنة

تتعلم في هذا الجزء من الدرس كيفية إنشاء فئة محول المزامنة التي تضم رمز نقل البيانات. يتضمن إنشاء الفئة تمديد الفئة الأساسية لمحول المزامنة وتحديد وإنشاء دوال إنشاء للفئة وتنفيذ الطريقة التي يمكنك من خلالها تعريف نقل البيانات المهام.

تمديد فئة محوّل المزامنة الأساسية

لإنشاء مكون محول المزامنة، ابدأ بتمديد AbstractThreadedSyncAdapter وكتابة طرق الإنشاء الخاصة به. يمكنك استخدام دوال الإنشاء لتشغيل مهام الإعداد في كل مرة يتم فيها إنشاء مكون محول المزامنة من البداية، تمامًا كما تستخدم Activity.onCreate() لإعداد الأخرى. على سبيل المثال، إذا كان تطبيقك يستخدم إحدى موفّري المحتوى لتخزين البيانات، استخدِم دوال الإنشاء. للحصول على مثيل ContentResolver. نظرًا لأن النموذج الثاني تمت إضافة الدالة الإنشائية في الإصدار 3.0 من نظام Android الأساسي لإتاحة parallelSyncs. تحتاج إلى إنشاء شكلين من الدالة الإنشائية للحفاظ على التوافق.

ملاحظة: تم تصميم إطار عمل محوّل المزامنة للعمل مع محوّل المزامنة. والمكونات التي هي مثيلات فرديةتون. يتم حجب مثيل مكوِّن محول المزامنة بشكلٍ أكثر تفصيلاً في القسم اربط محوّل المزامنة بإطار العمل.

يوضح المثال التالي كيفية تنفيذ AbstractThreadedSyncAdapterوأسسه:

Kotlin

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

Java

/**
 * 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():

Kotlin

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

Java

/*
 * 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 التي تمرر كائن ربط Android خاصًا من محوّل المزامنة لإطار العمل. وباستخدام كائن أداة الربط هذا، يمكن أن يستدعي إطار العمل طريقة onPerformSync() تمرير البيانات إليه.

إنشاء مثيل لمكوِّن مهايئ المزامنة كصوت مفرد في طريقة واحدة (onCreate()) للخدمة. من خلال إنشاء مثيل المكون في onCreate()، فيمكنك تأجيل إنشاءه إلى أن تبدأ الخدمة، وهو ما يحدث عندما يحاول إطار العمل تشغيل نقل البيانات. يجب إنشاء مثيل للمكوِّن بطريقة آمنة سلسلة التعليمات في حال كانت المزامنة ينظم إطار عمل المحول عدة عمليات تنفيذ لمحوّل المزامنة استجابةً للمشغلات أو وجدولتها.

على سبيل المثال، يوضح المقتطف التالي كيفية إنشاء فئة تنفذ ربط Service، وإنشاء مثيل لمكوِّن محول المزامنة والحصول على كائن رابط Android:

Kotlin

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

Java

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

ملاحظة: للاطِّلاع على مثال أكثر تفصيلاً عن خدمة مرتبطة لمحوّل المزامنة، اطّلِع على نموذج التطبيق.

إضافة الحساب الذي يتطلبه إطار العمل

يتطلب إطار عمل محوّل المزامنة أن يكون لكل محوّل مزامنة نوع حساب. لقد أعلنت قيمة نوع الحساب في القسم أضِف ملف البيانات الوصفية لتطبيق Authenticator. عليك الآن إعداد نوع الحساب هذا في نظام Android لإعداد نوع الحساب، عليك إضافة حساب عنصر نائب يستخدم نوع الحساب. عبر الاتصال بالرقم addAccountExplicitly().

أفضل مكان لاستدعاء الطريقة هو طريقة واحدة (onCreate()) من طريقة أداء تطبيقك نشاط الفتح. يوضح مقتطف الرمز التالي كيفية إجراء ذلك:

Kotlin

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

Java

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

إضافة ملف البيانات الوصفية لمحوّل المزامنة

لتوصيل مكوِّن محول المزامنة بإطار العمل، يجب توفير إطار العمل مع بيانات وصفية تصف المكوِّن وتقدم علامات إضافية. تحدد بيانات التعريف نوع الحساب الذي أنشأته لمحوّل المزامنة، مع توضيح جهة موفّر المحتوى المرتبطة بتطبيقك، والتحكم في جزء من واجهة مستخدم النظام المتعلقة بمحوّلات المزامنة، وتوضح علامات أخرى ذات صلة بالمزامنة. يُرجى تعريف هذه البيانات الوصفية في ملف XML خاص مخزَّن في دليل /res/xml/ في مشروع تطبيقك. يمكنك إعطاء أي اسم للملف، على الرغم من أنّه يسمّى عادةً syncadapter.xml.

يحتوي ملف XML هذا على عنصر XML واحد <sync-adapter> يتضمّن السمات التالية:

android:contentAuthority
مرجع معرّف الموارد المنتظم (URI) لموفّر المحتوى إذا قمت بإنشاء موفّر محتوى بديل تطبيقك في الدرس السابق إنشاء موفّر محتوى Stub، استخدِم القيمة التي حدّدتها سمة android:authorities في العنصر <provider> الذي أضفته إلى بيان التطبيق. هذه السمة بمزيد من التفصيل في القسم توضيح موفّر الخدمة في البيان:
إذا كنت تنقل البيانات من موفّر محتوى إلى خادم باستخدام محول المزامنة، فإن هذا يجب أن تكون القيمة هي نفسها مرجع معرّف الموارد المنتظم (URI) للمحتوى الذي تستخدمه لتلك البيانات. هذه القيمة هي أيضًا إحدى السلطات التي تحددها في android:authorities للسمة <provider> التي تشير إلى موفّر الخدمة في بيان التطبيق.
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 المرتبط التي أضفتها.

نظرًا لأن مكوِّن محول المزامنة يشغِّل التعليمات البرمجية التي تنقل البيانات بين الشبكة عليك طلب إذن للدخول إلى الإنترنت. بالإضافة إلى ذلك، يحتاج تطبيقك لطلب إذن لقراءة إعدادات محوّل المزامنة وكتابتها، يمكنك التحكّم في تلقائيًا من المكونات الأخرى في تطبيقك. يجب أيضًا طلب إذن خاص يسمح للتطبيق باستخدام مكوّن المصادقة الذي أنشأته. في الدرس إنشاء أداة مصادقة Stub.

لطلب هذه الأذونات، أضف ما يلي إلى بيان التطبيق كعناصر فرعية من <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 الذي يستخدمه إطار العمل مع محوّل المزامنة، أضف ملف XML التالي إلى بيان التطبيق كعنصر فرعي من <application>:

        <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> إعداد فلتر يتم تشغيله بواسطة إجراء intent android.content.SyncAdapter، أرسله النظام لتشغيل محوّل المزامنة. عندما يعمل عامل التصفية عند التشغيل، يبدأ النظام الخدمة المرتبطة التي قمت بإنشائها، والتي في هذا المثال SyncService السمة android:exported="false" إلى السماح للتطبيق والنظام فقط بالوصول إلى Service السمة android:process=":sync" يطلب من النظام تشغيل Service في عملية مشتركة عمومية اسمها sync إذا كان لديك عدة محوّلات مزامنة في تطبيقك، يمكنهم مشاركة هذه العملية: مما يقلل من النفقات العامة.

تشير رسالة الأشكال البيانية <meta-data> اسم ملف XML الخاص بالبيانات الوصفية لمحول المزامنة الذي أنشأته سابقًا. تشير رسالة الأشكال البيانية android:name إلى أن البيانات الوصفية هذه مخصصة لإطار عمل محول المزامنة. تشير رسالة الأشكال البيانية android:resource اسم ملف البيانات الوصفية.

لديك الآن جميع مكونات محول المزامنة. يوضح لك الدرس التالي كيفية الطلب من إطار عمل محول المزامنة تشغيل محوّل المزامنة، إما استجابةً لحدث أو جدول زمني منتظم.