App für AutoFill optimieren

Anwendungen, die Standardansichten verwenden, funktionieren mit dem Autofill-Framework ohne spezielle Konfiguration. Sie können auch die Funktionsweise Ihrer App mit dem Framework optimieren.

Autofill-Umgebung einrichten

In diesem Abschnitt wird beschrieben, wie Sie die grundlegende Autofill-Funktion für Ihre App einrichten.

Autofill-Dienst konfigurieren

Damit Ihre App das Autofill-Framework verwenden kann, muss auf Ihrem Gerät ein Autofill-Dienst konfiguriert sein. Die meisten Smartphones und Tablets mit Android 8.0 (API-Level 26) und höher sind zwar mit einem Autofill-Dienst ausgestattet, wir empfehlen Ihnen jedoch, beim Testen Ihrer App einen Testdienst zu verwenden, z. B. den Autofill-Dienst im Beispiel für das Android Autofill Framework. Wenn Sie einen Emulator verwenden, legen Sie explizit einen Autofill-Dienst fest, da der Emulator möglicherweise keinen Standarddienst hat.

Nachdem Sie den Test-AutoFill-Dienst aus der Beispiel-App installiert haben, aktivieren Sie ihn unter Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > AutoFill-Dienst.

Weitere Informationen zum Konfigurieren eines Emulators zum Testen der Funktion „Autofill“ finden Sie unter App mit Autofill testen.

Hinweise für das automatische Ausfüllen bereitstellen

Der Autofill-Dienst bestimmt den Typ jeder Ansicht anhand von Heuristiken. Wenn deine App jedoch auf diese Heuristiken angewiesen ist, kann sich das Autofill-Verhalten unerwartet ändern, wenn du deine App aktualisierst. Damit der Autofill-Dienst die Formfaktoren deiner App korrekt erkennt, solltest du Autofill-Hinweise angeben.

Mit dem Attribut android:autofillHints können Sie Autofill-Hinweise festlegen. Im folgenden Beispiel wird ein "password"-Hinweis für ein EditText festgelegt:

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

Sie können Hinweise auch programmatisch mit der Methode setAutofillHints() festlegen, wie im folgenden Beispiel gezeigt:

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

Vordefinierte Hinweise einschließen

Das Autofill-Framework validiert keine Hinweise. Sie werden ohne Änderung oder Validierung an den Autofill-Dienst übergeben. Sie können zwar jeden Wert verwenden, die Klassen View und AndroidX HintConstants enthalten jedoch Listen mit offiziell unterstützten Hinweiskonstanten.

Mit einer Kombination dieser Konstanten können Sie Layouts für gängige Autofill-Szenarien erstellen:

Kontoanmeldedaten

In einem Anmeldeformular können Sie Hinweise zu Anmeldedaten wie AUTOFILL_HINT_USERNAME und AUTOFILL_HINT_PASSWORD einfügen.

Zum Erstellen eines neuen Kontos oder wenn Nutzer ihren Nutzernamen und ihr Passwort ändern, können Sie AUTOFILL_HINT_NEW_USERNAME und AUTOFILL_HINT_NEW_PASSWORD verwenden.

Kreditkartendaten

Wenn Sie Kreditkarteninformationen anfordern, können Sie Hinweise wie AUTOFILL_HINT_CREDIT_CARD_NUMBER und AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE verwenden.

Führen Sie einen der folgenden Schritte aus, um das Ablaufdatum Ihrer Kreditkarte anzugeben:

Anschrift

Für Formularfelder für die Anschrift können Sie Hinweise wie die folgenden verwenden:

Namen von Personen

Wenn Sie nach den Namen von Personen fragen, können Sie Hinweise wie die folgenden verwenden:

Telefonnummern

Für Telefonnummern können Sie Folgendes verwenden:

Einmalpasswort (OTP)

Für ein Einmalpasswort in einer einzelnen Ansicht können Sie AUTOFILL_HINT_SMS_OTP verwenden.

Bei mehreren Ansichten, bei denen jede Ansicht einer einzelnen Ziffer des OTP zugeordnet ist, können Sie mit der Methode generateSmsOtpHintForCharacterPosition() Hinweise für einzelne Zeichen generieren.

