Tạo bộ điều hợp đồng bộ hoá

Lưu ý: Bạn nên sử dụng WorkManager làm giải pháp đề xuất cho hầu hết các trường hợp sử dụng xử lý nền. Vui lòng tham khảo hướng dẫn xử lý nền để tìm hiểu giải pháp nào phù hợp nhất với bạn.

Thành phần bộ điều hợp đồng bộ hoá trong ứng dụng của bạn sẽ đóng gói mã cho các nhiệm vụ chuyển dữ liệu giữa thiết bị và máy chủ. Dựa trên lịch biểu và điều kiện kích hoạt bạn cung cấp trong ứng dụng, khung bộ điều hợp đồng bộ hoá sẽ chạy mã trong thành phần bộ điều hợp đồng bộ hoá. Để thêm thành phần bộ điều hợp đồng bộ hoá vào ứng dụng, bạn cần thêm các thành phần sau:

Lớp bộ chuyển đổi đồng bộ hoá.
Một lớp gói mã chuyển dữ liệu của bạn trong một giao diện tương thích với khung bộ điều hợp đồng bộ hoá.
Liên kết với Service.
Một thành phần cho phép khung bộ điều hợp đồng bộ hoá chạy mã trong lớp bộ điều hợp đồng bộ hoá.
Tệp siêu dữ liệu XML của bộ chuyển đổi đồng bộ hoá.
Tệp chứa thông tin về bộ điều hợp đồng bộ hoá. Khung sẽ đọc tệp này để tìm hiểu cách tải và lên lịch chuyển dữ liệu.
Nội dung khai báo trong tệp kê khai ứng dụng.
XML khai báo dịch vụ ràng buộc và trỏ đến để đồng bộ hoá siêu dữ liệu dành riêng cho bộ chuyển đổi.

Bài học này sẽ hướng dẫn bạn cách xác định các phần tử này.

Tạo lớp bộ điều hợp đồng bộ hoá

Trong phần này của bài học, bạn sẽ tìm hiểu cách tạo lớp bộ điều hợp đồng bộ hoá đóng gói mã chuyển dữ liệu. Tạo lớp bao gồm việc mở rộng lớp cơ sở của bộ điều hợp đồng bộ hoá, xác định hàm khởi tạo cho lớp và triển khai phương thức mà bạn xác định tác vụ chuyển dữ liệu.

Mở rộng lớp bộ điều hợp đồng bộ hoá cơ sở

Để tạo thành phần bộ điều hợp đồng bộ hoá, hãy bắt đầu bằng cách mở rộng AbstractThreadedSyncAdapter và viết các hàm khởi tạo của thành phần đó. Sử dụng các hàm khởi tạo để chạy tác vụ thiết lập mỗi khi thành phần bộ điều hợp đồng bộ hoá được tạo từ đầu, giống như khi bạn sử dụng Activity.onCreate() để thiết lập một hoạt động. Ví dụ: nếu ứng dụng của bạn sử dụng một nhà cung cấp nội dung để lưu trữ dữ liệu, hãy dùng các hàm khởi tạo để nhận một thực thể ContentResolver. Vì dạng thứ hai của hàm khởi tạo đã được thêm vào nền tảng Android phiên bản 3.0 để hỗ trợ đối số parallelSyncs, nên bạn cần tạo 2 dạng hàm khởi tạo để duy trì khả năng tương thích.

Lưu ý: Khung bộ điều hợp đồng bộ hoá được thiết kế để hoạt động với các thành phần của bộ điều hợp đồng bộ hoá là các thực thể singleton. Việc tạo thực thể của thành phần bộ điều hợp đồng bộ hoá được đề cập chi tiết hơn trong phần Liên kết bộ điều hợp đồng bộ hoá với khung.

Ví dụ sau đây cho bạn biết cách triển khai AbstractThreadedSyncAdapter và các hàm khởi tạo của nó:

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

Thêm mã chuyển dữ liệu

Thành phần bộ điều hợp đồng bộ hoá không tự động chuyển dữ liệu. Thay vào đó, khung này đóng gói mã chuyển dữ liệu của bạn để khung bộ điều hợp đồng bộ hoá có thể chạy quá trình chuyển dữ liệu ở chế độ nền mà không cần sự tham gia của ứng dụng. Khi đã sẵn sàng đồng bộ hoá dữ liệu của ứng dụng, khung này sẽ gọi phương thức triển khai onPerformSync() của bạn.

