Optimiser votre application pour la saisie automatique

Les applications qui utilisent des vues standards fonctionnent avec Autofill Framework sans nécessiter de configuration particulière. Cependant, vous pouvez optimiser le fonctionnement de votre application avec le framework.

Configurer l'environnement de saisie automatique

Cette section explique comment configurer la fonctionnalité de saisie automatique de base pour votre application.

Configurer un service de saisie automatique

Vous devez configurer un service de saisie automatique sur votre appareil pour que votre application utilise le framework de saisie automatique. Bien que la plupart des téléphones et tablettes équipés d'Android 8.0 (niveau d'API 26) ou version ultérieure soient équipés d'un service de saisie automatique, nous vous recommandons d'utiliser un service de test, comme le service de saisie automatique de l'exemple de framework de saisie automatique Android Java | Kotlin. Lorsque vous utilisez un émulateur, vous devez définir explicitement un service de saisie automatique, car il n'est peut-être pas fourni avec un service par défaut.

Après avoir installé le service de saisie automatique de test à partir de l'application exemple, activez-le en accédant à Paramètres > Système > Langues et saisie > Paramètres avancés > Aide à la saisie > Service de saisie automatique.

Pour en savoir plus sur la configuration d'un émulateur pour tester la saisie automatique, consultez Tester votre application avec la saisie automatique.

Fournir des indications pour la saisie automatique

Le service de saisie automatique tente de déterminer le type de chaque affichage à l'aide d'heuristiques. Toutefois, si votre application repose sur ces méthodes heuristiques, le comportement de saisie automatique peut changer de manière inattendue lorsque vous mettez à jour votre application. Pour vous assurer que le service de saisie automatique identifie correctement les facteurs de forme de votre application, vous devez fournir des indications pour la saisie automatique.

Vous pouvez définir ces indications à l'aide de l'attribut android:autofillHints. L'exemple suivant définit un indice "password" sur un EditText :

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:autofillHints="password" />

Vous pouvez également définir des indications programmatiques à l'aide de la méthode setAutofillHints(), comme illustré dans l'exemple suivant :

Kotlin

val password = findViewById<EditText>(R.id.password)
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD)

Java

EditText password = findViewById(R.id.password);
password.setAutofillHints(View.AUTOFILL_HINT_PASSWORD);

Constantes d'optimisation prédéfinies

Le framework de saisie automatique ne valide pas les indications. Ils sont transmis sans modification ni validation au service de saisie automatique. Bien que vous puissiez utiliser n'importe quelle valeur, les classes View et HintConstants AndroidX contiennent des listes de constantes d'optimisation officiellement compatibles.

En combinant ces constantes, vous pouvez créer des mises en page pour les scénarios de saisie automatique les plus courants :

Identifiants du compte

Lors de la saisie automatique des identifiants du compte, un formulaire de connexion peut inclure des indications telles que AUTOFILL_HINT_USERNAME et AUTOFILL_HINT_PASSWORD.

Lorsque vous créez un nouveau compte, ou lorsque les utilisateurs changent de nom d'utilisateur et de mot de passe, vous pouvez utiliser AUTOFILL_HINT_NEW_USERNAME et AUTOFILL_HINT_NEW_PASSWORD.

Informations de carte de crédit

Lorsque vous demandez des informations de carte de crédit, vous pouvez utiliser des indications telles que AUTOFILL_HINT_CREDIT_CARD_NUMBER et AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE.

Pour les dates d'expiration des cartes de crédit, effectuez l'une des actions suivantes :

Adresse physique

Lorsque vous saisissez automatiquement une adresse physique, vous pouvez utiliser des indications telles que :

Noms de personnes

Lorsque vous remplissez automatiquement les noms des personnes, vous pouvez utiliser des indications comme celles-ci :

Numéros de téléphone

Pour les numéros de téléphone, vous pouvez utiliser les indications suivantes :

Mot de passe à usage unique (OTP)

Pour obtenir un mot de passe à usage unique dans un seul affichage, vous pouvez utiliser AUTOFILL_HINT_SMS_OTP.

Si vous utilisez un affichage pour chaque chiffre du mot de passe à usage unique, vous pouvez utiliser la méthode generateSmsOtpHintForCharacterPosition() pour générer des indications par caractère.

Marquer des champs comme importants pour la saisie automatique

Vous pouvez indiquer au système si les champs individuels de votre application doivent être inclus dans une structure d'affichage pour la saisie automatique. Par défaut, l'affichage utilise le mode IMPORTANT_FOR_AUTOFILL_AUTO, qui permet à Android d'utiliser ses heuristiques pour déterminer si l'affichage est important pour la saisie automatique.