Felder für Autofill als wichtig markieren

Sie können die einzelnen Felder in Ihrer App in einer Ansichtsstruktur für das automatische Ausfüllen einschließen. Standardmäßig wird für Ansichten der Modus IMPORTANT_FOR_AUTOFILL_AUTO verwendet. Dadurch kann Android anhand seiner Heuristiken ermitteln, ob eine Ansicht für das automatische Ausfüllen wichtig ist.

Es gibt jedoch Fälle, in denen eine Ansicht, eine Ansichtsstruktur oder die gesamte Aktivität für das automatische Ausfüllen nicht wichtig ist:

  • Ein CAPTCHA-Feld in einer Anmeldeaktivität
  • Eine Ansicht, in der Nutzer Inhalte erstellen, z. B. ein Text- oder Tabelleneditor
  • Die Aufrufe bei einigen Aktivitäten in Spielen, z. B. bei solchen, die Gameplay zeigen

Mit dem Attribut android:importantForAutofill können Sie die Wichtigkeit einer Ansicht für das automatische Ausfüllen festlegen:

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

Für importantForAutofill kann einer der folgenden Werte angegeben werden:

auto
Lasse das Android-System anhand seiner Heuristik bestimmen, ob die Ansicht für die Funktion „Autofill“ wichtig ist.
no
Diese Ansicht ist für das automatische Ausfüllen nicht wichtig.
noExcludeDescendants
Diese Ansicht und ihre untergeordneten Elemente sind für das automatische Ausfüllen nicht wichtig.
yes
Diese Ansicht ist wichtig für das automatische Ausfüllen.
yesExcludeDescendants
Diese Ansicht ist für die Autofill-Funktion wichtig, die untergeordneten Elemente jedoch nicht.

Sie können auch die Methode setImportantForAutofill() verwenden:

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

Sie können die vorherigen Beispiel-Anwendungsfälle so für das automatische Ausfüllen als unwichtig deklarieren:

  • Das Feld CAPTCHA in einer Anmeldeaktivität:Verwenden Sie android:importantForAutofill="no" oder IMPORTANT_FOR_AUTOFILL_NO, um diese Ansicht als unwichtig zu markieren.
  • Eine Ansicht, in der Nutzer Inhalte erstellen:Verwenden Sie android:importantForAutofill="noExcludeDescendants" oder IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, um die gesamte Ansichtsstruktur als unwichtig zu markieren.
  • Die Ansichten in einigen Aktivitäten in Spielen:Verwenden Sie android:importantForAutofill="noExcludeDescendants" oder IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, um die gesamte Ansichtsstruktur als unwichtig zu kennzeichnen.

Website- und App-Daten verknüpfen

Autofill-Dienste wie „Autofill mit Google“ können Anmeldedaten von Nutzern zwischen Browsern und Android-Geräten teilen, nachdem die App und eine Website verknüpft wurden. Wenn ein Nutzer auf beiden Plattformen denselben Autofill-Dienst auswählt, werden seine Anmeldedaten bei der Anmeldung in Ihrer Webanwendung für die automatische Vervollständigung verfügbar gemacht, wenn er sich in der entsprechenden Android-App anmeldet.

Hoste zum Verknüpfen deiner Android-App mit deiner Website einen Digital Asset Link mit der delegate_permission/common.get_login_creds-Beziehung auf deiner Website. Geben Sie dann die Verknüpfung in der AndroidManifest.xml-Datei Ihrer App an. Eine ausführliche Anleitung zum Verknüpfen Ihrer Website mit Ihrer Android-App finden Sie unter Automatische Anmeldung in Apps und auf Websites aktivieren.

Autofill-Workflow abschließen

In diesem Abschnitt werden bestimmte Szenarien beschrieben, in denen Sie Maßnahmen ergreifen können, um die Autofill-Funktion für Nutzer Ihrer App zu verbessern.

Prüfen, ob das automatische Ausfüllen aktiviert ist

