App für AutoFill optimieren

Anwendungen, die Standardansichten verwenden, funktionieren ohne spezielle Konfiguration mit dem Autofill-Framework. Außerdem können Sie die Funktionsweise Ihrer Anwendung mit dem Framework optimieren.

Autofill-Umgebung einrichten

In diesem Abschnitt wird beschrieben, wie Sie grundlegende Funktionen zum automatischen Ausfüllen für Ihre App einrichten.

Autofill-Service konfigurieren

Auf Ihrem Gerät muss ein Autofill-Dienst konfiguriert sein, damit Ihre App das Autofill-Framework verwenden kann. Obwohl die meisten Smartphones und Tablets mit Android 8.0 (API-Level 26) und höher mit einem Autofill-Service ausgestattet sind, empfehlen wir Ihnen, beim Testen Ihrer App einen Testdienst zu verwenden, z. B. den Autofill-Dienst im Android Autofill-Framework-Beispiel. Wenn Sie einen Emulator verwenden, legen Sie explizit einen Autofill-Dienst fest, da er möglicherweise keinen Standarddienst enthält.

Nachdem Sie den Autofill-Testdienst über die 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 von Autofill finden Sie unter App mit Autofill testen.

Hinweise für Autofill angeben

Der Autofill-Service bestimmt die Art der einzelnen Ansichten mithilfe von Heuristiken. Wenn Ihre App jedoch auf diese Heuristiken angewiesen ist, kann sich das Verhalten der Autofill-Funktion beim Aktualisieren der App unerwartet ändern. Geben Sie AutoFill-Hinweise an, damit der Autofill-Dienst die Formfaktoren Ihrer App korrekt erkennt.

Sie können Autofill-Hinweise mit dem Attribut android:autofillHints 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" />

Mit der Methode setAutofillHints() kannst du Hinweise auch programmatisch 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 Hinweiskonstanten einschließen

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

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

Kontoanmeldedaten

In einem Anmeldeformular können Sie Hinweise für Kontoanmeldedaten wie AUTOFILL_HINT_USERNAME und AUTOFILL_HINT_PASSWORD angeben.

Wenn Sie ein neues Konto erstellen 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 Kreditkartendaten 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 ein Ablaufdatum für Ihre Kreditkarte zu erhalten:

Postanschrift

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

Personennamen

Wenn Sie nach Namen von Personen fragen, können Sie zum Beispiel folgende Hinweise 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.

Für mehrere Ansichten, bei denen jede Ansicht einer einzelnen Ziffer des OTP zugeordnet ist, können Sie die Methode generateSmsOtpHintForCharacterPosition() verwenden, um Hinweise pro Zeichen zu generieren.

Felder für Autofill als wichtig markieren

Für Autofill-Zwecke können Sie die einzelnen Felder in Ihrer App in eine Ansichtsstruktur aufnehmen. Standardmäßig wird für Ansichten der IMPORTANT_FOR_AUTOFILL_AUTO-Modus verwendet, in dem Android anhand seiner Heuristik bestimmen kann, ob eine Ansicht für Autofill wichtig ist.

Es gibt jedoch Fälle, in denen eine Ansicht, eine Ansichtsstruktur oder die gesamte Aktivität für die Autofill-Funktion nicht wichtig ist:

  • Ein CAPTCHA-Feld in einer Anmeldeaktivität
  • Eine Ansicht, in der der Nutzer Inhalte erstellt, z. B. einen Text- oder Tabelleneditor
  • Aufrufe bei bestimmten Aktivitäten innerhalb von Spielen, z. B. Aktivitäten zum Spielen des Spiels

Sie können die Wichtigkeit einer Ansicht für Autofill mit dem Attribut android:importantForAutofill festlegen:

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

Für importantForAutofill sind folgende Werte möglich:

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

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

