Tạo trình xác thực mã giả lập

Khung bộ điều hợp đồng bộ hoá giả định rằng bộ điều hợp đồng bộ hoá chuyển dữ liệu giữa bộ nhớ của thiết bị được liên kết với tài khoản và bộ nhớ máy chủ yêu cầu quyền truy cập đăng nhập. Vì lý do này, khung này yêu cầu bạn cung cấp một thành phần có tên là trình xác thực trong quá trình đồng bộ hoá bộ chuyển đổi. Thành phần này sẽ được đưa vào tài khoản Android và khung xác thực cung cấp giao diện chuẩn để xử lý thông tin xác thực của người dùng, chẳng hạn như thông tin đăng nhập.

Ngay cả khi ứng dụng của bạn không sử dụng tài khoản, bạn vẫn cần cung cấp thành phần trình xác thực. Nếu bạn không sử dụng tài khoản hoặc thông tin đăng nhập máy chủ, thì thông tin do trình xác thực xử lý sẽ bị bỏ qua, nên bạn có thể cung cấp một thành phần trình xác thực có chứa phương thức mã giả lập thực tế. Bạn cũng cần cung cấp một Service ràng buộc cho phép khung bộ điều hợp đồng bộ hoá gọi các phương thức của trình xác thực.

Bài học này sẽ hướng dẫn bạn cách xác định tất cả các phần của trình xác thực mã giả lập mà bạn cần đáp ứng các yêu cầu của khung bộ điều hợp đồng bộ hoá. Nếu bạn cần cung cấp trình xác thực xử lý tài khoản người dùng, hãy đọc tài liệu tham khảo về AbstractAccountAuthenticator.

Thêm thành phần trình xác thực mã giả lập

Để thêm thành phần trình xác thực mã giả lập vào ứng dụng của bạn, hãy tạo một lớp mở rộng AbstractAccountAuthenticator, sau đó tìm ra các phương thức cần thiết, bằng cách trả về null hoặc gửi một ngoại lệ.

Đoạn mã sau đây cho thấy ví dụ về một lớp trình xác thực mã giả lập:

Kotlin

/*
 * Implement AbstractAccountAuthenticator and stub out all
 * of its methods
 */
class Authenticator(context: Context) // Simple constructor
    : AbstractAccountAuthenticator(context) {

    // Editing properties is not supported
    override fun editProperties(r: AccountAuthenticatorResponse, s: String): Bundle {
        throw UnsupportedOperationException()
    }

    // Don't add additional accounts
    @Throws(NetworkErrorException::class)
    override fun addAccount(
            r: AccountAuthenticatorResponse,
            s: String,
            s2: String,
            strings: Array<String>,
            bundle: Bundle
    ): Bundle?  = null

    // Ignore attempts to confirm credentials
    @Throws(NetworkErrorException::class)
    override fun confirmCredentials(
            r: AccountAuthenticatorResponse,
            account: Account,
            bundle: Bundle
    ): Bundle?  = null

    // Getting an authentication token is not supported
    @Throws(NetworkErrorException::class)
    override fun getAuthToken(
            r: AccountAuthenticatorResponse,
            account: Account,
            s: String,
            bundle: Bundle
    ): Bundle {
        throw UnsupportedOperationException()
    }

    // Getting a label for the auth token is not supported
    override fun getAuthTokenLabel(s: String): String {
        throw UnsupportedOperationException()
    }

    // Updating user credentials is not supported
    @Throws(NetworkErrorException::class)
    override fun updateCredentials(
            r: AccountAuthenticatorResponse,
            account: Account,
            s: String,
            bundle: Bundle
    ): Bundle {
        throw UnsupportedOperationException()
    }

    // Checking features for the account is not supported
    @Throws(NetworkErrorException::class)
    override fun hasFeatures(
            r: AccountAuthenticatorResponse,
            account: Account,
            strings: Array<String>
    ): Bundle {
        throw UnsupportedOperationException()
    }
}

Java