Nutzer können Autofill aktivieren oder deaktivieren sowie den Autofill-Dienst ändern, indem sie Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > Autofill-Service aufrufen. Ihre App kann die Autofill-Einstellungen des Nutzers nicht überschreiben. Sie können jedoch zusätzliche Autofill-Funktionen in Ihrer App oder in bestimmten Ansichten Ihrer App implementieren, wenn Autofill für den Nutzer verfügbar ist.

TextView zeigt beispielsweise einen Autofill-Eintrag im Dreipunkt-Menü an, wenn Autofill für den Nutzer aktiviert ist. Wenn du prüfen möchtest, ob Autofill für den Nutzer aktiviert ist, rufe die Methode isEnabled() des AutofillManager-Objekts auf.

Damit die Registrierung und Anmeldung für Nutzer ohne Autofill optimiert ist, sollten Sie die One-Tap-Anmeldung implementieren.

Autofill-Anfrage erzwingen

Manchmal müssen Sie eine Autofill-Anfrage als Reaktion auf eine Nutzeraktion erzwingen. TextView bietet beispielsweise ein Autofill-Menüelement, wenn der Nutzer die Ansicht gedrückt hält. Im folgenden Codebeispiel wird gezeigt, wie Sie eine Autofill-Anfrage erzwingen:

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

Sie können auch die Methode cancel() verwenden, um den aktuellen Autofill-Kontext abzubrechen. Das kann nützlich sein, wenn Sie eine Schaltfläche haben, mit der die Felder auf einer Anmeldeseite gelöscht werden.

Den richtigen Autofill-Typ für Daten in Auswahlelementen verwenden

Auswahlfelder können bei der automatischen Vervollständigung nützlich sein, da sie eine Benutzeroberfläche bieten, mit der Nutzer den Wert eines Felds ändern können, in dem Datums- oder Uhrzeitdaten gespeichert sind. In einem Kreditkartenformular können Nutzer beispielsweise mit einer Datumsauswahl das Ablaufdatum ihrer Kreditkarte eingeben oder ändern. Wenn die Auswahl nicht sichtbar ist, müssen Sie jedoch eine andere Ansicht wie eine EditText verwenden, um die Daten anzuzeigen.

Für ein EditText-Objekt werden standardmäßig Autofill-Daten vom Typ AUTOFILL_TYPE_TEXT erwartet. Wenn Sie einen anderen Datentyp verwenden, erstellen Sie eine benutzerdefinierte Ansicht, die Werte von EditText übernimmt und die für die Verarbeitung des entsprechenden Datentyps erforderlichen Methoden implementiert. Wenn Sie beispielsweise ein Datumsfeld haben, implementieren Sie die Methoden mit einer Logik, die Werte vom Typ AUTOFILL_TYPE_DATE korrekt verarbeitet.

Wenn Sie den Datentyp für die automatische Vervollständigung angeben, kann der Dienst für die automatische Vervollständigung eine geeignete Darstellung der in der Ansicht angezeigten Daten erstellen. Weitere Informationen finden Sie unter Auswahllisten mit automatischer Vervollständigung verwenden.

Autofill-Kontext fertigstellen

Das Autofill-Framework speichert die Nutzereingabe für die zukünftige Verwendung, indem nach Abschluss des Autofill-Kontexts ein Dialogfeld „Für Autofill speichern?“ angezeigt wird. Normalerweise ist der Kontext für die Autofill-Funktion abgeschlossen, wenn eine Aktivität beendet wird. Es gibt jedoch einige Situationen, in denen Sie das Framework explizit benachrichtigen müssen, z. B. wenn Sie dieselbe Aktivität, aber unterschiedliche Fragmente für den Anmelde- und den Inhaltsbildschirm verwenden. In diesen Fällen können Sie den Kontext explizit beenden, indem Sie AutofillManager.commit() aufrufen.

Unterstützung für benutzerdefinierte Ansichten

In benutzerdefinierten Ansichten können die Metadaten angegeben werden, die dem Autofill-Framework mithilfe der Autofill API zur Verfügung gestellt werden. Einige Ansichten fungieren als Container mit virtuellen untergeordneten Elementen, z. B. Ansichten mit einer OpenGL-gerenderten UI. Für diese Ansichten muss die API verwendet werden, um die Struktur der in der App verwendeten Informationen anzugeben, damit sie mit dem Autofill-Framework verwendet werden können.