So können Sie die vorherigen Beispielanwendungsfälle für die Autofill-Funktion als unwichtig erklären:

  • Ein CAPTCHA-Feld 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 der Nutzer Inhalte erstellt:Verwenden Sie android:importantForAutofill="noExcludeDescendants" oder IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, um die gesamte Ansichtsstruktur als unwichtig zu markieren.
  • Die Aufrufe 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 markieren.

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. Wählt ein Nutzer auf beiden Plattformen denselben Autofill-Service aus, stehen nach der Anmeldung in Ihrer Web-App seine Anmeldedaten für das automatische Ausfüllen zur Verfügung, sobald er sich in der entsprechenden Android-App anmeldet.

Um deine Android-App mit deiner Website zu verknüpfen, musst du auf deiner Website einen Digital Asset Link mit der delegate_permission/common.get_login_creds-Beziehung hosten. Deklarieren Sie dann die Verknüpfung in der Datei AndroidManifest.xml Ihrer App. Eine ausführliche Anleitung zum Verknüpfen Ihrer Website mit Ihrer Android-App finden Sie unter Automatische Anmeldung in Apps und Websites aktivieren.

Einen Autofill-Workflow ausführen

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

Festlegen, ob Autofill aktiviert ist

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

Mit TextView wird beispielsweise ein Autofill-Eintrag im Dreipunkt-Menü angezeigt, wenn Autofill für den Nutzer aktiviert ist. Wenn Sie prüfen möchten, ob Autofill für den Nutzer aktiviert ist, rufen Sie die Methode isEnabled() des AutofillManager-Objekts auf.

Damit Ihre Registrierung und Anmeldung für Nutzer ohne Autofill optimiert werden, implementieren Sie die Anmeldung mit One Tap.

Autofill-Anfrage erzwingen

Manchmal müssen Sie das Ausführen einer Autofill-Anfrage als Reaktion auf eine Nutzeraktion erzwingen. TextView bietet beispielsweise einen Autofill-Menüpunkt, wenn der Nutzer die Ansicht berührt und gedrückt hält. Das folgende Codebeispiel zeigt, wie eine Autofill-Anfrage erzwungen wird:

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 den aktuellen Autofill-Kontext auch mit der Methode cancel() abbrechen. 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 den Auswahlsteuerelementen verwenden

Picker können bei der Funktion „Autofill“ nützlich sein, indem sie eine Benutzeroberfläche bereitstellen, mit der Nutzer den Wert eines Felds ändern können, in dem Datums- oder Uhrzeitdaten gespeichert werden. In einem Kreditkartenformular können Nutzer beispielsweise mit einer Datumsauswahl das Ablaufdatum ihrer Kreditkarte eingeben oder ändern. Sie müssen jedoch eine andere Ansicht verwenden, z. B. EditText, um die Daten darzustellen, wenn die Auswahl nicht sichtbar ist.

Ein EditText-Objekt erwartet nativ Autofill-Daten vom Typ AUTOFILL_TYPE_TEXT. Wenn Sie einen anderen Datentyp verwenden, erstellen Sie eine benutzerdefinierte Ansicht, die von EditText übernommen wird und die erforderlichen Methoden zur Verarbeitung des entsprechenden Datentyps 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 Autofill-Datentyp angeben, kann der Autofill-Dienst die in der Ansicht angezeigten Daten entsprechend darstellen. Weitere Informationen finden Sie unter Auswahl mit Autofill verwenden.

Autofill-Kontext fertigstellen

Das Autofill-Framework speichert Nutzereingaben zur späteren Verwendung, indem es nach Abschluss des Autofill-Kontexts das Dialogfeld „Für Autofill speichern?“ anzeigt. In der Regel ist der Autofill-Kontext beendet, wenn eine Aktivität abgeschlossen ist. Es gibt jedoch Situationen, in denen Sie das Framework explizit benachrichtigen müssen, z. B. wenn Sie dieselbe Aktivität, aber unterschiedliche Fragmente sowohl für Ihren Anmelde- als auch für den Inhaltsbildschirm verwenden. In diesen Situationen können Sie den Kontext explizit durch Aufrufen von AutofillManager.commit() beenden.