Để tạo điều kiện cho quá trình chuyển dữ liệu từ mã ứng dụng chính sang thành phần bộ điều hợp đồng bộ hoá, khung bộ điều hợp đồng bộ hoá sẽ gọi onPerformSync() với các đối số sau:

Tài khoản
Đối tượng Account liên kết với sự kiện đã kích hoạt bộ điều hợp đồng bộ hoá. Nếu máy chủ của bạn không sử dụng tài khoản, thì bạn không cần sử dụng thông tin trong đối tượng này.
Thông tin bổ sung
Bundle chứa cờ do sự kiện kích hoạt bộ chuyển đổi đồng bộ hoá gửi.
Cơ quan cấp chứng nhận
Quyền của một trình cung cấp nội dung trong hệ thống. Ứng dụng của bạn phải có quyền truy cập vào nhà cung cấp này. Thông thường, đơn vị quản lý này tương ứng với một trình cung cấp nội dung trong ứng dụng của riêng bạn.
Khách hàng của trình cung cấp nội dung
ContentProviderClient cho trình cung cấp nội dung được trỏ đến bởi đối số của đơn vị quản lý. ContentProviderClient là một giao diện công khai gọn nhẹ cho trình cung cấp nội dung. Lớp này có chức năng cơ bản giống như ContentResolver. Nếu đang sử dụng trình cung cấp nội dung để lưu trữ dữ liệu cho ứng dụng, bạn có thể kết nối với nhà cung cấp bằng đối tượng này. Nếu không, bạn có thể bỏ qua thông báo đó.
Kết quả đồng bộ hoá
Đối tượng SyncResult mà bạn dùng để gửi thông tin đến khung bộ điều hợp đồng bộ hoá.

Đoạn mã sau đây cho thấy cấu trúc tổng thể của 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.
     */
}

Mặc dù cách triển khai thực tế của onPerformSync() dành riêng cho các yêu cầu đồng bộ hoá dữ liệu và giao thức kết nối máy chủ của ứng dụng, nhưng bạn cũng nên thực hiện một số thao tác chung sau đây:

Kết nối với máy chủ
Mặc dù bạn có thể giả định rằng mạng sẽ hoạt động khi quá trình chuyển dữ liệu bắt đầu, nhưng khung bộ điều hợp đồng bộ hoá sẽ không tự động kết nối với máy chủ.
Tải xuống và tải dữ liệu lên
Bộ điều hợp đồng bộ hoá không tự động hoá bất kỳ tác vụ chuyển dữ liệu nào. Nếu muốn tải dữ liệu xuống từ máy chủ và lưu trữ trong nhà cung cấp nội dung, bạn phải cung cấp mã yêu cầu dữ liệu, tải xuống và chèn dữ liệu đó vào nhà cung cấp. Tương tự, nếu muốn gửi dữ liệu đến một máy chủ, bạn phải đọc dữ liệu đó từ tệp, cơ sở dữ liệu hoặc nhà cung cấp, rồi gửi yêu cầu tải lên cần thiết. Bạn cũng phải xử lý các lỗi mạng xảy ra khi quá trình chuyển dữ liệu đang chạy.
Xử lý xung đột dữ liệu hoặc xác định dữ liệu hiện tại
Bộ điều hợp đồng bộ hoá không tự động xử lý xung đột giữa dữ liệu trên máy chủ và dữ liệu trên thiết bị. Ngoài ra, công cụ này không tự động phát hiện nếu dữ liệu trên máy chủ mới hơn dữ liệu trên thiết bị, hoặc ngược lại. Thay vào đó, bạn phải cung cấp thuật toán của riêng mình để xử lý trường hợp này.
Dọn dẹp.
Luôn đóng các kết nối với máy chủ và dọn dẹp các tệp tạm thời cũng như bộ nhớ đệm khi kết thúc quá trình chuyển dữ liệu.