Wenn Ihre App benutzerdefinierte Ansichten verwendet, sollten Sie die folgenden Szenarien berücksichtigen:

  • Die benutzerdefinierte Ansicht bietet eine Standardansichtsstruktur oder eine Standardansichtsstruktur.
  • Die benutzerdefinierte Ansicht hat eine virtuelle Struktur oder eine Ansichtsstruktur, die für das Autofill-Framework nicht verfügbar ist.

Benutzerdefinierte Ansichten mit Standardansichtsstruktur

In benutzerdefinierten Ansichten können die Metadaten definiert werden, die für die Funktion der automatischen Vervollständigung erforderlich sind. Achten Sie darauf, dass die Metadaten in Ihrer benutzerdefinierten Ansicht für die Verwendung mit dem Autofill-Framework geeignet sind. In Ihrer benutzerdefinierten Ansicht müssen die folgenden Aktionen ausgeführt werden:

  • Bearbeiten Sie den Autofill-Wert, den das Framework an Ihre App sendet.
  • Geben Sie dem Framework den Autofill-Typ und den Wert an.

Wenn das Autofill-System ausgelöst wird, ruft das Autofill-Framework autofill() in Ihrer Ansicht auf und sendet den Wert, der in Ihrer Ansicht verwendet werden muss. Implementieren Sie autofill(), um anzugeben, wie der Autofill-Wert in Ihrer benutzerdefinierten Ansicht verarbeitet wird.

In Ihrer Ansicht müssen Sie einen AutoFill-Typ und einen Wert angeben, indem Sie die Methoden getAutofillType() und getAutofillValue() überschreiben.

Außerdem darf die Ansicht nicht automatisch ausgefüllt werden, wenn der Nutzer keinen Wert für die Ansicht in ihrem aktuellen Status angeben kann, z. B. wenn die Ansicht deaktiviert ist. In diesen Fällen muss getAutofillType() AUTOFILL_TYPE_NONE zurückgeben, getAutofillValue() muss null zurückgeben und autofill() muss nichts tun.

In den folgenden Fällen sind zusätzliche Schritte erforderlich, damit das Framework ordnungsgemäß funktioniert:

  • Die benutzerdefinierte Ansicht kann bearbeitet werden.
  • Die benutzerdefinierte Ansicht enthält vertrauliche Daten.

Die benutzerdefinierte Ansicht kann bearbeitet werden.

Wenn die Ansicht bearbeitet werden kann, informieren Sie das Autofill-Framework über die Änderungen. Dazu rufen Sie notifyValueChanged() für das AutofillManager-Objekt auf.

Die benutzerdefinierte Ansicht enthält sensible Daten

Wenn eine Ansicht personenidentifizierbare Informationen wie E-Mail-Adressen, Kreditkartennummern und Passwörter enthält, muss sie als vertraulich gekennzeichnet werden.

Im Allgemeinen enthalten Ansichten, deren Inhalte von statischen Ressourcen stammen, keine sensiblen Daten, während Ansichten, deren Inhalt dynamisch festgelegt wird, sensible Daten enthalten können. Ein Label mit dem Text Geben Sie Ihren Nutzernamen ein enthält beispielsweise keine vertraulichen Daten, während ein Label mit dem Text Hallo, Johannes dies tut.

Das Autofill-Framework geht davon aus, dass alle Daten standardmäßig vertraulich sind. Sie können Daten als nicht sensibel kennzeichnen.

Wenn Sie angeben möchten, ob eine Ansicht sensible Daten enthält, implementieren Sie onProvideAutofillStructure() und rufen Sie setDataIsSensitive() auf das ViewStructure-Objekt.

Im folgenden Codebeispiel wird gezeigt, wie die Daten in der Ansichtsstruktur als nicht sensibel gekennzeichnet werden:

Kotlin

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

    structure.setDataIsSensitive(false)
}

Java

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

    structure.setDataIsSensitive(false);
}