/*
 * Implement AbstractAccountAuthenticator and stub out all
 * of its methods
 */
public class Authenticator extends AbstractAccountAuthenticator {
    // Simple constructor
    public Authenticator(Context context) {
        super(context);
    }
    // Editing properties is not supported
    @Override
    public Bundle editProperties(
            AccountAuthenticatorResponse r, String s) {
        throw new UnsupportedOperationException();
    }
    // Don't add additional accounts
    @Override
    public Bundle addAccount(
            AccountAuthenticatorResponse r,
            String s,
            String s2,
            String[] strings,
            Bundle bundle) throws NetworkErrorException {
        return null;
    }
    // Ignore attempts to confirm credentials
    @Override
    public Bundle confirmCredentials(
            AccountAuthenticatorResponse r,
            Account account,
            Bundle bundle) throws NetworkErrorException {
        return null;
    }
    // Getting an authentication token is not supported
    @Override
    public Bundle getAuthToken(
            AccountAuthenticatorResponse r,
            Account account,
            String s,
            Bundle bundle) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
    // Getting a label for the auth token is not supported
    @Override
    public String getAuthTokenLabel(String s) {
        throw new UnsupportedOperationException();
    }
    // Updating user credentials is not supported
    @Override
    public Bundle updateCredentials(
            AccountAuthenticatorResponse r,
            Account account,
            String s, Bundle bundle) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
    // Checking features for the account is not supported
    @Override
    public Bundle hasFeatures(
        AccountAuthenticatorResponse r,
        Account account, String[] strings) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
}

Liên kết trình xác thực với khung

Để khung bộ điều hợp đồng bộ hoá truy cập vào trình xác thực, bạn phải tạo một mối liên kết Phục vụ yêu cầu đó. Dịch vụ này cung cấp một đối tượng liên kết Android cho phép khung để gọi trình xác thực và truyền dữ liệu giữa trình xác thực và khung.

Đoạn mã sau đây cho bạn biết cách xác định ràng buộc Service:

Kotlin

/**
* A bound Service that instantiates the authenticator
* when started.
*/
class AuthenticatorService : Service() {

    // Instance field that stores the authenticator object
    private lateinit var mAuthenticator: Authenticator

    override fun onCreate() {
        // Create a new authenticator object
        mAuthenticator = Authenticator(getApplicationContext())
    }

    /*
     * When the system binds to this Service to make the RPC call
     * return the authenticator's IBinder.
     */
    override fun onBind(intent: Intent?): IBinder = mAuthenticator.iBinder
}

Java

/**
 * A bound Service that instantiates the authenticator
 * when started.
 */
public class AuthenticatorService extends Service {
    ...
    // Instance field that stores the authenticator object
    private Authenticator mAuthenticator;
    @Override
    public void onCreate() {
        // Create a new authenticator object
        mAuthenticator = new Authenticator(getApplicationContext());
    }
    /*
     * When the system binds to this Service to make the RPC call
     * return the authenticator's IBinder.
     */
    @Override
    public IBinder onBind(Intent intent) {
        return mAuthenticator.getIBinder();
    }
}

Thêm tệp siêu dữ liệu trình xác thực

Để kết nối thành phần trình xác thực vào bộ điều hợp đồng bộ hoá và khung tài khoản, bạn cần hãy cung cấp khung này cùng với siêu dữ liệu mô tả thành phần đó. Siêu dữ liệu này khai báo loại tài khoản bạn đã tạo cho bộ điều hợp đồng bộ hoá và khai báo các phần tử giao diện người dùng mà hệ thống sẽ hiển thị nếu bạn muốn hiển thị loại tài khoản của mình cho người dùng. Khai báo nội dung này siêu dữ liệu trong tệp XML lưu trữ trong thư mục /res/xml/ trong dự án ứng dụng. Bạn có thể đặt bất kỳ tên nào cho tệp, mặc dù tệp này thường được gọi là authenticator.xml.

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