Lưu ý: Khung bộ điều hợp đồng bộ hoá chạy onPerformSync() trên một luồng ở chế độ nền nên bạn không phải thiết lập quy trình xử lý của riêng mình trong nền.

Ngoài các tác vụ liên quan đến việc đồng bộ hoá, bạn nên cố gắng kết hợp các tác vụ thông thường liên quan đến mạng và thêm chúng vào onPerformSync(). Bằng cách tập trung tất cả tác vụ mạng trong phương thức này, bạn tiết kiệm được năng lượng pin cần thiết để khởi động và dừng giao diện mạng. Để tìm hiểu thêm về cách giúp việc truy cập mạng trở nên hiệu quả hơn, hãy xem lớp đào tạo Chuyển dữ liệu mà không làm tiêu hao pin. Lớp này mô tả một số tác vụ truy cập mạng mà bạn có thể đưa vào mã chuyển dữ liệu.

Liên kết bộ điều hợp đồng bộ hoá với khung

Bây giờ, mã chuyển dữ liệu của bạn được đóng gói trong thành phần bộ điều hợp đồng bộ hoá, nhưng bạn phải cung cấp cho khung quyền truy cập vào mã của mình. Để thực hiện việc này, bạn cần tạo một Service ràng buộc để truyền một đối tượng liên kết Android đặc biệt từ thành phần bộ điều hợp đồng bộ hoá sang khung. Với đối tượng liên kết này, khung có thể gọi phương thức onPerformSync() và truyền dữ liệu vào phương thức đó.

Tạo thực thể thành phần bộ điều hợp đồng bộ hoá dưới dạng singleton trong phương thức onCreate() của dịch vụ. Bằng cách tạo thực thể cho thành phần trong onCreate(), bạn sẽ trì hoãn việc tạo thành phần đó cho đến khi dịch vụ bắt đầu. Việc này xảy ra khi khung cố gắng chạy lệnh chuyển dữ liệu của bạn lần đầu tiên. Bạn cần tạo thực thể thành phần theo cách an toàn cho luồng, trong trường hợp khung bộ điều hợp đồng bộ hoá xếp hàng nhiều lượt thực thi của bộ điều hợp đồng bộ hoá để phản hồi trình kích hoạt hoặc hoạt động lên lịch.

Ví dụ: đoạn mã sau đây cho bạn biết cách tạo một lớp triển khai Service ràng buộc, tạo thực thể cho thành phần bộ điều hợp đồng bộ hoá và lấy đối tượng liên kết 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();
    }
}

Lưu ý: Để xem ví dụ chi tiết hơn về dịch vụ ràng buộc cho bộ điều hợp đồng bộ hoá, hãy xem ứng dụng mẫu.

Thêm tài khoản theo yêu cầu của khung

Khung bộ điều hợp đồng bộ hoá yêu cầu mỗi bộ điều hợp đồng bộ hoá phải có một loại tài khoản. Bạn đã khai báo giá trị loại tài khoản trong phần Thêm tệp siêu dữ liệu Authenticator. Bây giờ, bạn phải thiết lập loại tài khoản này trong hệ thống Android. Để thiết lập loại tài khoản, hãy thêm một tài khoản giữ chỗ sử dụng loại tài khoản đó bằng cách gọi addAccountExplicitly().

Vị trí tốt nhất để gọi phương thức này là trong phương thức onCreate() của hoạt động mở của ứng dụng. Đoạn mã sau đây hướng dẫn bạn cách thực hiện việc này:

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

Thêm tệp siêu dữ liệu của bộ điều hợp đồng bộ hoá

Để cắm thành phần bộ điều hợp đồng bộ hoá vào khung, bạn cần cung cấp cho khung siêu dữ liệu mô tả thành phần đó và cung cấp thêm cờ. Siêu dữ liệu chỉ định loại tài khoản bạn đã tạo cho bộ điều hợp đồng bộ hoá, khai báo thẩm quyền của nhà cung cấp nội dung liên kết với ứng dụng, kiểm soát một phần giao diện người dùng hệ thống liên quan đến bộ điều hợp đồng bộ hoá, đồng thời khai báo các cờ khác liên quan đến việc đồng bộ hoá. Khai báo siêu dữ liệu này trong một tệp XML đặc biệt lưu trữ trong thư mục /res/xml/ của dự án ứng dụng. Bạn có thể đặt tên bất kỳ cho tệp, mặc dù tệp này thường tên là syncadapter.xml.

