Créer un authentificateur de bouchon

Le framework de l'adaptateur de synchronisation suppose que celui-ci transfère les données entre l'espace de stockage de l'appareil associé à un compte et l'espace de stockage du serveur nécessitant un accès. Pour cette raison, le framework s'attend à ce que vous fournissiez un composant appelé authentificateur dans le cadre de votre adaptateur de synchronisation. Ce composant se connecte au framework d'authentification et aux comptes Android, et fournit une interface standard pour gérer les identifiants utilisateur tels que les informations de connexion.

Même si votre application n'utilise pas de comptes, vous devez fournir un composant d'authentification. Si vous n'utilisez pas les comptes ni la connexion au serveur, les informations gérées par l'authentificateur sont ignorées. Vous pouvez ainsi fournir un composant d'authentification contenant des implémentations de méthodes bouchon. Vous devez également fournir un Service lié qui permet au framework de l'adaptateur de synchronisation d'appeler les méthodes de l'authentificateur.

Cette leçon vous explique comment définir toutes les parties d'un authentificateur de bouchon dont vous avez besoin pour répondre aux exigences du framework de l'adaptateur de synchronisation. Si vous devez fournir un véritable authentificateur qui gère les comptes utilisateur, consultez la documentation de référence de AbstractAccountAuthenticator.

Ajouter un composant d'authentification de bouchon

Pour ajouter un composant d'authentification de bouchon à votre application, créez une classe qui étend AbstractAccountAuthenticator, puis bouchons les méthodes requises en renvoyant null ou en générant une exception.

L'extrait de code suivant présente un exemple de classe d'authentification bouchon:

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

Lier l'authentificateur au framework

Pour que le framework de l'adaptateur de synchronisation puisse accéder à votre authentificateur, vous devez créer un service lié pour celui-ci. Ce service fournit un objet de liaison Android qui permet au framework d'appeler votre authentificateur et de transmettre des données entre l'authentificateur et le framework.

L'extrait de code suivant vous montre comment définir l'élément Service lié:

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

Ajouter le fichier de métadonnées de l'authentificateur

Pour connecter votre composant d'authentification aux frameworks d'adaptateur de synchronisation et de compte, vous devez fournir à ces frameworks des métadonnées qui décrivent le composant. Ces métadonnées indiquent le type de compte que vous avez créé pour votre adaptateur de synchronisation et déclarent les éléments d'interface utilisateur que le système affiche si vous souhaitez que l'utilisateur puisse voir votre type de compte. Déclarez ces métadonnées dans un fichier XML stocké dans le répertoire /res/xml/ de votre projet d'application. Vous pouvez attribuer n'importe quel nom au fichier, mais il s'appelle généralement authenticator.xml.

Ce fichier XML contient un seul élément <account-authenticator> qui possède les attributs suivants:

android:accountType
Le framework de l'adaptateur de synchronisation nécessite que chaque adaptateur dispose d'un type de compte, sous la forme d'un nom de domaine. Le framework utilise le type de compte dans le cadre de l'identification interne de l'adaptateur de synchronisation. Pour les serveurs nécessitant une connexion, le type de compte et le compte utilisateur sont envoyés au serveur dans les identifiants de connexion.

Même si votre serveur ne nécessite pas de connexion, vous devez indiquer un type de compte. Pour la valeur, utilisez un nom de domaine que vous contrôlez. Bien que le framework l'utilise pour gérer votre adaptateur de synchronisation, la valeur n'est pas envoyée à votre serveur.

android:icon
Pointeur vers une ressource Drawable contenant une icône. Si vous rendez l'adaptateur de synchronisation visible en spécifiant l'attribut android:userVisible="true" dans res/xml/syncadapter.xml, vous devez fournir cette ressource d'icône. Il apparaît dans la section Comptes de l'application Paramètres du système.
android:smallIcon
Pointeur vers une ressource Drawable contenant une version réduite de l'icône. Selon la taille de l'écran, cette ressource peut être utilisée à la place de android:icon dans la section Accounts (Comptes) de l'application Paramètres du système.
android:label
Chaîne localisable qui identifie le type de compte auprès des utilisateurs. Si vous rendez l'adaptateur de synchronisation visible en spécifiant l'attribut android:userVisible="true" dans res/xml/syncadapter.xml, vous devez fournir cette chaîne. Il apparaît dans la section Accounts (Comptes) de l'application Paramètres du système, à côté de l'icône que vous définissez pour l'authentificateur.

L'extrait de code suivant montre le fichier XML de l'authentificateur que vous avez créé précédemment:

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

Déclarer l'authentificateur dans le fichier manifeste

Lors d'une étape précédente, vous avez créé un Service lié qui associe l'authentificateur au framework de l'adaptateur de synchronisation. Pour identifier ce service dans le système, déclarez-le dans le fichier manifeste de votre application en ajoutant l'élément <service> suivant en tant qu'élément enfant 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>

L'élément <intent-filter> configure un filtre déclenché par l'action d'intent android.accounts.AccountAuthenticator, envoyée par le système pour exécuter l'authentificateur. Lorsque le filtre est déclenché, le système démarre AuthenticatorService, la Service liée que vous avez fournie pour encapsuler l'authentificateur.

L'élément <meta-data> déclare les métadonnées pour l'authentificateur. L'attribut android:name associe les métadonnées au framework d'authentification. L'élément android:resource spécifie le nom du fichier de métadonnées de l'authentificateur que vous avez créé précédemment.

En plus d'un authentificateur, un adaptateur de synchronisation nécessite un fournisseur de contenu. Si votre application n'utilise pas encore de fournisseur de contenu, passez à la leçon suivante pour découvrir comment créer un fournisseur de contenu bouchon. Sinon, passez à la leçon Créer un adaptateur de synchronisation.