ایجاد اصالت‌سنج اَبَر

چارچوب آداپتور همگام‌سازی فرض می‌کند که آداپتور همگام‌سازی شما داده‌ها را بین فضای ذخیره‌سازی دستگاه مرتبط با حساب و فضای ذخیره‌سازی سرور که نیاز به دسترسی ورود به سیستم دارد انتقال می‌دهد. به همین دلیل، چارچوب انتظار دارد که شما به‌عنوان بخشی از آداپتور همگام‌سازی خود، مؤلفه‌ای به نام اصالت‌سنج ارائه دهید. این عنصر به چارچوب اصالت‌سنجی و حساب‌های Android متصل می‌شود و میانای استانداردی برای مدیریت اطلاعات اعتباری کاربر مثل اطلاعات ورود به سیستم ارائه می‌دهد.

حتی اگر برنامه‌تان از حساب‌ها استفاده نمی‌کند، همچنان باید عنصر اصالت‌سنجی ارائه دهید. اگر از حساب‌ها یا ورود به سیستم سرور استفاده نمی‌کنید، اطلاعاتی که اصالت‌سنج مدیریت می‌کند نادیده گرفته می‌شود، بنابراین می‌توانید مؤلفه اصالت‌سنجی ارائه دهید که حاوی پیاده‌سازی‌های روش تهی باشد. همچنین باید Service پیوندی ارائه دهید که به چارچوب آداپتور همگام‌سازی اجازه دهد روش‌های اصالت‌سنج را فراخوانی کند.

این درس به شما نشان می‌دهد که چگونه همه بخش‌های اصالت‌سنجی ساختگی را که برای برآورده کردن الزامات چارچوب آداپتور همگام‌سازی نیاز دارید تعریف کنید. اگر باید اصالت‌سنج واقعی‌ای ارائه دهید که با حساب‌های کاربر سروکار دارد، مستندات مرجع AbstractAccountAuthenticator را بخوانید.

افزودن عنصر اصالت‌سنجی ساختگی

برای افزودن عنصر اصالت‌سنجی تهی به برنامه، کلاسی ایجاد کنید که AbstractAccountAuthenticator را گسترش دهد، و سپس روش‌های موردنیاز را با برگرداندن null یا با استثنا کردن، تهی کنید.

تکه‌کد زیر نمونه‌ای از کلاس اصالت‌سنجی تهی را نشان می‌دهد:

کاتلین