Tệp XML này chứa một phần tử XML duy nhất <sync-adapter> có các thuộc tính sau:

android:contentAuthority
Đơn vị quản lý URI cho trình cung cấp nội dung của bạn. Nếu bạn đã tạo một trình cung cấp nội dung giả lập cho ứng dụng của mình trong bài học trước Tạo trình cung cấp nội dung tạm thời, hãy sử dụng giá trị mà bạn đã chỉ định cho thuộc tính android:authorities trong phần tử <provider> mà bạn thêm vào tệp kê khai ứng dụng. Thuộc tính này được mô tả chi tiết hơn trong phần Khai báo nhà cung cấp trong tệp kê khai.
Nếu bạn đang chuyển dữ liệu từ một nhà cung cấp nội dung sang một máy chủ bằng bộ điều hợp đồng bộ hoá, thì giá trị này phải giống với đơn vị quản lý URI nội dung mà bạn đang sử dụng cho dữ liệu đó. Giá trị này cũng là một trong các thẩm quyền mà bạn chỉ định trong thuộc tính android:authorities của phần tử <provider> khai báo trình cung cấp trong tệp kê khai ứng dụng.
android:accountType
Loại tài khoản mà khung bộ điều hợp đồng bộ hoá yêu cầu. Giá trị này phải giống với giá trị loại tài khoản bạn đã cung cấp khi tạo tệp siêu dữ liệu của trình xác thực, như mô tả trong phần Thêm tệp siêu dữ liệu của Authenticator. Đây cũng là giá trị mà bạn đã chỉ định cho hằng số ACCOUNT_TYPE trong đoạn mã trong phần Thêm tài khoản bắt buộc theo khung.
Thuộc tính cài đặt
android:userVisible
Đặt chế độ hiển thị cho loại tài khoản của bộ điều hợp đồng bộ hoá. Theo mặc định, biểu tượng tài khoản và nhãn liên kết với loại tài khoản sẽ hiển thị trong mục Accounts (Tài khoản) của ứng dụng Cài đặt của hệ thống. Vì vậy, bạn nên ẩn bộ điều hợp đồng bộ hoá trừ phi bạn có loại tài khoản hoặc miền dễ liên kết với ứng dụng. Nếu ẩn loại tài khoản, bạn vẫn có thể cho phép người dùng kiểm soát bộ chuyển đổi đồng bộ hoá bằng giao diện người dùng trong một trong các hoạt động của ứng dụng.
android:supportsUploading
Cho phép bạn tải dữ liệu lên đám mây. Hãy thiết lập thuộc tính này thành false nếu ứng dụng của bạn chỉ tải dữ liệu xuống.
android:allowParallelSyncs
Cho phép chạy nhiều phiên bản của thành phần bộ điều hợp đồng bộ hoá cùng một lúc. Hãy sử dụng phương thức này nếu ứng dụng của bạn hỗ trợ nhiều tài khoản người dùng và bạn muốn cho phép nhiều người dùng chuyển dữ liệu song song. Cờ này không có hiệu lực nếu bạn không bao giờ chạy nhiều lần chuyển dữ liệu.
android:isAlwaysSyncable
Cho khung bộ điều hợp đồng bộ hoá biết rằng khung này có thể chạy bộ điều hợp đồng bộ hoá bất cứ lúc nào mà bạn chỉ định. Nếu bạn muốn kiểm soát theo phương thức lập trình thời điểm có thể chạy bộ điều hợp đồng bộ hoá, hãy đặt cờ này thành false, sau đó gọi requestSync() để chạy bộ điều hợp đồng bộ hoá. Để tìm hiểu thêm về cách chạy bộ điều hợp đồng bộ hoá, hãy xem bài học Chạy bộ điều hợp đồng bộ hoá

Ví dụ sau đây minh hoạ mã XML cho một bộ điều hợp đồng bộ hoá sử dụng một tài khoản giữ chỗ duy nhất và chỉ thực hiện việc tải xuống.

<?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"/>