Wenn für eine Ansicht nur vordefinierte Werte zulässig sind, können Sie mit der Methode setAutofillOptions() die Optionen festlegen, mit denen die Ansicht automatisch ausgefüllt werden kann. Insbesondere für Ansichten mit dem Autofill-Typ AUTOFILL_TYPE_LIST muss diese Methode verwendet werden, da der Autofill-Dienst bessere Ergebnisse erzielen kann, wenn er die Optionen kennt, die zum Ausfüllen der Ansicht verfügbar sind.

Ähnlich verhält es sich bei Ansichten, für die ein Adapter wie Spinner verwendet wird. Beispiel: Ein Auswahlschalter, der dynamisch erstellte Jahre basierend auf dem aktuellen Jahr für die Verwendung in Ablaufdatumfeldern für Kreditkarten bereitstellt, kann die Methode getAutofillOptions() der Benutzeroberfläche Adapter implementieren, um eine Liste der Jahre bereitzustellen.

In Ansichten mit einem ArrayAdapter können auch Listen von Werten verwendet werden. ArrayAdapter setzt automatisch Optionen für das automatische Ausfüllen für statische Ressourcen. Wenn Sie die Werte dynamisch angeben, überschreiben Sie getAutofillOptions().

Benutzerdefinierte Ansichten mit virtueller Struktur

Das Autofill-Framework benötigt eine Ansichtsstruktur, bevor es die Informationen in der Benutzeroberfläche Ihrer App bearbeiten und speichern kann. In den folgenden Fällen ist die Ansichtsstruktur für das Framework nicht verfügbar:

  • Die App verwendet eine Low-Level-Rendering-Engine wie OpenGL, um die Benutzeroberfläche zu rendern.
  • In der App wird eine Instanz von Canvas verwendet, um die Benutzeroberfläche zu zeichnen.

In diesen Fällen können Sie eine Ansichtsstruktur angeben, indem Sie onProvideAutofillVirtualStructure() implementieren und die folgenden Schritte ausführen:

  1. Erhöhen Sie die Anzahl der untergeordneten Elemente der Ansichtsstruktur, indem Sie addChildCount() aufrufen.
  2. Fügen Sie ein untergeordnetes Element hinzu, indem Sie newChild() aufrufen.
  3. Legen Sie die Autofill-ID für das untergeordnete Element fest, indem Sie setAutofillId() aufrufen.
  4. Legen Sie relevante Properties fest, z. B. den Autofill-Wert und -Typ.
  5. Wenn die Daten im virtuellen untergeordneten Element vertraulich sind, übergeben Sie true an setDataIsSensitive(). Andernfalls übergeben Sie false.

Das folgende Code-Snippet zeigt, wie ein neues untergeordnetes Element in der virtuellen Struktur erstellt wird:

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, such as when 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 when
    // 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, such as when the child is
    // a spinner.
    CharSequence childAutofillOptions[] = { "option1", "option2" };
    child.setAutofillOptions(childAutofillOptions);

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

Wenn sich Elemente in einer virtuellen Struktur ändern, benachrichtigen Sie das Framework, indem Sie die folgenden Aufgaben ausführen:

  • Wenn sich der Fokus innerhalb der untergeordneten Elemente ändert, rufe notifyViewEntered() und notifyViewExited() auf das AutofillManager-Objekt auf.
  • Wenn sich der Wert eines untergeordneten Elements ändert, rufen Sie notifyValueChanged() auf das AutofillManager-Objekt auf.
  • Wenn die Ansichtshierarchie nicht mehr verfügbar ist, weil der Nutzer einen Schritt im Workflow abgeschlossen hat, z. B. bei der Anmeldung über ein Anmeldeformular, rufen Sie commit() für das AutofillManager-Objekt auf.
  • Wenn die Ansichtshierarchie nicht gültig ist, weil der Nutzer einen Schritt im Workflow abgebrochen hat, z. B. wenn der Nutzer auf eine Schaltfläche zum Löschen eines Anmeldeformulars tippt, rufe cancel() für das AutofillManager-Objekt auf.

Rückrufe für Autofill-Ereignisse verwenden

Wenn Ihre App eigene Ansichten für die automatische Vervollständigung bietet, benötigen Sie einen Mechanismus, der die App anweist, die Ansichten als Reaktion auf Änderungen an der Affordance für die automatische Vervollständigung auf der Benutzeroberfläche zu aktivieren oder zu deaktivieren. Das AutoFill-Framework bietet diesen Mechanismus in Form von AutofillCallback.