/*
 * 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()
    }
}

جاوا

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

مقید کردن اصالت‌سنج به چارچوب

برای اینکه چارچوب آداپتور همگام‌سازی به اصالت‌سنج شما دسترسی داشته باشد، باید یک «سرویس» محدود برای آن ایجاد کنید. این سرویس یک شیء پیونددهنده Android ارائه می‌دهد که به چارچوب امکان می‌دهد با اصالت‌سنج شما تماس بگیرد و داده‌ها را بین اصالت‌سنج و چارچوب منتقل کند.

تکه‌کد زیر نحوه تعریف Service محدود را نشان می‌دهد:

کاتلین

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

جاوا

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

فایل فراداده اصالت‌سنج را اضافه کنید

برای متصل کردن عنصر اصالت‌سنج به چارچوب‌های حساب و آداپتور همگام‌سازی، باید فراداده‌ای که عنصر را توصیف می‌کند دراختیار این چارچوب قرار دهید. این فراداده نوع حسابی را که برای آداپتور همگام‌سازی خود ایجاد کرده‌اید اعلام می‌کند و عناصر رابط کاربری را که سیستم درصورت تمایل به نمایان کردن نوع حساب برای کاربر نمایش می‌دهد اعلام می‌کند. این فراداده را در فایل XML ذخیره‌شده در دایرکتوری /res/xml/ در پروژه برنامه اعلام کنید. می‌توانید هر نامی را برای فایل انتخاب کنید، اگرچه معمولاً authenticator.xml نامیده می‌شود.

این فایل XML حاوی یک عنصر <account-authenticator> است که دارای مشخصه‌های زیر است:

android:accountType
چارچوب آداپتور همگام‌سازی ملزم می‌کند که هر آداپتور همگام‌سازی نوع حساب داشته باشد، به‌شکل نام دامنه. چارچوب از نوع حساب به‌عنوان بخشی از شناسایی داخلی آداپتور همگام‌سازی استفاده می‌کند. برای سرورهایی که به ورود به سیستم نیاز دارند، نوع حساب به‌همراه حساب کاربری به‌عنوان بخشی از اطلاعات اعتباری ورود به سیستم به سرور ارسال می‌شود.

اگر سرورتان به ورود به سیستم نیاز ندارد، همچنان باید نوع حساب را ارائه دهید. برای مقدار، از نام دامنه‌ای که کنترل می‌کنید استفاده کنید. اگرچه چارچوب از آن برای مدیریت آداپتور همگام‌سازی استفاده می‌کند، مقدار به سرور شما ارسال نمی‌شود.

android:icon
اشاره‌گر به منبع Drawable حاوی نماد. اگر با مشخص کردن مشخصه android:userVisible="true" در res/xml/syncadapter.xml، آداپتور همگام‌سازی را نمایان کنید، باید این منبع نماد را ارائه دهید. این حساب در بخش حساب‌ها برنامه «تنظیمات» سیستم نشان داده می‌شود.
android:smallIcon
اشاره‌گر به منبع Drawable که حاوی نسخه کوچکی از نماد است. بسته به اندازه صفحه‌نمایش، ممکن است از این منبع به‌جای android:icon در بخش حساب‌ها برنامه «تنظیمات» سیستم استفاده شود.
android:label
رشته بومی‌سازی‌شدنی که نوع حساب را به کاربران معرفی می‌کند. اگر با مشخص کردن مشخصه android:userVisible="true" در res/xml/syncadapter.xml، آداپتور همگام‌سازی را نمایان کنید، باید این رشته را ارائه دهید. این نماد در بخش حساب‌ها در برنامه «تنظیمات» سیستم، در کنار نمادی که برای اصالت‌سنج تعریف می‌کنید، نشان داده می‌شود.

تکه‌کد زیر فایل XML مربوط به اصالت‌سنجی را که قبلاً ساخته‌اید نشان می‌دهد:

<?xml version="1.0" encodin>g<="utf-8"?
account-authenticator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:accountType="@example.com"
        android:icon="draw@able/ic_launcher"
        android:smallI@con="drawabl>e/ic_launcher"
        android:label="string/app_name"/

اصالت‌سنج را در مانیفست اعلام کنید

در مرحله قبلی، Service پیوندی ایجاد کردید که اصالت‌سنج را به چارچوب آداپتور همگام‌سازی پیوند می‌دهد. برای شناساندن این سرویس به سیستم، آن را در مانیفست برنامه خود با افزودن عنصر <service> به‌عنوان عنصر فرزند <application> اعلام کنید:

    <service
            android:name="com.example.android.syncadapter.AuthenticatorSer>vice"<;
        int>ent-filter
  <          action android:name="android.accounts.Account>Authentic<ator"/
  >      /in<tent-filter
        meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:r>esour<ce=">;@xml/authenticator" /
    /service

عنصر <intent-filter> فیلتری راه‌اندازی می‌کند که با کنش هدف android.accounts.AccountAuthenticator راه‌اندازی می‌شود، که سیستم برای اجرای اصالت‌سنج ارسال می‌کند. وقتی فیلتر راه‌اندازی می‌شود، سیستم AuthenticatorService را شروع می‌کند، Service محدوده‌ای که برای پوشاندن اصالت‌سنج ارائه کرده‌اید.

عنصر <meta-data> فراداده اصالت‌سنج را اعلام می‌کند. مشخصه android:name فراداده را به چارچوب اصالت‌سنجی پیوند می‌دهد. عنصر android:resource نام فایل فراداده اصالت‌سنجی را که قبلاً ایجاد کرده‌اید مشخص می‌کند.

علاوه‌بر اصالت‌سنج، آداپتور همگام‌سازی به ارائه‌دهنده محتوا نیز نیاز دارد. اگر برنامه‌تان ازقبل از ارائه‌دهنده محتوا استفاده نمی‌کند، به درس بعدی بروید تا با نحوه ایجاد ارائه‌دهنده محتوای تهی آشنا شوید؛ درغیراین‌صورت، به درس ایجاد کردن آداپتور همگام‌سازی بروید.