Vous pouvez définir l'importance à l'aide de l'attribut android:importantForAutofill :

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:importantForAutofill="no" />

La valeur de importantForAutofill peut être l'une des valeurs définies dans android:importantForAutofill :

auto
Laissez le système Android utiliser ses heuristiques pour déterminer si l'affichage est important pour la saisie automatique.
no
Cet affichage n'est pas important pour la saisie automatique.
noExcludeDescendants
Cet affichage et ses éléments enfants ne sont pas importants pour la saisie automatique.
yes
Cet affichage est important pour la saisie automatique.
yesExcludeDescendants
Cet affichage est important pour la saisie automatique, mais pas ses éléments enfants.

Vous pouvez également utiliser la méthode setImportantForAutofill() :

Kotlin

val captcha = findViewById<TextView>(R.id.captcha)
captcha.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO)

Java

TextView captcha = findViewById(R.id.captcha);
captcha.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);

Il peut arriver qu'un affichage, une structure d'affichage ou l'ensemble de l'activité ne soient pas importants pour la saisie automatique :

  • Un champ CAPTCHA dans une activité de connexion n'est généralement pas important pour la saisie automatique. Dans ce cas, vous pouvez marquer l'affichage comme étant IMPORTANT_FOR_AUTOFILL_NO.
  • Dans un affichage pour lequel l'utilisateur crée un contenu, comme un éditeur de texte ou de feuille de calcul, la structure de l'affichage n'est généralement pas importante pour la saisie automatique. Dans ce cas, vous pouvez marquer l'affichage comme étant IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS afin de vous assurer que tous les enfants sont également marqués comme non importants pour la saisie automatique.
  • Dans certaines activités de jeux, telles que celles qui affichent des séquences de jeu, aucun des affichages enregistrés n'est important pour la saisie automatique. Vous pouvez marquer l'affichage racine comme étant IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, pour vous assurer que tous les affichages de l'activité sont marqués comme non importants pour la saisie automatique.

Associer les données de sites Web et d'applications mobiles

Une fois l'application et le site Web associés, les services de saisie automatique tels que la saisie automatique avec Google peuvent partager les données de connexion des utilisateurs entre les navigateurs et les appareils Android. Lorsqu'un utilisateur choisit le même service de saisie automatique sur les deux plates-formes et qu'il se connecte à votre application, ses identifiants sont disponibles pour la saisie automatique lors de la connexion à l'application Android correspondante.

Pour associer votre application Android à votre site Web, vous devez héberger un Digital Asset Link avec la relation delegate_permission/common.get_login_creds sur votre site. Ensuite, déclarez l'association dans le fichier AndroidManifest.xml de votre application. Pour obtenir des instructions détaillées sur l'association de votre site Web à votre application Android, consultez la page Activer la connexion automatique entre les applications et les sites Web.

Terminer le workflow de saisie automatique

Cette section décrit des scénarios spécifiques dans lesquels vous pouvez prendre des mesures pour améliorer la fonctionnalité de saisie automatique pour les utilisateurs de votre application.

Déterminer si la saisie automatique est activée

Vous pouvez implémenter des fonctionnalités de saisie automatique supplémentaires dans votre application, voire dans certains affichages de votre application, si l'utilisateur a accès à cette fonctionnalité. Par exemple, TextView affiche une entrée de saisie automatique dans le menu à développer si la saisie automatique est activée pour l'utilisateur. Pour vérifier si la saisie automatique est activée pour l'utilisateur, appelez la méthode isEnabled() de l'objet AutofillManager.

Les utilisateurs peuvent activer ou désactiver la saisie automatique, et modifier le service de saisie automatique, en accédant à Paramètres > Système > Langues et saisie > Paramètres avancés > Aide à la saisie > Service de saisie automatique. Votre application ne peut pas remplacer les paramètres de saisie automatique de l'utilisateur.

Pour vous assurer que l'inscription et la connexion sont optimisées pour les utilisateurs sans saisie automatique, envisagez d'implémenter Smart Lock pour les mots de passe.

Forcer une requête de saisie automatique

Vous devrez peut-être parfois forcer une requête de saisie automatique en réponse à une action de l'utilisateur. Par exemple, TextView propose un élément de menu de saisie automatique lorsque l'utilisateur appuie de manière prolongée sur l'affichage. L'exemple de code suivant montre comment forcer une requête de saisie automatique :

