יצירת מתאם סנכרון

הערה: אנחנו ממליצים על WorkManager הוא הפתרון המומלץ לרוב התרחישים לדוגמה של עיבוד ברקע. כדאי לעיין במדריך לעיבוד ברקע כדי ללמוד איזה פתרון הכי מתאים לכם.

רכיב מתאם הסנכרון באפליקציה כולל את הקוד של המשימות שמועברות בין המכשיר לשרת. על סמך התזמון והטריגרים שסיפקת באפליקציה שלך, ה-framework של מתאם הסנכרון מריץ את הקוד ברכיב של מתאם הסנכרון. כדי להוסיף רכיב של מתאם סנכרון לאפליקציה שלך, עליך להוסיף את החלקים הבאים:

סנכרון סוג המתאם.
מחלקה שעוטפת את הקוד להעברת נתונים בממשק שתואם למתאם הסנכרון .
קשור ל-Service.
רכיב שמאפשר למסגרת של מתאם הסנכרון להריץ את הקוד במתאם הסנכרון בכיתה.
קובץ ה-XML של מתאם הסנכרון:
קובץ שמכיל מידע על מתאם הסנכרון. ה-framework קורא את הקובץ הזה כדי להבין איך לטעון ולתזמן את העברת הנתונים.
הצהרות בקובץ המניפסט של האפליקציה.
XML שמצהיר על השירות המקושר ומצביע על סנכרון מטא-נתונים ספציפיים למתאם.

בשיעור הזה נסביר איך להגדיר את הרכיבים האלה.

יצירת סיווג של מתאם סנכרון

בחלק הזה של השיעור תלמדו איך ליצור את סיווג מתאם הסנכרון שמקיף את את הקוד להעברת נתונים. יצירת המחלקה כוללת הרחבה של מחלקה בסיסית של מתאם סנכרון, הגדרת של המחלקה, והטמעת השיטה שבה מגדירים את העברת הנתונים. למשימות סיווג.

הרחבת הסיווג של מתאם הסנכרון הבסיסי

כדי ליצור את הרכיב של מתאם הסנכרון, צריך להתחיל בהרחבה AbstractThreadedSyncAdapter וכתיבת הבנאים שלו. משתמשים ב כדי להריץ משימות הגדרה בכל פעם שרכיב מתאם הסנכרון נוצר מאפס, בדיוק כמו שמשתמשים ב-Activity.onCreate() כדי להגדיר פעילות. לדוגמה, אם האפליקציה שלך משתמשת בספק תוכן כדי לאחסן נתונים, השתמש ב-constructor כדי לקבל מופע של ContentResolver. מכיוון שצורה שנייה constructor נוסף בפלטפורמת Android בגרסה 3.0 כדי לתמוך ב-parallelSyncs , צריך ליצור שתי צורות של ה-constructor כדי לשמור על תאימות.

הערה: מסגרת מתאם הסנכרון מיועדת לפעול עם מתאם סנכרון שהם מופעים של סינגלטון. יצירת האובייקט של מתאם הסנכרון מכוסה בצורה מפורטת יותר מקשרים את מתאם הסנכרון ל-framework.

בדוגמה הבאה אפשר לראות איך מטמיעים 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();
        ...
    }

הוספת הקוד של העברת הנתונים

רכיב המתאם לסנכרון לא מבצע העברת נתונים באופן אוטומטי. במקום זאת, כולל את הקוד להעברת נתונים, כך שמסגרת מתאם הסנכרון יכולה להריץ את העברת נתונים ברקע, ללא מעורבות מהאפליקציה. כשה-framework מוכן לסנכרן את נתוני האפליקציה, הוא מפעיל את היישום של השיטה onPerformSync()

כדי להקל על העברת נתונים מקוד האפליקציה הראשי לרכיב של מתאם הסנכרון, הקריאות ל-framework של מתאם הסנכרון 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() ספציפי ל הדרישות לסנכרון נתונים והפרוטוקולים של חיבור לשרת, יש מספר משימות כלליות שההטמעה צריכה לבצע:

התחברות לשרת
למרות שאפשר להניח שהרשת זמינה כשהעברת הנתונים מתחילה, framework של מתאם סנכרון לא מתחבר לשרת באופן אוטומטי.
הורדה והעלאה של נתונים
מתאם סנכרון לא מבצע אוטומציה של משימות של העברת נתונים. רוצה להוריד? לשרת ולאחסן אותם בספק תוכן, עליך לספק את הקוד מבקש את הנתונים, מוריד אותם ומוסיף אותם לספק. באופן דומה, אם רוצים לשלוח נתונים לשרת, לקרוא אותם מקובץ, ממסד נתונים או מספק, ולשלוח בבקשת ההעלאה הנדרשת. עליך לטפל גם בשגיאות רשת שמתרחשות בזמן העברת הנתונים פועלת.
טיפול בהתנגשויות נתונים או קביעת מידת העדכניות של הנתונים
מתאם סנכרון לא מטפל באופן אוטומטי בהתנגשויות בין נתונים בשרת לנתונים במכשיר. כמו כן, הוא לא מזהה באופן אוטומטי אם הנתונים בשרת חדשים יותר מ- את הנתונים במכשיר, או להיפך. במקום זאת, אתם צריכים לספק אלגוריתמים משלכם במצב הזה.
הסרת המשאבים.
תמיד לסגור חיבורים לשרת ולנקות קבצים זמניים ומטמון בסוף העברת הנתונים.

הערה: מסגרת מתאם הסנכרון פועלת onPerformSync() על שרשור ברקע, כך שאין צורך להגדיר עיבוד משלכם ברקע.

בנוסף למשימות שקשורות לסנכרון, כדאי לנסות לשלב את משימות שקשורות לרשת ולהוסיף אותן onPerformSync() על ידי ריכוז כל משימות הרשת בשיטה הזו, אפשר לחסוך בצריכת הסוללה, שנדרשים כדי להפעיל ולהפסיק את ממשקי הרשת. למידע נוסף על מתן גישה לרשת ביעילות אפשר לעיין בשיעור האימון העברת נתונים מבלי לרוקן את הסוללה, שמתארת כמה גישה לרשת משימות שאפשר לכלול בקוד העברת הנתונים.

חיבור מתאם הסנכרון ל-framework

הקוד להעברת נתונים מוקף ברכיב של מתאם סנכרון, אבל כדי לתת ל-framework גישה לקוד שלכם. כדי לעשות את זה, צריך ליצור Service שמעביר אובייקט מיוחד בקשר ל-Android ממתאם הסנכרון של רכיב ל-framework. באמצעות אובייקט קישור זה, ה-framework יכול להפעיל אמצעי תשלום אחד (onPerformSync()) ו להעביר אליו נתונים.

יצירת אובייקט של מתאם הסנכרון כרכיב singleton השיטה onCreate() בשירות. על ידי יצירת אובייקט את הרכיב ב-onCreate(), צריך לעכב תיצור אותם עד שהשירות יתחיל, כלומר כאשר ה-framework מנסה להפעיל בפעם הראשונה העברת נתונים. עליך ליצור את הרכיב באופן מאובטח בשרשור, למקרה שהסנכרון מתאם הסנכרון נכנס לתור להפעלות מרובות של מתאם הסנכרון בתגובה לטריגרים או תזמון.

לדוגמה, קטע הקוד הבא מראה איך ליצור מחלקה שמממשת את ב-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();
    }
}

הערה: כדי לראות דוגמה מפורטת יותר של שירות קשור למתאם סנכרון, לצפייה באפליקציה לדוגמה

הוספת החשבון שנדרש על ידי ה-framework

במסגרת מתאם הסנכרון, כל מתאם סנכרון צריך להיות מסוג חשבון. הצהרת על הערך של סוג החשבון בקטע מוסיפים את קובץ המטא-נתונים של מאמת החשבונות. עכשיו צריך להגדיר את סוג החשבון הזה מערכת Android. כדי להגדיר את סוג החשבון, צריך להוסיף חשבון placeholder שנעשה בו שימוש בסוג החשבון. באמצעות התקשרות אל 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.
             */
        }
    }
    ...
}

הוספת קובץ המטא-נתונים של מתאם הסנכרון