android:accountType
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, ở dạng của một tên miền. Khung này sử dụng loại tài khoản trong bộ điều hợp đồng bộ hoá nhận dạng nội bộ. Đối với các máy chủ yêu cầu đăng nhập, loại tài khoản cùng với tài khoản người dùng được gửi đến máy chủ dưới dạng một phần của thông tin xác thực đăng nhập.

Nếu máy chủ của bạn không yêu cầu đăng nhập, bạn vẫn phải cung cấp loại tài khoản. Đối với hãy sử dụng tên miền mà bạn kiểm soát. Trong khi khung này sử dụng nó để quản lý bộ điều hợp đồng bộ hoá, giá trị này không được gửi đến máy chủ của bạn.

android:icon
Con trỏ đến Đối tượng có thể vẽ tài nguyên chứa biểu tượng. Nếu bạn làm cho bộ điều hợp đồng bộ hoá hiển thị bằng cách chỉ định thuộc tính android:userVisible="true" trong res/xml/syncadapter.xml, thì bạn phải cung cấp tài nguyên biểu tượng này. Tài khoản này xuất hiện trong phần Tài khoản của ứng dụng Cài đặt của hệ thống.
android:smallIcon
Con trỏ đến Đối tượng có thể vẽ chứa một phiên bản nhỏ của biểu tượng. Tài nguyên này có thể được sử dụng thay cho android:icon trong phần Accounts (Tài khoản) trong ứng dụng Cài đặt của hệ thống, tuỳ thuộc vào kích thước màn hình.
android:label
Chuỗi có thể bản địa hoá giúp xác định loại tài khoản cho người dùng. Nếu bạn thực hiện bộ điều hợp đồng bộ hoá hiển thị bằng cách chỉ định thuộc tính android:userVisible="true" trong res/xml/syncadapter.xml, thì bạn nên cung cấp chuỗi này. Tên này xuất hiện trong Phần Tài khoản của ứng dụng Cài đặt của hệ thống, bên cạnh biểu tượng bạn xác định cho Trình xác thực.

Đoạn mã sau đây hiển thị tệp XML cho trình xác thực bạn đã tạo trước đây:

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:accountType="example.com"
        android:icon="@drawable/ic_launcher"
        android:smallIcon="@drawable/ic_launcher"
        android:label="@string/app_name"/>

Khai báo trình xác thực trong tệp kê khai

Ở bước trước, bạn đã tạo một Service ràng buộc liên kết trình xác thực vào khung bộ điều hợp đồng bộ hoá. Để hệ thống có thể xác định dịch vụ này, hãy khai báo dịch vụ trong ứng dụng bằng cách thêm đoạn mã sau <service> làm phần tử con của <application>:

    <service
            android:name="com.example.android.syncadapter.AuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator"/>
        </intent-filter>
        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>

Chiến lược phát hành đĩa đơn <intent-filter> thiết lập một bộ lọc được kích hoạt bởi thao tác theo ý định android.accounts.AccountAuthenticator được hệ thống gửi để chạy Trình xác thực. Khi bộ lọc được kích hoạt, hệ thống sẽ khởi động AuthenticatorService. giới hạn Service mà bạn đã cung cấp để gói trình xác thực.

Chiến lược phát hành đĩa đơn <meta-data> khai báo siêu dữ liệu cho trình xác thực. Chiến lược phát hành đĩa đơn android:name sẽ liên kết siêu dữ liệu với khung xác thực. Chiến lược phát hành đĩa đơn android:resource chỉ định tên của tệp siêu dữ liệu trình xác thực mà bạn đã tạo trước đó.

Ngoài trình xác thực, bộ điều hợp đồng bộ hoá cũng yêu cầu nhà cung cấp nội dung. Nếu ứng dụng của bạn không sử dụng một trình cung cấp nội dung đã có, hãy chuyển đến bài học tiếp theo để tìm hiểu cách tạo nội dung giả lập nhà cung cấp dịch vụ trực tuyến; nếu không, hãy xem bài học Tạo bộ điều hợp đồng bộ hoá.