Kotlin

fun eventHandler(view: View) {
    val afm = requireContext().getSystemService(AutofillManager::class.java)
    afm?.requestAutofill(view)
}

Java

public void eventHandler(View view) {
    AutofillManager afm = context.getSystemService(AutofillManager.class);
    if (afm != null) {
        afm.requestAutofill(view);
    }
}

Vous pouvez également utiliser la méthode cancel() pour annuler le contexte de saisie automatique actuel. Cela peut être utile, par exemple, si vous avez un bouton permettant d'effacer les champs sur une page de connexion.

Utiliser le type de saisie automatique approprié pour les données dans les commandes du sélecteur

Les outils de sélection sont utiles dans certains scénarios de saisie automatique, car ils fournissent une UI (interface utilisateur) qui permet aux utilisateurs de modifier la valeur d'un champ qui stocke des données de date ou d'heure. Par exemple, dans un formulaire de carte de crédit, un sélecteur de date permet aux utilisateurs de saisir ou de modifier la date d'expiration de leur carte de crédit. Toutefois, vous devez utiliser un autre affichage, tel que EditText, pour afficher les données lorsque l'outil de sélection n'est pas visible.

Un objet EditText attend de façon native des données de saisie automatique de type AUTOFILL_TYPE_TEXT. Si vous utilisez un autre type de données, vous devez créer un affichage personnalisé qui hérite de EditText et mette en œuvre les méthodes requises pour gérer le type de données correspondant. Par exemple, si vous disposez d'un champ de date, implémentez les méthodes avec une logique qui gère correctement les valeurs de type AUTOFILL_TYPE_DATE.

Lorsque vous spécifiez le type de données de saisie automatique, le service de saisie automatique peut créer une représentation appropriée des données affichées dans l'affichage. Pour en savoir plus, consultez la section Utiliser les outils de sélection avec la saisie automatique.

Terminer le contexte de saisie automatique

Le framework de saisie automatique enregistre les entrées utilisateur pour une utilisation ultérieure en affichant le message "Enregistrer pour la saisie automatique ?" une fois que le contexte de saisie automatique est terminé. En général, le contexte de saisie automatique est terminé à la fin d'une activité. Cependant, dans certains cas, vous devez explicitement en informer le framework ; par exemple, si vous utilisez la même activité mais des fragments différents pour vos écrans de connexion et de contenu. Dans ces situations particulières, vous pouvez terminer explicitement le contexte en appelant AutofillManager.commit().

Compatibilité avec les affichages personnalisés

Les affichages personnalisés peuvent spécifier les métadonnées exposées au framework de saisie automatique à l'aide de l'API de saisie automatique. Certains affichages agissent comme un conteneur d'éléments enfants virtuels tels que les affichages contenant une UI rendue par OpenGL. Ces affichages doivent utiliser l'API pour spécifier la structure des informations utilisées dans l'application avant de pouvoir fonctionner avec le framework de saisie automatique.

Si votre application utilise des affichages personnalisés, vous devez tenir compte des scénarios suivants :

  • L'affichage personnalisé fournit une structure d'affichage standard ou une structure d'affichage par défaut.
  • L'affichage personnalisé présente une structure virtuelle ou une structure d'affichage qui n'est pas disponible pour le framework de saisie automatique.

Affichages personnalisés avec structure d'affichage standard

Les affichages personnalisés peuvent définir les métadonnées dont la saisie automatique a besoin pour fonctionner. Vous devez vous assurer que votre affichage personnalisé gère les métadonnées de manière appropriée pour fonctionner avec le framework de saisie automatique. Votre affichage personnalisé doit effectuer les actions suivantes :

  • Gérer la valeur de saisie automatique que le framework envoie à votre application.
  • Indiquer le type et la valeur de la saisie automatique dans le framework.

Lorsque la saisie automatique est déclenchée, le framework de saisie automatique appelle autofill() sur votre affichage et envoie la valeur qu'il doit utiliser. Vous devez implémenter autofill() pour spécifier la manière dont votre affichage personnalisé gère la valeur de saisie automatique.

Votre affichage doit spécifier un type et une valeur de saisie automatique en remplaçant les méthodes getAutofillType() et getAutofillValue(), respectivement. En ajoutant ce code, vous vous assurez que votre affichage peut fournir des valeurs et des types de saisie automatique appropriés au framework.