Diese Klasse bietet die Methode onAutofillEvent(View, int), die die App nach einer Änderung des Autofill-Status aufruft, der mit einer Ansicht verknüpft ist. Es gibt auch eine überladene Version dieser Methode, die einen childId-Parameter enthält, den Ihre App mit virtuellen Ansichten verwenden kann. Die verfügbaren Status werden im Rückruf als Konstanten definiert.

Sie können einen Rückruf mit der Methode registerCallback() der Klasse AutofillManager registrieren. Im folgenden Codebeispiel wird gezeigt, wie ein Callback für Autofill-Ereignisse deklariert wird:

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

Wenn Sie den Rückruf entfernen möchten, verwenden Sie die Methode unregisterCallback().

Hervorgehobenes Drawable für die Autofill-Funktion anpassen

Wenn eine Ansicht automatisch ausgefüllt wird, wird auf der Plattform das Symbol Drawable angezeigt, um anzugeben, dass die Inhalt der Ansicht automatisch ausgefüllt werden. Standardmäßig ist dieses Drawable ein ausgefülltes Rechteck mit einer durchscheinenden Farbe, die etwas dunkler ist als die Farbe des Designs, die zum Zeichnen von Hintergründen verwendet wird. Das Drawable muss nicht geändert werden, kann aber angepasst werden, indem das android:autofilledHighlight-Element des von der App oder Aktivität verwendeten Designs überschrieben wird, wie in diesem Beispiel gezeigt:

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

Für Autofill authentifizieren

Ein Autofill-Dienst kann eine Authentifizierung des Nutzers erfordern, bevor der Dienst Felder in Ihrer App ausfüllen kann. In diesem Fall startet das Android-System die Authentifizierungsaktivität des Dienstes als Teil des Stacks Ihrer Aktivität.

Sie müssen Ihre App nicht aktualisieren, um die Authentifizierung zu unterstützen, da die Authentifizierung im Dienst erfolgt. Sie müssen jedoch dafür sorgen, dass die Ansichtsstruktur der Aktivität erhalten bleibt, wenn die Aktivität neu gestartet wird. Dazu erstellen Sie die Ansichtsstruktur z. B. in onCreate() und nicht in onStart() oder onResume().

Sie können prüfen, wie sich Ihre App verhält, wenn für einen Autofill-Dienst eine Authentifizierung erforderlich ist. Verwenden Sie dazu den HeuristicsService aus dem AutofillFramework-Beispiel und konfigurieren Sie ihn so, dass eine Authentifizierung der Antwort für das Ausfüllen erforderlich ist. Sie können auch das Beispiel BadViewStructureCreationSignInActivity verwenden, um dieses Problem zu emulieren.

Autofill-IDs zu wiederverwendeten Ansichten zuweisen

Container, die Ansichten wiederverwenden, z. B. die Klasse RecyclerView, sind nützlich für Apps, in denen scrollbare Listen von Elementen auf der Grundlage großer Datensätze angezeigt werden müssen. Beim Scrollen des Containers werden die Ansichten im Layout vom System wiederverwendet, enthalten aber dann neue Inhalte.

Wenn der ursprüngliche Inhalt einer wiederverwendeten Ansicht ausgefüllt ist, behält der Autofill-Dienst die logische Bedeutung der Ansichten anhand ihrer Autofill-IDs bei. Ein Problem tritt auf, wenn die logischen IDs der Ansichten beim Wiederverwenden der Ansichten im Layout durch das System gleich bleiben, wodurch die falschen Autofill-Nutzerdaten mit einer Autofill-ID verknüpft werden.

Um dieses Problem auf Geräten mit Android 9 (API-Level 28) und höher zu lösen, verwaltest du die Autofill-ID der Ansichten, die von RecyclerView verwendet werden, mit den folgenden Methoden explizit:

  • Die Methode getNextAutofillId() erhält eine neue Autofill-ID, die für die Aktivität eindeutig ist.
  • Mit der Methode setAutofillId() wird die eindeutige, logische Autofill-ID dieser Ansicht in der Aktivität festgelegt.

