یک احراز هویت خرد ایجاد کنید

چارچوب آداپتور همگام‌سازی فرض می‌کند که آداپتور همگام‌سازی شما داده‌ها را بین فضای ذخیره‌سازی دستگاه مرتبط با حساب و فضای ذخیره‌سازی سرور که به دسترسی به ورود نیاز دارد، منتقل می‌کند. به همین دلیل، چارچوب از شما انتظار دارد که مؤلفه‌ای به نام authenticator را به عنوان بخشی از آداپتور همگام‌سازی خود ارائه دهید. این مؤلفه به حساب‌های 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();
    }
}

Authenticator را به چارچوب متصل کنید

برای اینکه چارچوب آداپتور همگام‌سازی به تأیید کننده شما دسترسی پیدا کند، باید یک سرویس محدود برای آن ایجاد کنید. این سرویس یک شی بایندر 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();
    }
}

فایل فراداده Authenticator را اضافه کنید

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

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

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

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

android:icon
اشاره گر به یک منبع قابل ترسیم حاوی یک نماد. اگر آداپتور همگام‌سازی را با مشخص کردن ویژگی 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" 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"/>

احراز هویت را در مانیفست اعلام کنید

در مرحله قبل، یک Service محدود ایجاد کردید که احراز هویت را به چارچوب آداپتور همگام‌سازی پیوند می‌دهد. برای شناسایی این سرویس به سیستم، آن را در مانیفست برنامه خود با افزودن عنصر <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 فعال می‌شود، که توسط سیستم برای اجرای احراز هویت ارسال می‌شود. هنگامی که فیلتر فعال می شود، سیستم AuthenticatorService Service راه اندازی می کند.

عنصر <meta-data> متادیتا را برای احراز هویت کننده اعلام می کند. ویژگی android:name متا داده ها را به چارچوب احراز هویت پیوند می دهد. عنصر android:resource نام فایل فراداده Authenticator را که قبلا ایجاد کرده اید مشخص می کند.

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