Enfin, la saisie automatique ne doit pas remplir l'affichage si l'utilisateur ne peut pas lui fournir de valeur dans son état actuel (par exemple, si l'affichage est désactivé). Dans ce cas, getAutofillType() doit renvoyer AUTOFILL_TYPE_NONE, getAutofillValue() doit renvoyer null et autofill() ne doit rien faire.

Les cas suivants nécessitent des étapes supplémentaires pour fonctionner correctement dans le framework :

  • L'affichage personnalisé peut être modifié.
  • L'affichage personnalisé contient des données sensibles.

L'affichage personnalisé peut être modifié

Si l'affichage est modifiable, vous devez informer le framework de saisie automatique des modifications en appelant notifyValueChanged() sur l'objet AutofillManager.

L'affichage personnalisé contient des données sensibles

Si l'affichage contient des informations permettant d'identifier personnellement l'utilisateur telles que des adresses e-mail, des numéros de carte de crédit et des mots de passe, il doit être marqué comme tel. En général, les affichages dont le contenu provient de ressources statiques ne contiennent pas de données sensibles, mais les affichages dont le contenu est défini de manière dynamique peuvent contenir des données sensibles. Par exemple, un libellé contenant saisissez votre nom d'utilisateur ne contient pas de données sensibles, contrairement à un libellé contenant Bonjour, John. Pour indiquer si l'affichage contient des données sensibles ou non, implémentez onProvideAutofillStructure() et appelez setDataIsSensitive() sur l'objet ViewStructure.

L'exemple de code suivant montre comment marquer les données de la structure d'affichage comme sensibles ou non :

Kotlin

override fun onProvideAutofillStructure(structure: ViewStructure, flags: Int) {
    super.onProvideAutofillStructure(structure, flags)

    // Content that comes from static resources generally isn't sensitive.
    val sensitive = !contentIsSetFromResources()
    structure.setDataIsSensitive(sensitive)
}

Java

@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
    super.onProvideAutofillStructure(structure, flags);

    // Content that comes from static resources generally isn't sensitive.
    boolean sensitive = !contentIsSetFromResources();
    structure.setDataIsSensitive(sensitive);
}

Si l'affichage n'accepte que des valeurs prédéfinies, vous pouvez utiliser la méthode setAutofillOptions() pour définir les options pouvant être utilisées pour la saisie automatique. En particulier, les affichages dont le type de saisie automatique est AUTOFILL_TYPE_LIST doivent utiliser cette méthode, car le service de saisie automatique peut s'avérer plus efficace s'il connaît les options disponibles pour remplir l'affichage.