Unterstützung für benutzerdefinierte Ansichten

In benutzerdefinierten Ansichten können die Metadaten, die dem Autofill-Framework zugänglich gemacht werden, mithilfe der Autofill API angegeben werden. Einige Ansichten dienen als Container für virtuelle untergeordnete Elemente, z. B. Ansichten, die eine mit OpenGL gerenderte UI enthalten. Für diese Ansichten muss die API verwendet werden, um die Struktur der in der App verwendeten Informationen anzugeben, bevor sie mit dem Autofill-Framework verwendet werden können.

Wenn Ihre App benutzerdefinierte Ansichten verwendet, sind folgende Szenarien möglich:

  • Die benutzerdefinierte Ansicht stellt eine Standardansichtsstruktur oder eine Standardansichtsstruktur bereit.
  • Die benutzerdefinierte Ansicht hat eine virtuelle Struktur oder eine Ansichtsstruktur, die dem Autofill-Framework nicht zur Verfügung steht.

Benutzerdefinierte Ansichten mit Standardansichtsstruktur

In benutzerdefinierten Ansichten können die Metadaten definiert werden, die die Autofill-Funktion benötigt. Achten Sie darauf, dass die Metadaten in der benutzerdefinierten Ansicht entsprechend verwaltet werden, damit sie mit dem Autofill-Framework funktionieren. In der benutzerdefinierten Ansicht müssen folgende Aktionen ausgeführt werden:

  • den Autofill-Wert verarbeiten, den das Framework an Ihre App sendet.
  • Geben Sie den Autofill-Typ und den Wert für das Framework an.

Wenn Autofill ausgelöst wird, ruft das Autofill-Framework für Ihre Ansicht autofill() auf und sendet den Wert, den die Ansicht verwenden muss. Implementieren Sie autofill(), um festzulegen, wie der Autofill-Wert in der benutzerdefinierten Ansicht gehandhabt wird.

In der Ansicht müssen ein Autofill-Typ und -Wert angegeben werden. Dazu müssen die Methoden getAutofillType() bzw. getAutofillValue() überschrieben werden.

Schließlich darf die Autofill-Funktion die Ansicht nicht ausfüllen, wenn der Nutzer keinen Wert für die Ansicht in ihrem aktuellen Zustand 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() darf 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 sensible Daten.

Die benutzerdefinierte Ansicht kann bearbeitet werden

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

Die benutzerdefinierte Ansicht enthält sensible Daten

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

Im Allgemeinen enthalten Ansichten, deren Inhalt aus statischen Ressourcen stammt, keine sensiblen Daten, während Ansichten, deren Inhalt dynamisch festgelegt wird, sensible Daten enthalten können. So enthält beispielsweise ein Label mit dem Text Geben Sie Ihren Nutzernamen ein keine sensiblen Daten, ein Label mit dem Text Hallo John dagegen schon.

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

Um anzugeben, ob eine Ansicht sensible Daten enthält, implementieren Sie onProvideAutofillStructure() und rufen setDataIsSensitive() für das Objekt ViewStructure auf.

Das folgende Codebeispiel zeigt, wie die Daten in der Ansichtsstruktur als nicht vertraulich markiert 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 akzeptiert werden, können Sie mit der Methode setAutofillOptions() die Optionen zum automatischen Ausfüllen der Ansicht festlegen. Diese Methode muss insbesondere für Ansichten mit dem Autofill-Typ AUTOFILL_TYPE_LIST verwendet werden, da der Autofill-Dienst bessere Arbeit leisten kann, wenn er die Optionen kennt, die zum Ausfüllen der Ansicht verfügbar sind.

Ähnliches gilt für Ansichten, in denen ein Adapter wie Spinner verwendet wird. Beispielsweise kann ein rotierendes Ladesymbol, das dynamisch erstellte Jahre auf Basis des aktuellen Jahres in den Feldern für das Ablaufdatum von Kreditkarten verwendet, die getAutofillOptions()-Methode der Adapter-Schnittstelle implementieren, um eine Liste der Jahre zu erhalten.

