스터브 인증자 만들기

동기화 어댑터 프레임워크에서는 동기화 어댑터가 계정에 연결된 기기 저장소와 로그인 액세스가 필요한 서버 저장소 간에 데이터를 전송한다고 가정합니다. 이러한 이유로 프레임워크에서는 동기화 어댑터의 일부로 인증자라는 구성요소를 제공할 것을 기대합니다. 이 구성요소는 Android 계정 및 인증 프레임워크에 연결되며 로그인 정보와 같은 사용자 인증 정보를 처리하기 위한 표준 인터페이스를 제공합니다.

앱에서 계정을 사용하지 않더라도 인증자 구성요소를 제공해야 합니다. 계정 또는 서버 로그인을 사용하지 않는 경우 인증자가 처리하는 정보는 무시되므로 스텁 메서드 구현이 포함된 인증자 구성요소를 제공할 수 있습니다. 동기화 어댑터 프레임워크가 인증자의 메서드를 호출할 수 있도록 하는 바인딩된 Service도 제공해야 합니다.

이 과정에서는 동기화 어댑터 프레임워크의 요구사항을 충족하는 데 필요한 스텁 인증자의 모든 부분을 정의하는 방법을 보여줍니다. 사용자 계정을 처리하는 실제 인증자를 제공해야 한다면 AbstractAccountAuthenticator 참조 문서를 확인하세요.

스터브 인증자 구성요소 추가

스터브 인증자 구성요소를 앱에 추가하려면 AbstractAccountAuthenticator를 확장하는 클래스를 만들고 null를 반환하거나 예외를 발생시켜 필요한 메서드를 스텁 처리합니다.

다음 스니펫에서는 스터브 인증자 클래스의 예를 보여줍니다.

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

인증자를 프레임워크에 바인딩

동기화 어댑터 프레임워크가 인증자에 액세스할 수 있으려면 바인드된 서비스를 만들어야 합니다. 이 서비스는 프레임워크에서 인증자를 호출하고 인증자와 프레임워크 간에 데이터를 전달할 수 있는 Android 바인더 객체를 제공합니다.

다음 스니펫은 바인딩된 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();
    }
}

인증자 메타데이터 파일 추가

인증자 구성요소를 동기화 어댑터 및 계정 프레임워크에 연결하려면 구성요소를 설명하는 메타데이터를 이 프레임워크에 제공해야 합니다. 이 메타데이터는 동기화 어댑터용으로 만든 계정 유형을 선언하고 계정 유형을 사용자에게 표시하려는 경우 시스템에서 표시하는 사용자 인터페이스 요소를 선언합니다. 이 메타데이터를 앱 프로젝트의 /res/xml/ 디렉터리에 저장된 XML 파일에서 선언합니다. 파일 이름은 일반적으로 authenticator.xml이지만 원하는 이름을 지정할 수 있습니다.

이 XML 파일에는 다음 속성을 지닌 단일 요소 <account-authenticator>가 포함되어 있습니다.

android:accountType
동기화 어댑터 프레임워크는 각 동기화 어댑터에 도메인 이름 형식의 계정 유형이 있어야 합니다. 프레임워크는 동기화 어댑터의 내부 식별의 일부로 계정 유형을 사용합니다. 로그인이 필요한 서버의 경우 사용자 계정과 함께 계정 유형이 로그인 사용자 인증 정보의 일부로 서버에 전송됩니다.

서버에 로그인이 필요하지 않더라도 계정 유형을 제공해야 합니다. 이 값에는 개발자가 제어하는 도메인 이름을 사용합니다. 프레임워크에서는 이 값을 사용하여 동기화 어댑터를 관리하지만 이 값은 서버로 전송되지 않습니다.

android:icon
아이콘이 포함된 드로어블 리소스를 가리키는 포인터입니다. res/xml/syncadapter.xmlandroid:userVisible="true" 속성을 지정하여 동기화 어댑터를 표시하려면 이 아이콘 리소스를 제공해야 합니다. 시스템 설정 앱의 계정 섹션에 표시됩니다.
android:smallIcon
작은 버전의 아이콘이 포함된 드로어블 리소스를 가리키는 포인터입니다. 이 리소스는 화면 크기에 따라 시스템 설정 앱의 계정 섹션에 있는 android:icon 대신 사용할 수 있습니다.
android:label
사용자에게 계정 유형을 식별하는 현지화 가능한 문자열입니다. res/xml/syncadapter.xmlandroid:userVisible="true" 속성을 지정하여 동기화 어댑터를 표시하려면 이 문자열을 제공해야 합니다. 이 아이콘은 시스템 설정 앱의 계정 섹션에서 인증자에 정의한 아이콘 옆에 표시됩니다.

다음 스니펫에서는 앞서 만든 인증자의 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> 요소는 인증자 실행을 위해 시스템에서 전송하는 인텐트 작업 android.accounts.AccountAuthenticator에 의해 트리거되는 필터를 설정합니다. 필터가 트리거되면 시스템은 인증자를 래핑하기 위해 개발자가 제공한 바인드된 ServiceAuthenticatorService를 시작합니다.

<meta-data> 요소는 인증자의 메타데이터를 선언합니다. android:name 속성은 메타데이터를 인증 프레임워크에 연결합니다. android:resource 요소는 이전에 만든 인증자 메타데이터 파일의 이름을 지정합니다.

동기화 어댑터에는 인증자 외에 콘텐츠 제공업체도 필요합니다. 앱에서 아직 콘텐츠 제공업체를 사용하지 않는다면 다음 과정으로 이동하여 스터브 콘텐츠 제공업체를 만드는 방법을 알아보세요. 사용하고 있지 않다면 동기화 어댑터 만들기 과정으로 이동하세요.