Les affichages qui utilisent un adaptateur, comme une Spinner, sont similaires. Par exemple, une icône de chargement qui fournit des années créées de manière dynamique (en fonction de l'année en cours) à utiliser dans les champs d'expiration de cartes de crédit peut implémenter la méthode getAutofillOptions() de l'interface Adapter pour fournir une liste d'années.

Les affichages qui utilisent un ArrayAdapter peuvent également fournir des listes de valeurs. ArrayAdapter définit automatiquement les options de saisie automatique pour les ressources statiques. Toutefois, si vous fournissez les valeurs de façon dynamique, vous devez remplacer getAutofillOptions().

Affichages personnalisés avec structure virtuelle

Le framework de saisie automatique nécessite une structure d'affichage pour pouvoir modifier et enregistrer les informations dans l'UI de votre application. Dans certains cas, la structure d'affichage n'est pas disponible pour le framework :

  • L'application utilise un moteur de rendu de bas niveau, tel que OpenGL, pour afficher l'UI.
  • L'application utilise une instance de Canvas pour dessiner l'UI.

Dans ce cas, vous pouvez spécifier une structure d'affichage en implémentant onProvideAutofillVirtualStructure() et en procédant comme suit :

  1. Augmentez le nombre d'éléments enfants de la structure d'affichage en appelant addChildCount().
  2. Ajoutez un élément enfant en appelant newChild().
  3. Définissez l'ID de saisie automatique pour l'élément enfant en appelant setAutofillId().
  4. Définissez les propriétés pertinentes telles que la valeur et le type de saisie automatique.
  5. Si les données de l'élément enfant virtuel sont sensibles, vous devez transmettre true pour setDataIsSensitive() ou false dans le cas contraire.

L'extrait de code suivant montre comment créer un élément enfant dans la structure virtuelle :

Kotlin

override fun onProvideAutofillVirtualStructure(structure: ViewStructure, flags: Int) {

    super.onProvideAutofillVirtualStructure(structure, flags)

    // Create a new child in the virtual structure.
    structure.addChildCount(1)
    val child = structure.newChild(childIndex)

    // Set the autofill ID for the child.
    child.setAutofillId(structure.autofillId!!, childVirtualId)

    // Populate the child by providing properties such as value and type.
    child.setAutofillValue(childAutofillValue)
    child.setAutofillType(childAutofillType)

    // Some children can provide a list of values. For example, if the child is
    // a spinner.
    val childAutofillOptions = arrayOf<CharSequence>("option1", "option2")
    child.setAutofillOptions(childAutofillOptions)

    // Just like other types of views, mark the data as sensitive, if
    // appropriate.
    val sensitive = !contentIsSetFromResources()
    child.setDataIsSensitive(sensitive)
}

Java

@Override
public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {

    super.onProvideAutofillVirtualStructure(structure, flags);

    // Create a new child in the virtual structure.
    structure.addChildCount(1);
    ViewStructure child =
            structure.newChild(childIndex);

    // Set the autofill ID for the child.
    child.setAutofillId(structure.getAutofillId(), childVirtualId);

    // Populate the child by providing properties such as value and type.
    child.setAutofillValue(childAutofillValue);
    child.setAutofillType(childAutofillType);

    // Some children can provide a list of values. For example, if the child is
    // a spinner.
    CharSequence childAutofillOptions[] = { "option1", "option2" };
    child.setAutofillOptions(childAutofillOptions);

    // Just like other types of views, mark the data as sensitive, if
    // appropriate.
    boolean sensitive = !contentIsSetFromResources();
    child.setDataIsSensitive(sensitive);
}

Lorsque des éléments d'une structure virtuelle changent, vous devez en informer le framework en effectuant les tâches suivantes :

  • Si l'objectif dans les éléments enfants change, appelez notifyViewEntered() et notifyViewExited() sur l'objet AutofillManager.
  • Si la valeur d'un élément enfant change, appelez notifyValueChanged() sur l'objet AutofillManager.
  • Si la hiérarchie des affichages n'est plus disponible, car l'utilisateur a terminé une étape du workflow (par exemple, s'il s'est connecté à l'aide d'un formulaire de connexion), appelez commit() sur l'objet AutofillManager.
  • Si la hiérarchie des affichages n'est plus valide, car l'utilisateur a annulé une étape du workflow (par exemple, s'il clique sur un bouton permettant d'effacer un formulaire de connexion), appelez cancel() sur l'objet AutofillManager.

Utiliser des rappels pour les événements de saisie automatique

Si votre application fournit ses propres affichages avec saisie semi-automatique, vous avez besoin d'un mécanisme qui indique à l'application d'activer ou de désactiver les affichages en réponse aux modifications de l'affordance de saisie automatique de l'UI. Le framework de saisie automatique fournit ce mécanisme sous la forme AutofillCallback.

Cette classe fournit la méthode onAutofillEvent(View, int), que l'application appelle après un changement de l'état de saisie automatique associé à un affichage. Il existe également une version surchargée de cette méthode, qui inclut un paramètre childId que votre application peut utiliser avec des affichages virtuels. Les états disponibles sont définis comme des constantes dans le rappel.

Vous pouvez enregistrer un rappel à l'aide de la méthode registerCallback() de la classe AutofillManager. L'exemple de code suivant montre comment déclarer un rappel pour les événements de saisie automatique :

Kotlin

val afm = context.getSystemService(AutofillManager::class.java)

afm?.registerCallback(object : AutofillManager.AutofillCallback() {
    // For virtual structures, override
    // onAutofillEvent(View view, int childId, int event) instead.
    override fun onAutofillEvent(view: View, event: Int) {
        super.onAutofillEvent(view, event)
        when (event) {
            EVENT_INPUT_HIDDEN -> {
                // The autofill affordance associated with the view was hidden.
            }
            EVENT_INPUT_SHOWN -> {
                // The autofill affordance associated with the view was shown.
            }
            EVENT_INPUT_UNAVAILABLE -> {
                // Autofill isn't available.
            }
        }

    }
})

Java

AutofillManager afm = getContext().getSystemService(AutofillManager.class);

afm.registerCallback(new AutofillManager.AutofillCallback() {
    // For virtual structures, override
    // onAutofillEvent(View view, int childId, int event) instead.
    @Override
    public void onAutofillEvent(@NonNull View view, int event) {
        super.onAutofillEvent(view, event);
        switch (event) {
            case EVENT_INPUT_HIDDEN:
                // The autofill affordance associated with the view was hidden.
                break;
            case EVENT_INPUT_SHOWN:
                // The autofill affordance associated with the view was shown.
                break;
            case EVENT_INPUT_UNAVAILABLE:
                // Autofill isn't available.
                break;
        }
    }
});

Lorsque le moment est venu de supprimer le rappel, utilisez la méthode unregisterCallback().

Personnaliser le drawable en surbrillance de la saisie automatique

Lorsqu'un affichage est saisi automatiquement, la plate-forme affiche un élément Drawable au-dessus de l'affichage pour indiquer que son contenu a été saisi automatiquement. Par défaut, ce drawable est un rectangle plein avec une couleur translucide légèrement plus sombre que la couleur du thème utilisée pour dessiner les arrière-plans. Il n'est pas nécessaire de modifier le drawable, mais vous pouvez le personnaliser en remplaçant l'élément android:autofilledHighlight du thème utilisé par l'application ou l'activité, comme illustré dans cet exemple :

res/values/styles.xml

<resources>
    <style name="MyAutofilledHighlight" parent="...">
        <item name="android:autofilledHighlight">@drawable/my_drawable</item>
    </style>
</resources>

res/drawable/my_drawable.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#4DFF0000" />
</shape>

AndroidManifest.xml

<application ...
    android:theme="@style/MyAutofilledHighlight">
<!-- or -->
<activity ...
    android:theme="@style/MyAutofilledHighlight">

Authentification pour la saisie automatique

Un service de saisie automatique peut exiger l'authentification de l'utilisateur avant de remplir des champs de votre application. Dans ce cas, le système Android lance l'activité d'authentification du service dans la pile de votre activité.

Vous n'avez pas besoin de mettre à jour votre application pour qu'elle soit compatible avec l'authentification, car elle s'effectue dans le service. Cependant, vous devez vous assurer que la structure d'affichage de l'activité est conservée lors du redémarrage de l'activité (par exemple, en créant la structure d'affichage dans onCreate(), et non dans onStart() ou onResume()).