Ansichten, in denen ein ArrayAdapter verwendet wird, können auch Wertelisten bereitstellen. ArrayAdapter legt automatisch Optionen zum automatischen Ausfüllen für statische Ressourcen fest. Wenn Sie die Werte dynamisch angeben, überschreiben Sie getAutofillOptions().

Benutzerdefinierte Ansichten mit virtueller Struktur

Das Autofill-Framework benötigt eine Ansichtsstruktur, bevor die Informationen in der Benutzeroberfläche Ihrer App bearbeitet und gespeichert werden können. Die Ansichtsstruktur ist in den folgenden Situationen für das Framework nicht verfügbar:

  • Zum Rendern der UI verwendet die App eine Low-Level-Rendering-Engine wie OpenGL.
  • Die App verwendet eine Instanz von Canvas, um die UI zu zeichnen.

In diesen Fällen können Sie eine Ansichtsstruktur angeben. Implementieren Sie dazu onProvideAutofillVirtualStructure() und führen Sie die folgenden Schritte aus:

  1. Erhöhen Sie die Anzahl der untergeordneten Elemente der Ansichtsstruktur, indem Sie addChildCount() aufrufen.
  2. Fügen Sie ein Kind 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 Eigenschaften wie den Autofill-Wert und -Typ fest.
  5. Wenn die Daten im virtuellen Kind vertraulich sind, übergeben Sie true an setDataIsSensitive(). Andernfalls übergeben Sie false.

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

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, rufen Sie notifyViewEntered() und notifyViewExited() für das AutofillManager-Objekt auf.
  • Wenn sich der Wert eines untergeordneten Elements ändert, rufen Sie notifyValueChanged() für das AutofillManager-Objekt auf.
  • Wenn die Ansichtshierarchie nicht mehr verfügbar ist, weil der Nutzer einen Schritt im Workflow ausgeführt hat, z. B. bei der Anmeldung über ein Anmeldeformular, rufen Sie commit() für das AutofillManager-Objekt auf.
  • Wenn die Ansichtshierarchie ungü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, rufen Sie cancel() für das AutofillManager-Objekt auf.

Callbacks für Autofill-Ereignisse verwenden

Wenn Ihre Anwendung eigene Ansichten für die automatische Vervollständigung bereitstellt, benötigen Sie einen Mechanismus, der die Anwendung anweist, die Ansichten als Reaktion auf Änderungen der automatischen Vervollständigung in der UI zu aktivieren oder zu deaktivieren. Das Autofill-Framework stellt diesen Mechanismus in Form von AutofillCallback bereit.

Diese Klasse stellt die Methode onAutofillEvent(View, int) bereit, die von der App nach einer Änderung des Autofill-Status einer Ansicht aufgerufen wird. Es gibt auch eine überlastete Version dieser Methode, die den Parameter childId enthält, den Ihre App mit virtuellen Ansichten verwenden kann. Die verfügbaren Status werden als Konstanten im Callback definiert.

Sie können einen Callback mit der Methode registerCallback() der Klasse AutofillManager registrieren. Das folgende Codebeispiel zeigt, 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 der Callback entfernt werden muss, verwenden Sie die Methode unregisterCallback().

Automatisch ausgefülltes Drawable anpassen

Wenn eine Ansicht automatisch ausgefüllt wird, rendert die Plattform ein Drawable über der Ansicht, um anzuzeigen, dass der Inhalt der Ansicht automatisch ausgefüllt wird. Standardmäßig ist dieses Drawable ein durchgehendes Rechteck mit einer durchscheinenden Farbe, die etwas dunkler ist als die Farbe des Designs, mit der Hintergründe gezeichnet wurden. Das Drawable muss nicht geändert werden, kann aber angepasst werden. Dazu überschreibst du das android:autofilledHighlight-Element des von der Anwendung oder Aktivität verwendeten Designs, 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 verlangen, dass sich der Nutzer authentifizieren muss, 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 Aktivitätsstacks.