Bekannte Probleme beheben

In diesem Abschnitt werden Problemumgehungen für bekannte Probleme im Autofill-Framework beschrieben.

Autofill führt bei Android 8.0 und 8.1 zum Absturz von Apps

Unter Android 8.0 (API-Ebene 26) und 8.1 (API-Ebene 27) kann die Funktion „Autofill“ in bestimmten Fällen dazu führen, dass Ihre App abstürzt. Tagging-Probleme lassen sich vermeiden, indem Sie alle Ansichten, die nicht automatisch ausgefüllt werden, mit importantForAutofill=no taggen. Du kannst auch die gesamte Aktivität mit importantForAutofill=noExcludeDescendants taggen.

Dialogfelder mit geänderter Größe werden für das automatische Ausfüllen nicht berücksichtigt

Unter Android 8.1 (API-Ebene 27) und niedriger wird eine Ansicht in einem Dialogfeld nicht für das automatische Ausfüllen berücksichtigt, wenn sie nach der Anzeige neu skaliert wird. Diese Ansichten sind nicht im AssistStructure-Objekt enthalten, das das Android-System an den Autofill-Dienst sendet. Daher kann der Dienst die Aufrufe nicht ausfüllen.

Sie können dieses Problem umgehen, indem Sie das Attribut token der Parameter des Dialogfelds durch das Attribut token der Aktivität ersetzen, mit der das Dialogfeld erstellt wird. Nachdem Sie geprüft haben, ob die Autofill-Funktion aktiviert ist, speichern Sie die Fensterparameter in der Methode onWindowAttributesChanged() der Klasse, die von Dialog abgeleitet ist. Ersetzen Sie dann in der Methode onAttachedToWindow() die Property token der gespeicherten Parameter durch die Property token der übergeordneten Aktivität.

Das folgende Code-Snippet zeigt eine Klasse, mit der diese Problemumgehung implementiert wird:

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

}

Um unnötige Vorgänge zu vermeiden, zeigt das folgende Code-Snippet, wie Sie prüfen können, ob Autofill auf dem Gerät unterstützt und für den aktuellen Nutzer aktiviert ist und ob diese Umgehung erforderlich ist:

Kotlin

// AutofillExtensions.kt

fun Context.isDialogResizedWorkaroundRequired(): Boolean {
    // After the issue is resolved on Android, check whether 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 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, check whether 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 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();
    }
}

App mit Autofill testen

Nachdem Sie Ihre App für die Verwendung mit AutoFill-Diensten optimiert haben, testen Sie, ob sie wie beabsichtigt funktioniert.

Verwenden Sie einen Emulator oder ein physisches Gerät mit Android 8.0 (API-Level 26) oder höher, um Ihre App zu testen. Weitere Informationen zum Erstellen eines Emulators finden Sie unter Virtuelle Geräte erstellen und verwalten.

Autofill-Dienst installieren

Bevor Sie Ihre App mit Autofill testen können, müssen Sie eine andere App installieren, die Autofill-Dienste bereitstellt. Sie können dazu eine Drittanbieter-App verwenden. Es ist jedoch einfacher, einen Beispiel-Autofill-Dienst zu verwenden, damit Sie sich nicht für Drittanbieterdienste registrieren müssen.

Sie können das Beispiel für das Android-Autofill-Framework in Java verwenden, um Ihre App mit Autofill-Diensten zu testen. Die Beispielanwendung bietet einen Autofill-Dienst und Client-Activity-Klassen, mit denen Sie den Workflow testen können, bevor Sie ihn in Ihrer App verwenden. Auf dieser Seite wird auf die Beispielanwendung android-AutofillFramework verwiesen.

Aktivieren Sie nach der Installation der App den AutoFill-Dienst in den Systemeinstellungen des Emulators. Gehen Sie dazu zu Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > AutoFill-Dienst.

Datenanforderungen analysieren

