สร้างตัวตรวจสอบสิทธิ์ Stub

เฟรมเวิร์กอะแดปเตอร์การซิงค์จะถือว่าอะแดปเตอร์การซิงค์จะโอนข้อมูลระหว่างพื้นที่เก็บข้อมูลของอุปกรณ์ ที่เชื่อมโยงกับบัญชีและพื้นที่เก็บข้อมูลของเซิร์ฟเวอร์ที่ต้องมีการเข้าสู่ระบบ ด้วยเหตุนี้ เฟรมเวิร์กต้องการให้คุณระบุคอมโพเนนต์ที่เรียกว่า Authenticator เพื่อเป็นส่วนหนึ่งของการซิงค์ อะแดปเตอร์ คอมโพเนนต์นี้จะเสียบปลั๊กในบัญชี Android และเฟรมเวิร์กการตรวจสอบสิทธิ์ และ มีอินเทอร์เฟซมาตรฐานสำหรับจัดการข้อมูลเข้าสู่ระบบของผู้ใช้ เช่น ข้อมูลการเข้าสู่ระบบ

แม้ว่าแอปจะไม่ได้ใช้บัญชี แต่คุณก็ต้องระบุคอมโพเนนต์ Authenticator หากคุณไม่ใช้บัญชีหรือการเข้าสู่ระบบเซิร์ฟเวอร์ ข้อมูลที่ Authenticator จัดการจะเป็น ละเว้น เพื่อให้คุณระบุคอมโพเนนต์ Authenticator ที่มีเมธอด stub ได้ การนำไปใช้งานจริง คุณยังต้องระบุ Service ที่มีผลผูกพันซึ่ง อนุญาตให้เฟรมเวิร์กอะแดปเตอร์ซิงค์เรียกใช้เมธอดของ Authenticator ได้

บทเรียนนี้แสดงวิธีกำหนดองค์ประกอบทั้งหมดของ stub Authenticator ที่คุณจำเป็นต้องใช้ เป็นไปตามข้อกำหนดของเฟรมเวิร์กอะแดปเตอร์การซิงค์ หากคุณต้องส่ง Authenticator ที่จัดการบัญชีผู้ใช้ โปรดอ่านเอกสารอ้างอิงสำหรับ AbstractAccountAuthenticator

เพิ่มคอมโพเนนต์ตัวตรวจสอบสิทธิ์ Stub

หากต้องการเพิ่มคอมโพเนนต์ตัวตรวจสอบสิทธิ์ Stub ลงในแอป ให้สร้างคลาสที่ขยาย AbstractAccountAuthenticator แล้วนำวิธีการที่จำเป็นออก ด้วยการส่งคืน null หรือแสดงผลข้อยกเว้น

ข้อมูลโค้ดต่อไปนี้จะแสดงตัวอย่างคลาส Authenticator ของ Stub

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

เชื่อมโยง Authenticator กับเฟรมเวิร์ก

เพื่อให้เฟรมเวิร์กอะแดปเตอร์การซิงค์เข้าถึง Authenticator ได้ คุณต้องสร้างขอบเขต บริการได้เลย บริการนี้มีออบเจ็กต์ Android Binder ที่ช่วยให้เฟรมเวิร์ก เพื่อเรียกใช้ Authenticator และส่งข้อมูลระหว่าง Authenticator กับเฟรมเวิร์ก

ข้อมูลโค้ดต่อไปนี้แสดงวิธีกําหนดขอบเขต 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();
    }
}

เพิ่มไฟล์ข้อมูลเมตาของ Authenticator

หากต้องการเสียบคอมโพเนนต์ Authenticator เข้ากับอะแดปเตอร์การซิงค์และเฟรมเวิร์กบัญชี คุณต้องทำดังนี้ ให้เฟรมเวิร์กเหล่านี้มีข้อมูลเมตาที่อธิบายคอมโพเนนต์นั้นๆ ข้อมูลเมตานี้ประกาศ ประเภทบัญชีที่คุณสร้างขึ้นสำหรับอะแดปเตอร์การซิงค์ และประกาศองค์ประกอบของอินเทอร์เฟซผู้ใช้ ที่ระบบแสดงหากคุณต้องการให้ผู้ใช้เห็นประเภทบัญชี ประกาศสิ่งนี้ ข้อมูลเมตาในไฟล์ XML ที่จัดเก็บในไดเรกทอรี /res/xml/ ในโปรเจ็กต์แอปของคุณ คุณตั้งชื่อไฟล์อะไรก็ได้ แต่โดยปกติแล้วจะใช้ชื่อว่า authenticator.xml