Khai báo bộ điều hợp đồng bộ hoá trong tệp kê khai

Sau khi thêm thành phần bộ điều hợp đồng bộ hoá vào ứng dụng, bạn phải yêu cầu các quyền liên quan đến việc sử dụng thành phần này, đồng thời phải khai báo Service ràng buộc mà bạn đã thêm.

Vì thành phần bộ điều hợp đồng bộ hoá chạy mã chuyển dữ liệu giữa mạng và thiết bị, nên bạn cần yêu cầu quyền truy cập Internet. Ngoài ra, ứng dụng của bạn cần yêu cầu quyền đọc và ghi chế độ cài đặt bộ chuyển đổi đồng bộ hoá, nhờ đó, bạn có thể kiểm soát bộ điều hợp đồng bộ hoá theo phương thức lập trình qua các thành phần khác trong ứng dụng. Bạn cũng cần yêu cầu một quyền đặc biệt để cho phép ứng dụng sử dụng thành phần trình xác thực mà bạn đã tạo trong bài học Tạo trình xác thực mã giả lập.

Để yêu cầu những quyền này, hãy thêm nội dung sau đây vào tệp kê khai ứng dụng dưới dạng phần tử con của <manifest>:

android.permission.INTERNET
Cho phép mã bộ điều hợp đồng bộ hoá truy cập Internet để có thể tải dữ liệu xuống hoặc tải dữ liệu từ thiết bị lên máy chủ. Bạn không cần thêm lại quyền này nếu từng yêu cầu cấp quyền đó.
android.permission.READ_SYNC_SETTINGS
Cho phép ứng dụng của bạn đọc chế độ cài đặt hiện tại của bộ điều hợp đồng bộ hoá. Ví dụ: bạn cần có quyền này để gọi getIsSyncable().
android.permission.WRITE_SYNC_SETTINGS
Cho phép ứng dụng của bạn kiểm soát chế độ cài đặt của bộ điều hợp đồng bộ hoá. Bạn cần có quyền này để thiết lập quá trình chạy bộ chuyển đổi đồng bộ hoá định kỳ bằng cách sử dụng addPeriodicSync(). Quyền này không cần thiết để gọi requestSync(). Để tìm hiểu thêm về cách chạy bộ điều hợp đồng bộ hoá, hãy xem phần Chạy bộ điều hợp đồng bộ hoá.

Đoạn mã sau đây cho biết cách thêm quyền:

<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>

Cuối cùng, để khai báo Service ràng buộc mà khung sử dụng để tương tác với bộ điều hợp đồng bộ hoá, hãy thêm XML sau đây vào tệp kê khai ứng dụng dưới dạng phần tử con của <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>

Phần tử <intent-filter> thiết lập bộ lọc được kích hoạt bởi thao tác theo ý định android.content.SyncAdapter, do hệ thống gửi để chạy bộ điều hợp đồng bộ hoá. Khi bộ lọc được kích hoạt, hệ thống sẽ khởi động dịch vụ ràng buộc mà bạn đã tạo, trong ví dụ này là SyncService. Thuộc tính android:exported="false" chỉ cho phép ứng dụng của bạn và hệ thống truy cập vào Service. Thuộc tính android:process=":sync" yêu cầu hệ thống chạy Service trong một quy trình chung chung có tên là sync. Nếu bạn có nhiều bộ chuyển đổi đồng bộ hoá trong ứng dụng, chúng có thể chia sẻ quy trình này, giúp giảm chi phí.

Phần tử <meta-data> cung cấp tên của tệp XML siêu dữ liệu của bộ điều hợp đồng bộ hoá mà bạn đã tạo trước đó. Thuộc tính android:name cho biết siêu dữ liệu này là dành cho khung bộ điều hợp đồng bộ hoá. Phần tử android:resource chỉ định tên của tệp siêu dữ liệu.

Giờ đây, bạn đã có tất cả các thành phần cho bộ điều hợp đồng bộ hoá. Bài học tiếp theo sẽ hướng dẫn bạn cách yêu cầu khung bộ điều hợp đồng bộ hoá chạy bộ điều hợp đồng bộ hoá để phản hồi một sự kiện hoặc theo lịch biểu định kỳ.