Vous pouvez vérifier le comportement de votre application lorsqu'un service de saisie automatique nécessite une authentification. Pour ce faire, utilisez HeuristicsService dans l'exemple AutofillFramework et configurez-le pour qu'il exige une authentification de réponse au remplissage. Vous pouvez également utiliser l'exemple BadViewStructureCreationSignInActivity pour émuler ce problème.

Attribuer des ID de saisie automatique aux affichages recyclés

Les conteneurs qui recyclent des affichages, comme la classe RecyclerView, sont très utiles pour les applications qui doivent afficher des listes déroulantes d'éléments en fonction de grands ensembles de données. Lorsque le conteneur fait défiler la page, le système réutilise les affichages dans la mise en page, mais ils comportent du nouveau contenu. Si le contenu initial de l'affichage est rempli, le service de saisie automatique conserve la signification logique des affichages en utilisant leurs ID de saisie automatique. Un problème peut survenir lorsque le système réutilise les affichages dans la mise en page et que les ID logiques des affichages restent identiques, ce qui entraîne l'association de données utilisateur incorrectes à un ID de saisie automatique.

Pour résoudre ce problème sur les appareils équipés d'Android 9 (niveau d'API 28) ou version ultérieure, vous pouvez gérer explicitement l'ID de saisie automatique des affichages utilisés avec RecyclerView à l'aide des nouvelles méthodes suivantes :

  • La méthode getNextAutofillId() obtient un nouvel ID de saisie automatique propre à l'activité.
  • La méthode setAutofillId() définit l'ID de saisie automatique logique unique de cet affichage dans l'activité.

Résoudre les problèmes connus

Cette section présente des solutions de contournement aux problèmes connus du framework de saisie automatique.

La saisie automatique provoque le plantage des applications sur Android 8.0 et 8.1.

Dans Android 8.0 (niveau d'API 26) et 8.1 (niveau d'API 27), la saisie automatique peut parfois entraîner le plantage de votre application. Pour éviter les problèmes potentiels, ajoutez la balise importantForAutofill=no aux affichages qui n'ont pas été remplis automatiquement. Vous pouvez également ajouter la balise importantForAutofill=noExcludeDescendants pour toute l'activité.

Les boîtes de dialogue redimensionnées ne sont pas prises en compte pour la saisie automatique

