Apps, die Standardansichten verwenden, funktionieren mit dem Autofill-Framework, ohne dass eine spezielle Konfiguration erforderlich ist. Sie können auch optimieren, wie Ihre App mit dem Framework funktioniert.
Umgebung für automatisches Ausfüllen einrichten
In diesem Abschnitt wird beschrieben, wie Sie die grundlegende Autofill-Funktion für Ihre App einrichten.
Autofill-Service konfigurieren
Damit deine App das Autofill-Framework verwenden kann, muss auf deinem Gerät ein Autofill-Service konfiguriert sein. Die meisten Smartphones und Tablets mit Android 8.0 (API-Level 26) und höher werden zwar mit einem Autofill-Service ausgeliefert, wir empfehlen jedoch, beim Testen Ihrer App einen Testdienst zu verwenden, z. B. den Autofill-Service im Beispiel für das Android Autofill-Framework. Wenn du einen Emulator verwendest, musst du einen Autofill-Service explizit festlegen, da der Emulator möglicherweise keinen Standarddienst hat.
Nachdem Sie den Autofill-Service zum Testen aus der Beispiel-App installiert haben, aktivieren Sie ihn. Gehen Sie dazu zu Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > Autofill-Service.
Weitere Informationen zum Konfigurieren eines Emulators zum Testen des automatischen Ausfüllens finden Sie unter App mit automatischem Ausfüllen testen.
Aktivitätskontext für Ansichten verwenden
Der Autofill-Service benötigt den Aktivitätskontext, um richtig zu funktionieren. Verwenden Sie beim Instanziieren einer Ansicht Activity als Kontext, damit sie richtig automatisch ausgefüllt werden kann.
Hinweise für Autofill bereitstellen
Der Autofill-Service bestimmt den Typ jeder Ansicht mithilfe von Heuristiken. Wenn deine App jedoch auf diese Heuristiken angewiesen ist, kann sich das Autofill-Verhalten beim Aktualisieren der App unerwartet ändern. Damit der Autofill-Service die Formfaktoren deiner App richtig erkennt, solltest du Autofill-Hinweise angeben.
Mit dem Attribut android:autofillHints können Sie Hinweise für das automatische Ausfüllen 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 Hinweis-Konstanten einschließen
Das Autofill-Framework validiert keine Hinweise. Sie werden ohne Änderung oder Validierung an den Autofill-Service weitergegeben. Sie können einen beliebigen Wert verwenden. Die Klassen View und AndroidX HintConstants enthalten jedoch Listen mit offiziell unterstützten Hinweis-Konstanten.
Mithilfe einer Kombination dieser Konstanten können Sie Layouts für gängige Autofill-Szenarien erstellen:
Kontoanmeldedaten
In einem Anmeldeformular können Sie Hinweise zu Kontoanmeldedaten wie AUTOFILL_HINT_USERNAME und AUTOFILL_HINT_PASSWORD angeben.
Wenn Sie ein neues Konto erstellen oder 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 für das Ablaufdatum der Kreditkarte einen der folgenden Schritte aus:
- 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 die jeweilige Ansicht
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY,AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTHundAUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEARverwenden.
Adresse
Für Formularfelder für die Postanschrift können Sie Hinweise wie die folgenden verwenden:
- Verwenden Sie für eine Adresse in einer einzelnen Ansicht
AUTOFILL_HINT_POSTAL_ADDRESS. - Wenn Sie separate Ansichten für verschiedene Teile einer Adresse verwenden, können Sie Folgendes nutzen:
Namen von Personen
Wenn Sie nach den Namen von Personen fragen, können Sie Hinweise wie die folgenden verwenden:
- Wenn Sie den vollständigen Namen einer Person in einer einzelnen Ansicht automatisch ausfüllen lassen 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 verwenden:
Telefonnummern
Für Telefonnummern können Sie Folgendes verwenden:
- Wenn Sie eine vollständige Telefonnummer in einer einzelnen Ansicht anfordern, verwenden Sie
AUTOFILL_HINT_PHONE_NUMBER. - Wenn Sie separate Ansichten für verschiedene Teile einer Telefonnummer verwenden, können Sie eine der folgenden Optionen verwenden:
Einmalpasswort (OTP)
Für ein Einmalpasswort in einer einzelnen Ansicht können Sie AUTOFILL_HINT_SMS_OTP verwenden.
Wenn Sie mehrere Ansichten haben, wobei jede Ansicht einer einzelnen Ziffer des OTP zugeordnet ist, können Sie die Methode generateSmsOtpHintForCharacterPosition() verwenden, um Hinweise für jedes Zeichen zu generieren.
Website- und App-Daten verknüpfen
Autofill-Services wie „Autofill mit Google“ können Nutzeranmeldedaten zwischen Browsern und Android-Geräten teilen, nachdem die App und eine Website verknüpft wurden. Wenn ein Nutzer auf beiden Plattformen denselben Autofill-Service auswählt, werden seine Anmeldedaten bei der Anmeldung in Ihrer Web-App für das automatische Ausfüllen verfügbar, wenn er sich in Ihrer entsprechenden Android-App anmeldet.
Wenn Sie Ihre Android-App mit Ihrer Website verknüpfen möchten, hosten Sie einen Digital Asset Link mit der Beziehung delegate_permission/common.get_login_creds auf Ihrer Website. Deklarieren Sie dann die Verknüpfung in der Datei AndroidManifest.xml Ihrer Anwendung. Eine ausführliche Anleitung zum Verknüpfen deiner Website mit deiner Android-App findest du 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 das automatische Ausfüllen aktivieren oder deaktivieren und den Autofill-Service ändern. Dazu rufen sie Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > Autofill-Service auf. Ihre App kann die Einstellungen für das automatische Ausfüllen des Nutzers nicht überschreiben. Sie können jedoch zusätzliche Funktionen für das automatische Ausfüllen in Ihrer App oder in bestimmten Ansichten Ihrer App implementieren, wenn das automatische Ausfüllen für den Nutzer verfügbar ist.
Beispiel: TextView zeigt einen Autofill-Eintrag im Dreipunkt-Menü an, 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 Objekts AutofillManager auf.
Damit die Registrierung und Anmeldung auch für Nutzer ohne Autofill optimiert ist, sollten Sie die Anmeldung über One Tap implementieren.
Anfrage zum automatischen Ausfüllen erzwingen
Manchmal ist es erforderlich, eine Anfrage zum automatischen Ausfüllen als Reaktion auf eine Nutzeraktion zu erzwingen. Beispielsweise bietet TextView einen Menüpunkt für das automatische Ausfüllen, wenn der Nutzer die Ansicht berührt und 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.
Korrekten Autofill-Typ für Daten in Auswahlsteuerelementen verwenden
Auswahltools können beim automatischen Ausfüllen nützlich sein, da sie eine Benutzeroberfläche bieten, über die Nutzer den Wert eines Felds ändern können, in dem Datums- oder Uhrzeitdaten gespeichert sind. In einem Kreditkartenformular können Nutzer beispielsweise über eine Datumsauswahl das Ablaufdatum ihrer Kreditkarte eingeben oder ändern. Sie müssen jedoch eine andere Ansicht verwenden, z. B. eine EditText, um die Daten anzuzeigen, 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 erbt und die Methoden implementiert, die für die Verarbeitung des entsprechenden Datentyps erforderlich sind. Wenn Sie beispielsweise ein Datumsfeld haben, implementieren Sie die Methoden mit einer Logik, die Werte vom Typ AUTOFILL_TYPE_DATE korrekt verarbeitet.
Wenn du den Datentyp für das automatische Ausfüllen angibst, kann der Autofill-Service eine geeignete Darstellung der in der Ansicht angezeigten Daten erstellen. Weitere Informationen finden Sie unter Auswahltools mit Autofill verwenden.
Autofill-Kontext fertigstellen
Das Autofill-Framework speichert Nutzereingaben für die spätere Verwendung. Dazu wird nach Abschluss des Autofill-Kontexts das Dialogfeld „Für Autofill speichern?“ angezeigt. In der Regel wird der Autofill-Kontext beendet, wenn eine Aktivität beendet wird. In einigen Situationen musst du das Framework jedoch explizit benachrichtigen, z. B. wenn du dieselbe Aktivität, aber unterschiedliche Fragmente für deine Anmelde- und Inhaltsbildschirme verwendest. 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, die für das Autofill-Framework verfügbar gemacht werden, mithilfe der Autofill API angegeben werden. Einige Ansichten fungieren als Container für virtuelle untergeordnete Elemente, z. B. Ansichten, die eine mit OpenGL gerenderte Benutzeroberfläche enthalten. Diese Ansichten müssen die API verwenden, 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, 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 das automatische Ausfüllen erforderlich sind. Achten Sie darauf, dass die Metadaten in Ihrer benutzerdefinierten Ansicht so verwaltet werden, dass sie mit dem Autofill-Framework funktionieren. Ihre benutzerdefinierte Ansicht muss die folgenden Aktionen ausführen:
- Verarbeiten Sie den Wert für die automatische Bestätigung, den das Framework an Ihre App sendet.
- Geben Sie den Autofill-Typ und den Wert an das Framework weiter.
Wenn das automatische Ausfüllen ausgelöst wird, ruft das Autofill-Framework autofill() für Ihre Ansicht auf und sendet den Wert, den Ihre Ansicht verwenden muss. Implementiere autofill(), um anzugeben, wie deine benutzerdefinierte Ansicht den Wert für die automatische Bestätigung verarbeitet.
In der Ansicht müssen ein Typ und ein Wert für das automatische Ausfüllen 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 im aktuellen Zustand der Ansicht keinen Wert für die Ansicht 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, benachrichtigen Sie das Autofill-Framework über Änderungen, indem Sie notifyValueChanged() für das AutofillManager-Objekt aufrufen.
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 Inhalt aus statischen Ressourcen stammt, keine sensiblen Daten, während Ansichten, deren Inhalt dynamisch festgelegt wird, sensible Daten enthalten können. Ein Label, das Geben Sie Ihren Nutzernamen ein enthält, enthält beispielsweise keine sensiblen Daten, ein Label, das Hallo, John enthält, dagegen schon.
Das Autofill-Framework geht standardmäßig davon aus, dass alle Daten vertraulich sind. Sie können Daten markieren, die nicht sensibel sind.
Wenn Sie kennzeichnen möchten, ob eine Ansicht vertrauliche Daten enthält, implementieren Sie onProvideAutofillStructure() und rufen Sie setDataIsSensitive() für das ViewStructure-Objekt auf.
Im folgenden Codebeispiel wird gezeigt, wie die Daten in der Ansichtsstruktur als nicht sensibel 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 eine Ansicht nur vordefinierte Werte akzeptiert, können Sie mit der Methode setAutofillOptions() die Optionen festlegen, die zum automatischen Ausfüllen der Ansicht verwendet werden können. Insbesondere Ansichten, deren Autofill-Typ AUTOFILL_TYPE_LIST ist, müssen diese Methode verwenden, da der Autofill-Service besser funktioniert, wenn er die Optionen kennt, die zum Ausfüllen der Ansicht verfügbar sind.
Ansichten, die einen Adapter wie Spinner verwenden, sind ein ähnlicher Fall. Beispiel: Ein Spinner, der dynamisch erstellte Jahre basierend auf dem aktuellen Jahr für die Verwendung in Feldern für das Ablaufdatum von Kreditkarten bereitstellt, kann die Methode getAutofillOptions() der Schnittstelle Adapter implementieren, um eine Liste von Jahren bereitzustellen.
Ansichten, die einen ArrayAdapter verwenden, können auch Listen mit Werten bereitstellen. ArrayAdapter legt automatisch Autofill-Optionen 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 es die Informationen in der Benutzeroberfläche Ihrer App bearbeiten und speichern kann. In den folgenden Situationen 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.
- Die Anwendung verwendet eine Instanz von
Canvas, 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:
- Erhöhen Sie die Anzahl der untergeordneten Elemente der Ansichtsstruktur, indem Sie
addChildCount()aufrufen. - Wenn du ein Kind hinzufügen möchtest, rufe
newChild()an. - Legen Sie die Autofill-ID für das untergeordnete Element fest, indem Sie
setAutofillId()aufrufen. - Legen Sie relevante Attribute fest, z. B. den Wert und den Typ für das automatische Ausfüllen.
- Wenn die Daten im virtuellen untergeordneten Element vertraulich sind, übergeben Sie
trueansetDataIsSensitive(). 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 abgeschlossen hat, z. B. wenn er sich über ein Anmeldeformular anmeldet, 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 er auf eine Schaltfläche tippt, die ein Anmeldeformular löscht, rufen Sie
cancel()für dasAutofillManager-Objekt auf.
Callbacks 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 UI-Affordanz für die automatische Vervollständigung 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 aufgerufen wird, nachdem sich der Autofill-Status einer Ansicht geändert hat.
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 sind im Callback als Konstanten definiert.
Sie können einen Callback 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 der Callback entfernt werden soll, verwenden Sie die Methode unregisterCallback().
Hervorgehobenes Drawable für Autofill anpassen
Wenn eine Ansicht automatisch ausgefüllt wird, rendert die Plattform ein Drawable über der Ansicht, um anzugeben, dass der Inhalt der Ansicht automatisch ausgefüllt wird. 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 Element android:autofilledHighlight des Designs, das von der Anwendung oder Aktivität verwendet wird, ü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">
Authentifizierung für Autofill
Ein Autofill-Service kann erfordern, dass sich der Nutzer authentifiziert, bevor der Dienst Felder in deiner App ausfüllen kann. In diesem Fall startet das Android-System die Authentifizierungsaktivität des Dienstes als Teil des Stacks deiner Aktivität.
Sie müssen Ihre Anwendung nicht aktualisieren, um die Authentifizierung zu unterstützen, da die Authentifizierung innerhalb des Dienstes erfolgt. Sie müssen jedoch dafür sorgen, dass die Ansichtsstruktur der Aktivität beim Neustart der Aktivität beibehalten wird, z. B. indem Sie die Ansichtsstruktur in onCreate() und nicht in onStart() oder onResume() erstellen.
Sie können das Verhalten Ihrer App überprüfen, wenn ein Autofill-Service eine Authentifizierung erfordert. Verwenden Sie dazu den HeuristicsService aus dem AutofillFramework-Beispiel und konfigurieren Sie ihn so, dass eine Authentifizierung für die Antwort zum Ausfüllen erforderlich ist. Sie können auch das Beispiel BadViewStructureCreationSignInActivity verwenden, um dieses Problem zu emulieren.
Recycelten Ansichten Autofill-IDs zuweisen
Container, die Ansichten wiederverwenden, z. B. die Klasse RecyclerView, sind nützlich für Apps, die scrollbare Listen mit Elementen basierend auf großen Datasets anzeigen müssen. Wenn der Container gescrollt wird, werden die Ansichten im Layout wiederverwendet, enthalten dann aber neue Inhalte.
Wenn der ursprüngliche Inhalt einer recycelten Ansicht ausgefüllt ist, behält der Autofill-Service die logische Bedeutung der Ansichten anhand ihrer Autofill-IDs bei. Ein Problem tritt auf, wenn das System die Ansichten im Layout wiederverwendet und die logischen IDs der Ansichten gleich bleiben. Dadurch werden die falschen Autofill-Nutzerdaten mit einer Autofill-ID verknüpft.
Um dieses Problem auf Geräten mit Android 9 (API-Level 28) und höher zu beheben, verwalte die Autofill-ID von Ansichten, die von RecyclerView verwendet werden, explizit mit den folgenden Methoden:
- Die Methode
getNextAutofillId()ruft eine neue Autofill-ID ab, 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.
Automatisches Ausfüllen führt bei Android 8.0 und 8.1 zu App-Abstürzen
In Android 8.0 (API-Level 26) und 8.1 (API-Level 27) kann Autofill in bestimmten Szenarien zum Absturz der App führen. Um potenzielle Probleme zu vermeiden, können Sie alle Ansichten, die nicht automatisch ausgefüllt werden, mit importantForAutofill=no taggen. Sie können auch die gesamte Aktivität mit importantForAutofill=noExcludeDescendants taggen.
In der Größe geänderte Dialogfelder werden beim Autofill nicht berücksichtigt
Wenn in Android 8.1 (API-Level 27) und niedriger die Größe einer Ansicht in einem Dialogfeld geändert wird, nachdem sie bereits angezeigt wurde, wird die Ansicht nicht für Autofill berücksichtigt. Diese Ansichten sind nicht im AssistStructure-Objekt enthalten, das das Android-System an den Autofill-Service sendet. Daher kann der Dienst die Ansichten nicht ausfüllen.
Ersetzen Sie das Attribut token der Parameter des Dialogfensters durch das Attribut token der Aktivität, die das Dialogfeld erstellt, um dieses Problem zu umgehen. Nachdem Sie geprüft haben, ob das automatische Ausfüllen aktiviert ist, speichern Sie die Fensterparameter in der Methode onWindowAttributesChanged() der Klasse, die von Dialog erbt. Ersetzen Sie dann in der Methode onAttachedToWindow() das Attribut token der gespeicherten Parameter durch das Attribut token der übergeordneten Aktivität.
Das folgende Code-Snippet zeigt eine Klasse, die diesen Workaround implementiert:
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 Sie prüfen können, ob Autofill auf dem Gerät unterstützt wird und für den aktuellen Nutzer aktiviert ist und ob dieser Workaround 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 Verwendung mit Autofill-Services optimiert hast, solltest du testen, ob sie wie vorgesehen mit Autofill-Services funktioniert.
Verwenden Sie zum Testen Ihrer App einen Emulator oder ein physisches 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 du deine App mit Autofill testen kannst, musst du eine andere App installieren, die Autofill-Services bietet. Sie können dafür eine Drittanbieter-App verwenden. Es ist jedoch 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-Service und Client-Activity-Klassen, mit denen Sie den Workflow testen können, bevor Sie ihn mit Ihrer App verwenden. Auf dieser Seite wird die Beispiel-App android-AutofillFramework verwendet.
Nachdem Sie die App installiert haben, aktivieren Sie den Autofill-Service in den Systemeinstellungen des Emulators. Gehen Sie dazu zu Einstellungen > System > Sprachen und Eingabe > Erweitert > Eingabehilfe > Autofill-Service.
Datenanforderungen analysieren
Wenn Sie Ihre App mit dem Autofill-Service testen möchten, muss der Dienst Daten haben, mit denen er Ihre App ausfüllen kann. Der Dienst muss auch wissen, welche Art von Daten in den Ansichten Ihrer App erwartet wird. Wenn Ihre App beispielsweise eine Ansicht hat, die einen Nutzernamen erwartet, muss der Dienst ein Dataset haben, das einen Nutzernamen enthält, und einen Mechanismus, um zu wissen, dass die Ansicht solche Daten erwartet.
Teilen Sie dem Dienst mit, welche Art von Daten in Ihren Ansichten erwartet wird, indem Sie das Attribut android:autofillHints festlegen. Einige Dienste verwenden komplexe Heuristiken, um den Datentyp zu bestimmen. Andere, wie die Beispiel-App, sind darauf angewiesen, dass der Entwickler diese Informationen bereitstellt. Ihre App funktioniert besser mit Autofill-Diensten, wenn Sie das Attribut android:autofillHints in den Ansichten festlegen, die für Autofill relevant sind.
Test ausführen
Nachdem Sie die Datenanforderungen analysiert haben, können Sie den Test ausführen. Dazu speichern Sie Testdaten im Autofill-Service und lösen das automatische Ausfüllen in Ihrer App aus.
Daten im Dienst speichern
So speichern Sie Daten im derzeit 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 der Benutzeroberfläche Ansichten zur Verfügung, die verschiedene Datentypen wie Kreditkartennummern und Nutzernamen erwarten.
- Tippe auf die Ansicht, die die gewünschten Daten enthält.
- 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 senden, bevor der Dienst die Daten speichert.
- Bestätigen Sie die Berechtigungsanfrage im Systemdialogfeld. Im Systemdialogfeld wird der Name des derzeit aktiven Dienstes angezeigt und Sie werden gefragt, ob Sie diesen Dienst in Ihrem Test verwenden möchten. Wenn Sie den Dienst verwenden möchten, tippen Sie auf Speichern.
Wenn Android das Dialogfeld für die Berechtigung nicht anzeigt oder der Dienst nicht der ist, den du in deinem Test verwenden möchtest, prüfe, ob der Dienst derzeit in den Systemeinstellungen aktiv ist.
Autofill-Funktion in Ihrer App auslösen
So lösen Sie das automatische Ausfüllen in Ihrer App aus:
- Öffnen Sie Ihre App und rufen Sie die Aktivität mit den Ansichten auf, die Sie testen möchten.
- Tippen Sie auf die Ansicht, die ausgefüllt werden muss.
- Das System zeigt die Autofill-Benutzeroberfläche an, die die Datasets enthält, mit denen die Ansicht ausgefüllt werden kann (siehe Abbildung 1).
- Tippen Sie auf das Dataset, das die Daten enthält, die Sie verwenden möchten. In der Ansicht werden die zuvor im Dienst gespeicherten Daten angezeigt.
Wenn Android die Benutzeroberfläche für das automatische Ausfüllen nicht anzeigt, können Sie die folgenden Optionen zur Fehlerbehebung ausprobieren:
- Prüfen Sie, ob die Ansichten in Ihrer App den richtigen Wert im Attribut
android:autofillHintsverwenden. Eine Liste der möglichen Werte für das Attribut finden Sie in den Konstanten mit dem PräfixAUTOFILL_HINTin der KlasseView. - Prüfen Sie, ob das Attribut
android:importantForAutofillin der Ansicht, die ausgefüllt werden muss, auf einen anderen Wert alsnooder in der Ansicht oder einem ihrer übergeordneten Elemente auf einen anderen Wert alsnoExcludeDescendantsfestgelegt ist.