כדי לחבר את הרכיב של מתאם הסנכרון ל-framework, צריך לספק את ה-framework עם מטא-נתונים שמתארים את הרכיב ומספקים דגלים נוספים. המטא-נתונים מציינים סוג החשבון שיצרתם למתאם הסנכרון (כולל הצהרה על רשות של ספק תוכן) המשויך לאפליקציה שלך, שולט בחלק מממשק המשתמש של המערכת שקשור למתאמי סנכרון, ומצהיר על דגלים אחרים הקשורים לסנכרון. להצהיר על המטא-נתונים בקובץ XML מיוחד המאוחסן ב הספרייה /res/xml/ בפרויקט האפליקציה. אפשר לתת כל שם לקובץ, למרות שהוא בדרך כלל נקרא syncadapter.xml.

קובץ ה-XML הזה מכיל רכיב XML יחיד <sync-adapter> עם המאפיינים הבאים:

android:contentAuthority
רשות ה-URI של ספק התוכן. אם יצרתם ספק תוכן stub עבור האפליקציה שלך בשיעור הקודם יצירת ספק תוכן Stub, השתמש בערך שציינת עבור שיוך android:authorities ברכיב <provider> שהוספת לקובץ המניפסט של האפליקציה. המאפיין הזה שתוארו יותר בקטע להצהיר על הספק במניפסט.
אם אתם מעבירים נתונים מספק תוכן לשרת עם מתאם הסנכרון, ההגדרות הבאות צריך להיות זהה לרשות ה-URI של התוכן שבה אתם משתמשים לנתונים האלה. הערך הזה היא גם אחת מהרשויות שציינתם android:authorities של הרכיב <provider> שמצהיר על הספק בקובץ המניפסט של האפליקציה.
android:accountType
סוג החשבון שנדרש על ידי מסגרת מתאם הסנכרון. הערך חייב להיות זהה כערך של סוג החשבון שסיפקת כשיצרת את קובץ המטא-נתונים של המאמת, כפי שמתואר בסעיף הוספת קובץ המטא-נתונים של מאמת החשבונות. זה גם הערך שציינת עבור קבוע ACCOUNT_TYPE בקטע הקוד בקטע מוסיפים את החשבון שנדרש על ידי המסגרת.
מאפייני הגדרות
android:userVisible
מגדיר את החשיפה של סוג החשבון של מתאם הסנכרון. כברירת מחדל, סמל החשבון והתווית שמשויכים לסוג החשבון מופיעים בקטע הקטע חשבונות באפליקציית ההגדרות של המערכת, לכן עליך לבצע את הסנכרון המתאם בלתי נראה, אלא אם יש לך סוג חשבון או דומיין שניתן לשייך בקלות באפליקציה שלכם. גם אם סוג החשבון שלך יהיה בלתי נראה, עדיין אפשר יהיה לאפשר למשתמשים לשלוט במתאם הסנכרון באמצעות ממשק משתמש באחת מהפעילויות של האפליקציה.
android:supportsUploading
מאפשרת להעלות נתונים לענן. יש להגדיר את הערך כ-false אם האפליקציה שלך בלבד הורדות נתונים.
android:allowParallelSyncs
מאפשרת להפעיל מספר מופעים של רכיב מתאם הסנכרון בו-זמנית. כדאי להשתמש באפשרות הזו אם האפליקציה תומכת במספר חשבונות משתמשים ורוצים לאפשר גישה לכמה חשבונות משתמשים משתמשים כדי להעביר נתונים במקביל. לסימון הזה אין השפעה אם לא מריצים אף פעם העברות מרובות של נתונים.
android:isAlwaysSyncable
מציינת למסגרת של מתאם הסנכרון שהיא יכולה להפעיל את מתאם הסנכרון שלך בכל השעה שציינת. אם רוצים לקבוע באופן פרוגרמטי מתי הסנכרון המתאם יכול לפעול, להגדיר את הדגל הזה ל-false, ואז להתקשר requestSync() כדי להריץ את למתאם הסנכרון. למידע נוסף על הפעלת מתאם סנכרון, עיינו בשיעור להפעיל מתאם סנכרון

הדוגמה הבאה מציגה את ה-XML של מתאם סנכרון שמשתמש בחשבון placeholder אחד, רק הורדות.

<?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 מציין את השם של קובץ המטא-נתונים.

עכשיו כל הרכיבים של מתאם הסנכרון נמצאים ברשותך. בשיעור הבא תלמדו להורות ל-framework של מתאם הסנכרון להפעיל את מתאם הסנכרון, בתגובה לאירוע או במכשיר לוח זמנים קבוע.