Sous Android 8.1 (niveau d'API 27) et versions antérieures, si l'affichage d'une boîte de dialogue est redimensionné alors que la boîte de dialogue est déjà affichée, l'affichage ne sera pas pris en compte pour la saisie automatique. Ces affichages ne sont pas inclus dans l'objet AssistStructure que le système Android envoie au service de saisie automatique. Par conséquent, le service ne peut pas remplir les affichages.

Pour contourner ce problème, remplacez la propriété token des paramètres de la fenêtre de dialogue par la propriété token de l'activité qui crée la boîte de dialogue. Après avoir vérifié que la saisie automatique est activée, enregistrez les paramètres de fenêtre dans la méthode onWindowAttributesChanged() de la classe qui hérite de Dialog. Remplacez ensuite la propriété token des paramètres enregistrés par la propriété token de l'activité parente dans la méthode onAttachedToWindow().

L'extrait de code suivant montre une classe mettant en œuvre la solution de contournement :

Kotlin

class MyDialog(context: Context) : Dialog(context) {

    // Used to store the dialog window parameters.
    private var token: IBinder? = null

    private val isDialogResizedWorkaroundRequired: Boolean
        get() {
            if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O || Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
                return false
            }
            val autofillManager = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                context.getSystemService(AutofillManager::class.java)
            } else {
                null
            }
            return autofillManager?.isEnabled ?: false
        }

    override fun onWindowAttributesChanged(params: WindowManager.LayoutParams) {
        if (params.token == null && token != null) {
            params.token = token
        }

        super.onWindowAttributesChanged(params)
    }

    override fun onAttachedToWindow() {
        if (isDialogResizedWorkaroundRequired) {
            token = ownerActivity!!.window.attributes.token
        }

        super.onAttachedToWindow()
    }

}

Java

public class MyDialog extends Dialog {

    public MyDialog(Context context) {
        super(context);
    }

    // Used to store the dialog window parameters.
    private IBinder token;

    @Override
    public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
        if (params.token == null && token != null) {
            params.token = token;
        }

        super.onWindowAttributesChanged(params);
    }

    @Override
    public void onAttachedToWindow() {
        if (isDialogResizedWorkaroundRequired()) {
            token = getOwnerActivity().getWindow().getAttributes().token;
        }

        super.onAttachedToWindow();
    }

    private boolean isDialogResizedWorkaroundRequired() {
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O
                || Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {
            return false;
        }
        AutofillManager autofillManager =
                null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            autofillManager = getContext().getSystemService(AutofillManager.class);
        }
        return autofillManager != null && autofillManager.isEnabled();
    }

}

Pour éviter des opérations inutiles, l'extrait de code suivant montre comment vérifier si la saisie automatique est compatible avec l'appareil et si elle est activée pour l'utilisateur actuel. Elle indique également si cette solution est nécessaire :

Kotlin

// AutofillExtensions.kt

fun Context.isDialogResizedWorkaroundRequired(): Boolean {
    // After the issue is resolved on Android, you should check if the
    // workaround is still required for the current device.
    return isAutofillAvailable()
}

fun Context.isAutofillAvailable(): Boolean {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        // The autofill framework is only available on Android 8.0
        // or higher.
        return false
    }

    val afm = getSystemService(AutofillManager::class.java)
    // Return true if autofill is supported by the device and enabled
    // for the current user.
    return afm != null && afm.isEnabled
}

Java

public class AutofillHelper {

    public static boolean isDialogResizedWorkaroundRequired(Context context) {
        // After the issue is resolved on Android, you should check if the
        // workaround is still required for the current device.
        return isAutofillAvailable(context);
    }

    public static boolean isAutofillAvailable(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            // The autofill framework is only available on Android 8.0
            // or higher.
            return false;
        }

        AutofillManager afm = context.getSystemService(AutofillManager.class);
        // Return true if autofill is supported by the device and enabled
        // for the current user.
        return afm != null && afm.isEnabled();
    }
}

Tester votre application avec la saisie automatique

La plupart des applications fonctionnent avec les services de saisie automatique sans aucune modification. Toutefois, vous pouvez optimiser votre application pour qu'elle fonctionne de manière optimale avec les services de saisie automatique. Après avoir optimisé votre application, vous devez la tester pour vous assurer qu'elle fonctionne comme prévu avec les services de saisie automatique.