Wenn Sie Ihre App mit dem Autofill-Dienst testen möchten, muss der Dienst Daten haben, mit denen er Ihre App ausfüllen kann. Außerdem muss der Dienst wissen, welche Art von Daten in den Ansichten Ihrer App erwartet wird. Wenn Ihre App beispielsweise eine Ansicht hat, für die ein Nutzername erwartet wird, muss der Dienst einen Datensatz mit einem Nutzernamen und einen Mechanismus haben, um zu erkennen, dass für die Ansicht solche Daten erwartet werden.

Geben Sie dem Dienst an, welche Art von Daten in Ihren Ansichten erwartet wird, indem Sie das Attribut android:autofillHints festlegen. Einige Dienste verwenden ausgefeilte Heuristiken, um den Datentyp zu bestimmen. Andere, wie die Beispiel-App, verlassen sich darauf, dass der Entwickler diese Informationen angibt. Ihre App funktioniert besser mit AutoFill-Diensten, wenn Sie das Attribut android:autofillHints in den Ansichten festlegen, die für das automatische Ausfüllen relevant sind.

Test ausführen

Nachdem Sie die Datenanforderungen analysiert haben, können Sie den Test ausführen. Dazu müssen Sie Testdaten im Autofill-Dienst speichern und die Autofill-Funktion in Ihrer App auslösen.

Daten im Dienst speichern

So speichern Sie Daten in dem derzeit aktiven Autofill-Service:

  1. Öffnen Sie eine App mit einer Ansicht, für die die Daten erforderlich sind, die Sie während des Tests verwenden möchten. Die Beispiel-App android-AutofillFramework bietet der Benutzeroberfläche Ansichten, für die verschiedene Datentypen erwartet werden, z. B. Kreditkartennummern und Nutzernamen.
  2. Tippen Sie auf die Ansicht, die den von Ihnen benötigten Datentyp enthält.
  3. Geben Sie einen Wert in die Ansicht ein.
  4. Tippen Sie auf die Bestätigungsschaltfläche, z. B. Anmelden oder Senden. In der Regel müssen Sie das Formular absenden, bevor der Dienst die Daten speichert.
  5. Bestätigen Sie die Berechtigungsanfrage im Systemdialogfeld. Im Systemdialog wird der Name des derzeit aktiven Dienstes angezeigt und Sie werden gefragt, ob dies der Dienst ist, den Sie in Ihrem Test verwenden möchten. Wenn Sie den Dienst verwenden möchten, tippen Sie auf Speichern.

Wenn Android das Berechtigungsdialogfeld nicht anzeigt oder der Dienst nicht der ist, den Sie in Ihrem Test verwenden möchten, prüfen Sie, ob der Dienst derzeit in den Systemeinstellungen aktiv ist.

AutoFill in Ihrer App auslösen

So aktivieren Sie die Funktion „Autofill“ in Ihrer App:

  1. Öffnen Sie die App und rufen Sie die Aktivität auf, für die Sie die Aufrufe testen möchten.
  2. Tippen Sie auf die Ansicht, die ausgefüllt werden muss.
  3. Das System zeigt die Benutzeroberfläche für die automatische Ausfüllung an, die die Datasets enthält, mit denen die Ansicht ausgefüllt werden kann (siehe Abbildung 1).
  4. Tippen Sie auf den Datensatz mit den Daten, die Sie verwenden möchten. Die Ansicht enthält die Daten, die zuvor im Dienst gespeichert wurden.
Autofill-Benutzeroberfläche, in der „dataset-2“ als verfügbarer Datensatz angezeigt wird
Abbildung 1. AutoFill-Benutzeroberfläche mit verfügbaren Datensätzen

Wenn die Autofill-Benutzeroberfläche unter Android nicht angezeigt wird, können Sie die folgenden Schritte zur Fehlerbehebung ausprobieren:

  • Prüfe, ob die Ansichten in deiner App den richtigen Wert im Attribut android:autofillHints verwenden. Eine Liste der möglichen Werte für das Attribut finden Sie in der Klasse View in den Konstanten mit dem Präfix AUTOFILL_HINT.
  • Prüfen Sie, ob das android:importantForAutofill-Attribut in der Ansicht, die ausgefüllt werden muss, auf einen anderen Wert als no oder in der Ansicht oder einem übergeordneten Element auf einen anderen Wert als noExcludeDescendants festgelegt ist.