Sie müssen Ihre Anwendung nicht aktualisieren, um die Authentifizierung zu unterstützen, da die Authentifizierung innerhalb des Dienstes erfolgt. Sie müssen jedoch darauf achten, dass die Ansichtsstruktur der Aktivität beibehalten wird, wenn die Aktivität neu gestartet wird. Dazu erstellen Sie beispielsweise die Ansichtsstruktur in onCreate() und nicht in onStart() oder onResume().

Mit dem HeuristicsService aus dem AutofillFramework-Beispiel können Sie prüfen, wie sich Ihre Anwendung verhält, wenn ein Autofill-Dienst eine Authentifizierung erfordert, indem Sie ihn so konfigurieren, dass eine Authentifizierung für die Füllantwort erforderlich ist. Sie können auch das Beispiel „BadViewStructureCreationSignInActivity“ verwenden, um dieses Problem zu emulieren.

Autofill-IDs zu wiederverwendeten Ansichten zuweisen

Container, in denen Ansichten wiederverwendet werden, z. B. die Klasse RecyclerView, sind nützlich für Anwendungen, die Scrolllisten von Elementen auf der Grundlage großer Datensätze anzeigen müssen. Wenn der Container scrollt, verwendet das System Ansichten im Layout wieder, enthalten dann aber neue Inhalte.

Wenn der ursprüngliche Inhalt einer recycelten Ansicht ausgefüllt wird, behält der Autofill-Dienst die logische Bedeutung der Ansichten anhand ihrer Autofill-IDs bei. Wenn das System die Ansichten im Layout wiederverwendet, aber die logischen IDs der Ansichten gleich bleiben, tritt ein Problem auf. Dadurch werden falsche Autofill-Nutzerdaten mit einer Autofill-ID verknüpft.

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

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

Bekannte Probleme beheben

In diesem Abschnitt werden Lösungen für bekannte Probleme im Autofill-Framework beschrieben.

Autofill führt unter Android 8.0, 8.1 zum Absturz von Apps

Unter Android 8.0 (API-Level 26) und 8.1 (API-Level 27) kann die Autofill-Funktion in bestimmten Fällen zum Absturz Ihrer App führen. Um potenzielle Probleme zu umgehen, taggen Sie alle nicht automatisch ausgefüllten Datenansichten mit importantForAutofill=no. Sie können auch die gesamte Aktivität mit importantForAutofill=noExcludeDescendants taggen.

Dialogfelder mit geänderter Größe werden beim Autofill nicht berücksichtigt

Wenn unter Android 8.1 (API-Level 27) und niedriger die Größe einer Ansicht in einem Dialog geändert wird, nachdem sie bereits angezeigt wurde, wird die Ansicht nicht für Autofill berücksichtigt. Diese Ansichten sind nicht im Objekt AssistStructure enthalten, das vom Android-System an den Autofill-Service gesendet wird. Daher kann der Dienst die Ansichten nicht ausfüllen.

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

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

}

Das folgende Code-Snippet zeigt, wie du prüfen kannst, ob Autofill auf dem Gerät unterstützt und für den aktuellen Nutzer aktiviert ist und ob diese Problemumgehung erforderlich ist, um unnötige Vorgänge zu vermeiden:

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 du deine App für die Arbeit mit Autofill-Diensten optimiert hast, solltest du testen, ob sie mit Autofill-Diensten wie vorgesehen funktioniert.

Testen Sie Ihre App mit einem Emulator oder einem physischen Gerät mit Android 8.0 (API-Level 26) oder höher. Weitere Informationen zum Erstellen eines Emulators finden Sie unter Virtuelle Geräte erstellen und verwalten.

Autofill-Service installieren

