Cómo crear un autenticador de stub

El framework del adaptador de sincronización supone que tu adaptador de sincronización transfiere datos entre el almacenamiento del dispositivo. asociada a una cuenta y al almacenamiento del servidor que requiere acceso. Por este motivo, el espera que proporciones un componente llamado autenticador como parte de tu adaptador. Este componente se conecta con las cuentas de Android y el framework de autenticación, y y ofrece una interfaz estándar para manejar las credenciales del usuario, como la información de acceso.

Incluso si tu app no usa cuentas, debes proporcionar un componente de autenticación. Si no usas las cuentas ni el acceso al servidor, la información que controla el autenticador se ignorados, por lo que puedes proporcionar un componente autenticador que contenga el método de stub de Google Cloud. También debes proporcionar un Service vinculado que permite que el framework del adaptador de sincronización llame a los métodos del autenticador.

En esta lección, se muestra cómo definir todas las partes de un autenticador de stub que necesitas cumpla con los requisitos del framework del adaptador de sincronización. Si necesitas proporcionar una que administra cuentas de usuario, lee la documentación de referencia para AbstractAccountAuthenticator

Cómo agregar un componente de autenticador de stub

Para agregar un componente de autenticador de stub a tu app, crea una clase que extienda AbstractAccountAuthenticator y, luego, realiza el stub de los métodos requeridos. ya sea demostrando null o lanzando una excepción.

En el siguiente fragmento, se muestra un ejemplo de una clase de autenticador de 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();
    }
}

Cómo vincular el autenticador con el marco de trabajo

Para que el framework del adaptador de sincronización acceda a tu autenticador, debes crear un vínculo Servicio adecuado. Este servicio proporciona un objeto vinculante de Android que permite que el framework llamar a tu autenticador y pasar datos entre el autenticador y el framework.

En el siguiente fragmento, se muestra cómo definir el Service vinculado:

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

Cómo agregar el archivo de metadatos del autenticador

Para conectar el componente autenticador en el adaptador de sincronización y en los marcos de trabajo de cuentas, debes y proporcionarle metadatos que describan el componente a este framework. Estos metadatos declaran la tipo de cuenta que creaste para tu adaptador de sincronización y declara elementos de la interfaz de usuario que muestra el sistema si deseas que tu tipo de cuenta sea visible para el usuario. Declarar esto en un archivo en formato XML almacenado en el directorio /res/xml/ de tu proyecto de app. Puedes nombrar el archivo como quieras, aunque generalmente se llama authenticator.xml.

Este archivo en formato XML contiene un único elemento <account-authenticator> que tiene los siguientes atributos:

android:accountType
El framework del adaptador de sincronización requiere que cada adaptador de sincronización tenga un tipo de cuenta: de un nombre de dominio. El framework usa el tipo de cuenta como parte del directorio la identificación interna. Para los servidores que requieren acceso, el tipo de cuenta junto con una y la cuenta de usuario se envía al servidor como parte de las credenciales de acceso.

Si el servidor no requiere acceso, debes proporcionar un tipo de cuenta. Para el valor, usa un nombre de dominio que tú controles. Si bien el framework los usa para administrar tus de sincronización, el valor no se envía a tu servidor.

android:icon
Es un elemento que apunta a un elemento de diseño. recurso que contiene un ícono. Si haces visible el adaptador de sincronización especificando el el atributo android:userVisible="true" en res/xml/syncadapter.xml, debes proporcionar este recurso de ícono. Aparece en la sección Cuentas de la app de Configuración del sistema.
android:smallIcon
Es un elemento que apunta a un elemento de diseño. recurso que contiene una versión pequeña del ícono. Este recurso se puede usar en lugar de android:icon en la sección Cuentas de la app de Configuración del sistema según el tamaño de la pantalla.
android:label
Es una cadena localizable que identifica el tipo de cuenta de los usuarios. Si creas el adaptador de sincronización visible especificando el atributo android:userVisible="true" en res/xml/syncadapter.xml, debes proporcionar esta cadena. Aparece en la sección Cuentas de la app de Configuración del sistema, junto al ícono que definas para la autenticador.

En el siguiente fragmento de código, se muestra el archivo XML del autenticador que creaste anteriormente:

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

Cómo declarar el autenticador en el manifiesto

En un paso anterior, creaste un Service vinculado que vincula el autenticador. con el framework del adaptador de sincronización. Para que el sistema identifique este servicio, decláralo en tu app del manifiesto agregando lo siguiente <service> como un elemento secundario de <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>

El <intent-filter> elemento configura un filtro que se activa con la acción de intent android.accounts.AccountAuthenticator, que envió el sistema para ejecutar la autenticador. Cuando se activa el filtro, el sistema inicia AuthenticatorService. el Service vinculado que proporcionaste para unir el autenticador

El <meta-data> declara los metadatos del autenticador. El android:name vincula los metadatos con el marco de trabajo de autenticación. El android:resource especifica el nombre del archivo de metadatos del autenticador que creaste anteriormente.

Además de un autenticador, el adaptador de sincronización también requiere un proveedor de contenido. Si tu app no ya usas un proveedor de contenido, ve a la siguiente lección para aprender a crear contenido de stub el proveedor de servicios en la nube; De lo contrario, consulta la lección Cómo crear un adaptador de sincronización.