เฟรมเวิร์กอะแดปเตอร์การซิงค์จะถือว่าอะแดปเตอร์การซิงค์จะโอนข้อมูลระหว่างพื้นที่เก็บข้อมูลของอุปกรณ์ ที่เชื่อมโยงกับบัญชีและพื้นที่เก็บข้อมูลของเซิร์ฟเวอร์ที่ต้องมีการเข้าสู่ระบบ ด้วยเหตุนี้ เฟรมเวิร์กต้องการให้คุณระบุคอมโพเนนต์ที่เรียกว่า 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 แล้ว อะแดปเตอร์การซิงค์ยังต้องมีผู้ให้บริการเนื้อหาด้วย หากแอปของคุณไม่ ใช้ผู้ให้บริการเนื้อหาอยู่แล้ว ให้ไปยังบทเรียนถัดไปเพื่อดูวิธีสร้างเนื้อหาต้นขั้ว หรือไปที่บทเรียนการสร้างอะแดปเตอร์การซิงค์