Bevor Sie Ihre App mit Autofill testen können, müssen Sie eine andere App installieren, die Autofill-Dienste bietet. Sie können für diesen Zweck eine Drittanbieter-App verwenden, aber es ist einfacher, einen Beispiel-Autofill-Service 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 Beispiel-App bietet einen Autofill-Dienst und Client-Activity-Klassen, mit denen Sie den Workflow testen können, bevor Sie ihn mit Ihrer App verwenden. Diese Seite verweist auf die Beispiel-App android-AutofillFramework.

Nachdem Sie die App installiert haben, aktivieren Sie den Autofill-Dienst in den Systemeinstellungen des Emulators. Rufen Sie dazu Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > Autofill-Service auf.

Datenanforderungen analysieren

Zum Testen Ihrer App mit dem Autofill-Dienst benötigt der Dienst Daten, mit denen er Ihre Anwendung ausfüllen kann. Außerdem muss der Dienst wissen, welche Art von Daten in den Ansichten Ihrer App erwartet werden. Wenn Ihre App beispielsweise eine Ansicht hat, die einen Nutzernamen erwartet, muss der Dienst ein Dataset mit einem Nutzernamen und einem Mechanismus haben, der weiß, dass die Ansicht solche Daten erwartet.

Mit dem Attribut android:autofillHints teilen Sie dem Dienst mit, welche Art von Daten in Ihren Ansichten erwartet werden. Einige Dienste verwenden ausgefeilte Heuristiken, um den Datentyp zu bestimmen, während andere, wie die Beispielanwendung, auf den Entwickler angewiesen sind, um diese Informationen bereitzustellen. Deine App funktioniert besser mit Autofill-Diensten, wenn du das android:autofillHints-Attribut in den Ansichten festlegst, die für Autofill relevant sind.

Test durchführen

Nachdem Sie die Datenanforderungen analysiert haben, können Sie den Test ausführen. Dazu gehören das Speichern von Testdaten im Autofill-Dienst und das Auslösen von Autofill in Ihrer App.

Daten im Dienst speichern

So speichern Sie Daten im aktiven Autofill-Service:

  1. Öffnen Sie eine App mit einer Ansicht, die den Datentyp erwartet, den Sie während des Tests verwenden möchten. Die Beispiel-App android-AutofillFramework stellt in der Benutzeroberfläche Ansichten bereit, die verschiedene Datentypen wie Kreditkartennummern und Nutzernamen erwarten.
  2. Tippen Sie auf die Ansicht, die den Datentyp enthält, den Sie benötigen.
  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 einreichen, bevor der Dienst die Daten speichert.
  5. Prüfen Sie die Berechtigungsanfrage im Systemdialogfeld. Im Systemdialogfeld wird der Name des aktuell aktiven Dienstes angezeigt. Außerdem werden Sie gefragt, ob dies der Dienst ist, den Sie in Ihrem Test verwenden möchten. Wenn Sie diesen Dienst verwenden möchten, tippen Sie auf Speichern.

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

Autofill in Ihrer App auslösen

So aktivieren Sie die Funktion zum automatischen Ausfüllen in Ihrer App:

  1. Öffnen Sie die App und rufen Sie die Aktivität mit den Aufrufen auf, die Sie testen möchten.
  2. Tippen Sie auf die Ansicht, die ausgefüllt werden soll.
  3. Das System zeigt die Autofill-UI an, die die Datasets enthält, die die Ansicht ausfüllen können (siehe Abbildung 1).
  4. Tippen Sie auf das Dataset, das die gewünschten Daten enthält. In der Ansicht werden die zuvor im Dienst gespeicherten Daten angezeigt.
Autofill-Benutzeroberfläche, auf der „dataset-2“ als verfügbares Dataset angezeigt wird
Abbildung 1. Autofill-Benutzeroberfläche, auf der verfügbare Datasets angezeigt werden.

Wenn die Autofill-UI in Android nicht angezeigt wird, können Sie die folgenden Optionen zur Fehlerbehebung ausprobieren:

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