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:
- Wenn Sie eine einzelne Ansicht für das Ablaufdatum verwenden, verwenden Sie
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE
. - Wenn Sie für jeden Teil des Ablaufdatums eine andere Ansicht verwenden, können Sie für jede einzelne Ansicht
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY
,AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH
undAUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR
verwenden.
Postanschrift
Für Formularfelder für Adressen können Sie Hinweise wie die folgenden verwenden:
- Für eine Adresse in einer einzelnen Ansicht verwenden Sie
AUTOFILL_HINT_POSTAL_ADDRESS
. - Wenn Sie separate Ansichten für verschiedene Teile einer Adresse verwenden, haben Sie folgende Möglichkeiten:
Personennamen
Wenn Sie nach Namen von Personen fragen, können Sie zum Beispiel folgende Hinweise verwenden:
- Wenn Sie den vollständigen Namen einer Person automatisch in einer Ansicht ausfüllen möchten, verwenden Sie
AUTOFILL_HINT_PERSON_NAME
. - Wenn Sie separate Ansichten für verschiedene Teile eines Namens verwenden, können Sie eine der folgenden Optionen nutzen:
Telefonnummern
Für Telefonnummern können Sie Folgendes verwenden:
- Wenn Sie eine vollständige Telefonnummer in einer einzelnen Ansicht anfordern möchten, verwenden Sie
AUTOFILL_HINT_PHONE_NUMBER
. - Wenn Sie separate Ansichten für verschiedene Teile einer Telefonnummer verwenden, haben Sie folgende Möglichkeiten:
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 Sieandroid:importantForAutofill="no"
oderIMPORTANT_FOR_AUTOFILL_NO
, um diese Ansicht als unwichtig zu markieren. - Eine Ansicht, in der der Nutzer Inhalte erstellt:Verwenden Sie
android:importantForAutofill="noExcludeDescendants"
oderIMPORTANT_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"
oderIMPORTANT_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:
- Erhöhen Sie die Anzahl der untergeordneten Elemente der Ansichtsstruktur, indem Sie
addChildCount()
aufrufen. - Fügen Sie ein Kind hinzu, indem Sie
newChild()
aufrufen. - Legen Sie die Autofill-ID für das untergeordnete Element fest, indem Sie
setAutofillId()
aufrufen. - Legen Sie relevante Eigenschaften wie den Autofill-Wert und -Typ fest.
- Wenn die Daten im virtuellen Kind vertraulich sind, übergeben Sie
true
ansetDataIsSensitive()
. Andernfalls übergeben Siefalse
.
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()
undnotifyViewExited()
für dasAutofillManager
-Objekt auf. - Wenn sich der Wert eines untergeordneten Elements ändert, rufen Sie
notifyValueChanged()
für dasAutofillManager
-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 dasAutofillManager
-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 dasAutofillManager
-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:
<resources>
<style name="MyAutofilledHighlight" parent="...">
<item name="android:autofilledHighlight">@drawable/my_drawable</item>
</style>
</resources>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4DFF0000" />
</shape>
<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:
- Ö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.
- Tippen Sie auf die Ansicht, die den Datentyp enthält, den Sie benötigen.
- Geben Sie einen Wert in die Ansicht ein.
- 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.
- 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:
- Öffnen Sie die App und rufen Sie die Aktivität mit den Aufrufen auf, die Sie testen möchten.
- Tippen Sie auf die Ansicht, die ausgefüllt werden soll.
- Das System zeigt die Autofill-UI an, die die Datasets enthält, die die Ansicht ausfüllen können (siehe Abbildung 1).
- Tippen Sie auf das Dataset, das die gewünschten Daten enthält. In der Ansicht werden die zuvor im Dienst gespeicherten Daten angezeigt.
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äfixAUTOFILL_HINT
in der KlasseView
. - Prüfen Sie, ob das
android:importantForAutofill
-Attribut in der Ansicht auf einen anderen Wert alsno
oder einen anderen Wert alsnoExcludeDescendants
für die Ansicht oder eines ihrer übergeordneten Elemente festgelegt ist.