Vous devez utiliser un émulateur ou un appareil physique exécutant Android 8.0 (niveau d'API 26) ou une version ultérieure pour tester votre application. Pour en savoir plus sur la création d'un émulateur, consultez Créer et gérer des appareils virtuels.

Installer un service de saisie automatique

Avant de pouvoir tester votre application avec la saisie automatique, vous devez installer une autre application qui fournit des services de saisie automatique. Vous pouvez utiliser une application tierce à cet effet, mais il est plus facile d'utiliser un exemple de service de saisie automatique. Ainsi, vous n'avez pas besoin de vous inscrire à des services tiers.

Vous pouvez utiliser l'exemple de framework de saisie automatique Java | Kotlin Android pour tester votre application avec les services de saisie automatique. L'application exemple fournit un service de saisie automatique et des classes clientes Activity que vous pouvez utiliser pour tester le workflow avant de l'utiliser avec l'application. Cette page fait référence à l'application exemple android-AutofillFramework.

Après avoir installé l'application, vous devez activer le service de saisie automatique dans les paramètres système. Vous pouvez l'activer en accédant à Paramètres > Système > Langues et saisie > Paramètres avancés > Aide à la saisie > Service de saisie automatique.

Analyser les exigences concernant les données

Pour tester votre application avec le service de saisie automatique, il doit disposer de données permettant de remplir votre application. Le service doit également comprendre le type de données attendu dans les affichages de votre application. Par exemple, si votre application dispose d'un affichage qui s'attend à un nom d'utilisateur, le service doit disposer d'un ensemble de données contenant un nom d'utilisateur et un mécanisme permettant de savoir que l'affichage attend de telles données.

Vous devez indiquer au service le type de données attendu dans vos affichages en définissant l'attribut android:autofillHints. Certains services utilisent des modèles heuristiques sophistiqués pour déterminer le type de données, tandis que d'autres, tels que l'application exemple, dépendent du développeur pour fournir ces informations. Votre application fonctionne mieux avec les services de saisie automatique si vous définissez l'attribut android:autofillHints dans les affichages correspondants.

Exécuter le test

Après avoir analysé les exigences concernant les données, vous pouvez exécuter votre test, ce qui comprend l'enregistrement des données de test dans le service de saisie automatique et le déclenchement de la saisie automatique dans votre application.

Enregistrer les données dans le service

Pour enregistrer les données du service de saisie automatique actif, procédez comme suit :

  1. Ouvrez une application contenant un affichage qui utilise le type de données que vous souhaitez tester. L'application exemple android-AutofillFramework fournit à l'UI des affichages qui attendent plusieurs types de données tels que des numéros de carte de crédit et des noms d'utilisateur.
  2. Appuyez sur l'affichage qui contient le type de données dont vous avez besoin.
  3. Saisissez une valeur dans l'affichage.
  4. Appuyez sur le bouton de confirmation, par exemple Se connecter ou Envoyer.

    Vous devez généralement envoyer le formulaire avant que le service ne tente d'enregistrer les données.

  5. Le système affiche une boîte de dialogue vous demandant l'autorisation d'enregistrer les données. La boîte de dialogue affiche le nom du service actuellement actif.

    Vérifiez qu'il s'agit bien du service que vous souhaitez utiliser dans votre test, puis appuyez sur Enregistrer.

Si Android n'affiche pas la boîte de dialogue d'autorisation, ou si ce service n'est pas celui que vous souhaitez utiliser dans votre test, vérifiez qu'il est actuellement actif dans les paramètres système.

Déclencher la saisie automatique dans votre application

Pour déclencher la saisie automatique dans votre application, procédez comme suit :

  1. Ouvrez votre application et accédez à l'activité qui reprend les affichages que vous souhaitez tester.
  2. Appuyez sur l'affichage à remplir.
  3. Le système doit afficher l'UI de saisie automatique, qui contient les ensembles de données pouvant remplir l'affichage, comme illustré dans la Figure 1.
  4. Appuyez sur l'ensemble de données contenant les données que vous souhaitez utiliser. L'affichage doit afficher les données précédemment stockées dans le service.
UI de saisie automatique affichant
Figure 1. UI de saisie automatique affichant les ensembles de données disponibles.

Si Android n'affiche pas l'UI de saisie automatique, vous pouvez essayer les options de dépannage suivantes :

  • Vérifiez que les affichages de votre application utilisent la valeur correcte dans l'attribut android:autofillHints. Pour obtenir la liste des valeurs possibles pour l'attribut, consultez les constantes précédées du préfixe AUTOFILL_HINT dans la classe View.
  • Vérifiez que l'attribut android:importantForAutofill est défini sur une valeur autre que no sur l'affichage devant être rempli, ou défini sur une valeur autre que noExcludeDescendants sur l'affichage ou un de ses éléments parents.