ไฟล์ XML นี้มีเอลิเมนต์ <account-authenticator> เดียวที่ มีแอตทริบิวต์ต่อไปนี้

android:accountType
เฟรมเวิร์กอะแดปเตอร์การซิงค์กำหนดให้อะแดปเตอร์การซิงค์แต่ละรายการต้องมีประเภทบัญชี ดังรูปแบบ ของชื่อโดเมน เฟรมเวิร์กนี้ใช้ประเภทบัญชีเป็นส่วนหนึ่งของ การระบุภายใน สำหรับเซิร์ฟเวอร์ที่ต้องมีการลงชื่อเข้าใช้ ประเภทบัญชีที่มี บัญชีผู้ใช้จะถูกส่งไปยังเซิร์ฟเวอร์โดยเป็นส่วนหนึ่งของข้อมูลเข้าสู่ระบบ

หากเซิร์ฟเวอร์ไม่ต้องมีการเข้าสู่ระบบ คุณยังคงต้องระบุประเภทบัญชี สำหรับ ให้ใช้ชื่อโดเมนที่คุณเป็นผู้ควบคุม ในขณะที่เฟรมเวิร์กนี้ใช้เพื่อจัดการ อะแดปเตอร์ซิงค์ ค่าจะไม่ถูกส่งไปยังเซิร์ฟเวอร์ของคุณ

android:icon
ชี้ไปที่ถอนออกได้ ที่มีไอคอน หากคุณทำให้อะแดปเตอร์การซิงค์มองเห็นได้โดยการระบุ แอตทริบิวต์ android:userVisible="true" ใน res/xml/syncadapter.xml คุณต้องจัดเตรียมทรัพยากรไอคอนนี้ ซึ่งจะปรากฏในส่วนบัญชีของ แอปการตั้งค่าของระบบ
android:smallIcon
ชี้ไปที่ถอนออกได้ ที่มีไอคอนเวอร์ชันเล็กๆ ระบบอาจใช้ทรัพยากรนี้แทน android:iconในส่วนบัญชีของแอปการตั้งค่าของระบบ โดยขึ้นอยู่กับขนาดหน้าจอ
android:label
สตริงที่แปลได้ซึ่งจะระบุประเภทบัญชีให้กับผู้ใช้ หากคุณทำอะแดปเตอร์การซิงค์ แสดงโดยการระบุแอตทริบิวต์ android:userVisible="true" ใน res/xml/syncadapter.xml คุณควรระบุสตริงนี้ โดยจะปรากฏใน ส่วนบัญชีของแอปการตั้งค่าของระบบ ข้างไอคอนที่คุณกำหนดสำหรับ Authenticator

ข้อมูลโค้ดต่อไปนี้แสดงไฟล์ XML สำหรับ Authenticator ที่สร้างไว้ก่อนหน้านี้

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

ประกาศ Authenticator ในไฟล์ Manifest

ในขั้นตอนก่อนหน้า คุณได้สร้างขอบเขต Service ที่ลิงก์ Authenticator เข้ากับเฟรมเวิร์กอะแดปเตอร์การซิงค์ หากต้องการระบุบริการนี้แก่ระบบ ให้ประกาศในแอป ไฟล์ Manifest ด้วยการเพิ่มค่าต่อไปนี้ <service> เป็นเอลิเมนต์ย่อยของ <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>

<intent-filter> องค์ประกอบจะตั้งค่าตัวกรองที่ทริกเกอร์โดยการดำเนินการผ่าน Intent android.accounts.AccountAuthenticator ซึ่งระบบส่งมาเพื่อเรียกใช้ Authenticator เมื่อมีการทริกเกอร์ตัวกรอง ระบบจะเริ่มทำงาน AuthenticatorService ขอบเขต Service ที่คุณระบุเพื่อรวม Authenticator

<meta-data> จะประกาศข้อมูลเมตาสำหรับ Authenticator android:name จะลิงก์ข้อมูลเมตากับเฟรมเวิร์กการตรวจสอบสิทธิ์ android:resource ระบุชื่อของไฟล์ข้อมูลเมตา Authenticator ที่คุณสร้างขึ้นก่อนหน้านี้

นอกจาก Authenticator แล้ว อะแดปเตอร์การซิงค์ยังต้องมีผู้ให้บริการเนื้อหาด้วย หากแอปของคุณไม่ ใช้ผู้ให้บริการเนื้อหาอยู่แล้ว ให้ไปยังบทเรียนถัดไปเพื่อดูวิธีสร้างเนื้อหาต้นขั้ว หรือไปที่บทเรียนการสร้างอะแดปเตอร์การซิงค์