Приложения, в которых используются стандартные представления, работают с фреймворком автозаполнения без специальной настройки. Вы также можете оптимизировать работу приложения с фреймворком.
Как настроить среду автозаполнения
В этом разделе описывается, как настроить базовую функцию автозаполнения для приложения.
Как настроить сервис автозаполнения
Чтобы приложение могло использовать фреймворк автозаполнения, на устройстве должен быть настроен сервис автозаполнения. Хотя большинство телефонов и планшетов с Android 8.0 (уровень API 26) и более поздними версиями поставляются с сервисом автозаполнения, мы рекомендуем использовать тестовый сервис, например сервис автозаполнения в примере фреймворка автозаполнения Android. При использовании эмулятора явно задайте сервис автозаполнения, поскольку в эмуляторе может не быть сервиса по умолчанию.
После установки тестового сервиса автозаполнения из примера приложения включите его, выбрав Настройки > Система > Язык и ввод > Дополнительно > Помощь при вводе > Сервис автозаполнения.
Подробнее о том, как настроить эмулятор для тестирования автозаполнения…
Как использовать контекст действия для представлений
Для правильной работы сервиса автозаполнения требуется контекст действия. При создании экземпляра представления используйте Activity в качестве контекста, чтобы обеспечить правильное автозаполнение.
Как предоставить подсказки для автозаполнения
Сервис автозаполнения определяет тип каждого представления с помощью эвристики. Однако если ваше приложение полагается на эти эвристики, поведение автозаполнения может неожиданно измениться при обновлении приложения. Чтобы сервис автозаполнения правильно определял форм-факторы вашего приложения, предоставьте подсказки автозаполнения.
Подсказки для автозаполнения можно задать с помощью атрибута android:autofillHints. В следующем примере показано, как задать подсказку "password" для EditText:
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:autofillHints="password" />
Подсказки также можно задать программно с помощью метода setAutofillHints(), как показано в следующем примере:
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);
Включить предопределенные константы подсказок
Фреймворк автозаполнения не проверяет подсказки, а передает их сервису автозаполнения без изменений. Вы можете использовать любое значение, но в классах View и HintConstants AndroidX содержатся списки официально поддерживаемых констант подсказок.
Используя комбинацию этих констант, вы можете создавать макеты для распространенных сценариев автозаполнения:
Учетные данные аккаунта
В форму входа можно добавить подсказки для учетных данных аккаунта, например AUTOFILL_HINT_USERNAME и AUTOFILL_HINT_PASSWORD.
Для создания нового аккаунта или изменения имени пользователя и пароля можно использовать AUTOFILL_HINT_NEW_USERNAME и AUTOFILL_HINT_NEW_PASSWORD.
Сведения о кредитной карте
При запросе данных кредитной карты можно использовать подсказки, например AUTOFILL_HINT_CREDIT_CARD_NUMBER и AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE.
Для срока действия кредитной карты выполните одно из следующих действий:
- Если вы используете одно представление для срока действия, используйте
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE. - Если вы используете разные представления для каждой части срока действия, то можете использовать
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY,AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTHиAUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEARдля каждого представления.
Физический адрес.
Для полей с физическим адресом можно использовать следующие подсказки:
- Для адреса в одном представлении используйте
AUTOFILL_HINT_POSTAL_ADDRESS. - Если вы используете отдельные представления для разных частей адреса, можно использовать следующие:
Имена людей
При запросе имен пользователей можно использовать следующие подсказки:
- Чтобы автоматически заполнить полное имя пользователя в одном представлении, используйте
AUTOFILL_HINT_PERSON_NAME. - Если вы используете отдельные представления для разных частей имени, вы можете использовать любое из следующих:
Номера телефонов
Для номеров телефонов можно использовать следующие форматы:
- Если вы запрашиваете полный номер телефона в одном представлении, используйте
AUTOFILL_HINT_PHONE_NUMBER. - Если вы используете отдельные представления для разных частей номера телефона, вы можете использовать любой из следующих вариантов:
Одноразовый код
Для одноразового кода в одном представлении можно использовать AUTOFILL_HINT_SMS_OTP.
Если у вас несколько представлений, каждое из которых соответствует одной цифре одноразового кода, вы можете использовать метод generateSmsOtpHintForCharacterPosition(), чтобы генерировать подсказки для каждого символа.
Как связать данные сайта и мобильного приложения
Сервисы автозаполнения, такие как Автозаполнение от Google, могут передавать данные для входа между браузерами и устройствами Android после того, как приложение и сайт будут связаны. Если пользователь выбирает один и тот же сервис автозаполнения на обеих платформах, то после входа в веб-приложение его учетные данные становятся доступны для автозаполнения при входе в соответствующее приложение Android.
Чтобы связать приложение для Android с сайтом, разместите на сайте файл протокола связи цифровых объектов с отношением delegate_permission/common.get_login_creds. Затем объявите связь в файле AndroidManifest.xml приложения. Подробные инструкции о том, как связать сайт с приложением для Android, приведены в статье Как включить автоматический вход в приложениях и на сайтах.
Как завершить процесс автозаполнения
В этом разделе описаны конкретные сценарии, в которых вы можете предпринять шаги по улучшению функциональности автозаполнения для пользователей вашего приложения.
Определять, включено ли автозаполнение
Пользователи могут включать и отключать автозаполнение, а также менять сервис автозаполнения. Для этого нужно перейти в Настройки > Система > Язык и ввод > Дополнительно > Помощь при вводе > Сервис автозаполнения. Приложение не может переопределить настройки автозаполнения, заданные пользователем, но вы можете реализовать дополнительные функции автозаполнения в приложении или в определенных его представлениях, если автозаполнение доступно пользователю.
Например, если у пользователя включено автозаполнение, в дополнительном меню TextView будет показан пункт автозаполнения. Чтобы проверить, включено ли автозаполнение для пользователя, вызовите метод isEnabled() объекта AutofillManager.
Чтобы оптимизировать регистрацию и вход для пользователей, у которых не включено автозаполнение, реализуйте вход через One Tap.
Принудительный запрос автозаполнения
Иногда вам нужно принудительно выполнить запрос на автозаполнение в ответ на действие пользователя. Например, в TextView пункт меню автозаполнения появляется, когда пользователь нажимает и удерживает область просмотра.
В примере кода ниже показано, как принудительно отправить запрос на автозаполнение.
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);
}
}
Вы также можете использовать метод cancel(), чтобы отменить текущий контекст автозаполнения. Это может быть полезно, если у вас есть кнопка, которая очищает поля на странице входа.
Используйте правильный тип автозаполнения для данных в элементах управления выбором
Виджеты выбора могут быть полезны при автозаполнении, предоставляя пользовательский интерфейс, который позволяет пользователям изменять значение поля, в котором хранятся данные о дате или времени. Например, в форме для ввода данных кредитной карты окно выбора даты позволяет пользователям ввести или изменить срок действия карты. Однако для отображения данных, когда инструмент выбора не виден, необходимо использовать другое представление, например EditText.
Объект EditText по умолчанию ожидает данные автозаполнения типа AUTOFILL_TYPE_TEXT.
Если вы используете другой тип данных, создайте специальное представление, которое наследует от EditText и реализует методы, необходимые для обработки соответствующего типа данных. Например, если у вас есть поле даты, реализуйте методы с логикой, которая правильно обрабатывает значения типа AUTOFILL_TYPE_DATE.
Когда вы указываете тип данных автозаполнения, сервис автозаполнения может создать подходящее представление данных, отображаемых в представлении. Подробнее о том, как использовать виджеты выбора с автозаполнением…
Завершить контекст автозаполнения
Фреймворк автозаполнения сохраняет введенные пользователем данные для дальнейшего использования, показывая диалоговое окно "Сохранить для автозаполнения?" после завершения контекста автозаполнения. Обычно контекст автозаполнения завершается вместе с действием. Однако в некоторых ситуациях вам нужно явно уведомить фреймворк, например если вы используете одно и то же действие, но разные фрагменты для экранов входа и контента. В таких ситуациях вы можете явно завершить контекст, вызвав AutofillManager.commit().
Поддержка пользовательских представлений
Специальные представления могут указывать метаданные, которые предоставляются фреймворку автозаполнения, с помощью API автозаполнения. Некоторые представления выступают в качестве контейнера виртуальных дочерних элементов, например представления, содержащие пользовательский интерфейс, отрисованный с помощью OpenGL. Чтобы эти представления могли работать с фреймворком автозаполнения, они должны использовать API для указания структуры информации, используемой в приложении.
Если в вашем приложении используются специальные представления, учитывайте следующие сценарии:
- Специальный режим просмотра предоставляет стандартную структуру просмотра или структуру просмотра по умолчанию.
- Специальный режим просмотра имеет виртуальную структуру или структуру, которая недоступна для фреймворка автозаполнения.
Специальные представления со стандартной структурой
В пользовательских представлениях можно определить метаданные, необходимые для работы автозаполнения. Убедитесь, что ваше специальное представление правильно управляет метаданными для работы с фреймворком автозаполнения. Ваше специальное представление должно выполнять следующие действия:
- Обработайте значение автозаполнения, которое фреймворк отправляет в ваше приложение.
- Передайте фреймворку тип и значение автозаполнения.
Когда запускается автозаполнение, фреймворк автозаполнения вызывает autofill() в вашем представлении и отправляет значение, которое должно использовать представление. Реализуйте autofill(), чтобы указать, как ваше специальное представление обрабатывает значение автозаполнения.
В представлении необходимо указать тип и значение автозаполнения, переопределив методы getAutofillType() и getAutofillValue() соответственно.
Наконец, автозаполнение не должно заполнять представление, если пользователь не может указать значение для представления в его текущем состоянии, например если представление отключено.
В таких случаях getAutofillType() должен возвращать AUTOFILL_TYPE_NONE, getAutofillValue() – null, а autofill() не должен ничего делать.
В следующих случаях требуются дополнительные действия:
- Специальное представление можно редактировать.
- Представление содержит конфиденциальные данные.
Специальное представление можно редактировать.
Если представление можно редактировать, уведомьте фреймворк автозаполнения об изменениях, вызвав notifyValueChanged() для объекта AutofillManager.
Специальное представление содержит конфиденциальные данные.
Если представление содержит информацию, позволяющую идентифицировать личность, например адреса электронной почты, номера кредитных карт и пароли, его необходимо пометить как конфиденциальное.
Как правило, представления, контент которых поступает из статических ресурсов, не содержат конфиденциальных данных, а представления, контент которых задается динамически, могут содержать конфиденциальные данные. Например, ярлык, содержащий текст введите имя пользователя, не содержит конфиденциальных данных, а ярлык с текстом Здравствуйте, Иван – содержит.
По умолчанию фреймворк автозаполнения считает все данные конфиденциальными. Вы можете пометить данные, которые не являются конфиденциальными.
Чтобы указать, что представление содержит конфиденциальные данные, реализуйте onProvideAutofillStructure() и вызовите setDataIsSensitive() для объекта ViewStructure.
В примере кода ниже показано, как пометить данные в структуре представления как неконфиденциальные.
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);
}
Если представление принимает только предопределенные значения, вы можете использовать метод setAutofillOptions(), чтобы задать варианты, которые можно использовать для автозаполнения представления. В частности, этот метод должны использовать представления, у которых тип автозаполнения – AUTOFILL_TYPE_LIST, поскольку сервис автозаполнения может работать лучше, если он знает, какие варианты доступны для заполнения представления.
Аналогичная ситуация возникает при использовании адаптера, например Spinner. Например, спиннер, который динамически создает годы на основе текущего года для использования в полях срока действия кредитной карты, может реализовать метод getAutofillOptions() интерфейса Adapter, чтобы предоставить список лет.
Представления, в которых используется ArrayAdapter, также могут предоставлять списки значений. ArrayAdapter автоматически задает параметры автозаполнения для статических ресурсов.
Если вы передаете значения динамически, переопределите getAutofillOptions().
Специальные представления с виртуальной структурой
Чтобы фреймворк автозаполнения мог редактировать и сохранять информацию в интерфейсе приложения, ему требуется структура представления. Структура представления недоступна фреймворку в следующих случаях:
- Приложение использует низкоуровневый движок визуализации, например OpenGL, для отрисовки интерфейса.
- Для отрисовки интерфейса приложение использует экземпляр
Canvas.
В таких случаях вы можете указать структуру представления, реализовав onProvideAutofillVirtualStructure() и выполнив следующие действия:
- Увеличьте количество дочерних элементов в структуре представления, вызвав
addChildCount(). - Добавьте ребенка, позвонив по номеру
newChild(). - Задайте идентификатор автозаполнения для дочернего элемента, вызвав
setAutofillId(). - Задайте нужные свойства, например значение и тип автозаполнения.
- Если данные в виртуальном дочернем элементе конфиденциальны, передайте
trueвsetDataIsSensitive(), в противном случае передайтеfalse.
В приведенном ниже фрагменте кода показано, как создать дочерний элемент в виртуальной структуре.
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);
}
Если элементы в виртуальной структуре меняются, сообщите об этом фреймворку, выполнив следующие действия:
- Если фокус внутри дочерних элементов меняется, вызовите
notifyViewEntered()иnotifyViewExited()для объектаAutofillManager. - Если значение дочернего элемента изменилось, вызовите
notifyValueChanged()для объектаAutofillManager. - Если иерархия View больше недоступна, потому что пользователь завершил шаг в рабочем процессе, например вошел в аккаунт с помощью формы входа, вызовите
commit()для объектаAutofillManager. - Если иерархия View недействительна, потому что пользователь отменил шаг в рабочем процессе, например нажал кнопку, которая очищает форму входа, вызовите
cancel()для объектаAutofillManager.
Используйте обратные вызовы для событий автозаполнения
Если в вашем приложении есть собственные представления автозаполнения, вам нужен механизм, который сообщает приложению о необходимости включить или отключить представления в ответ на изменения в доступности автозаполнения пользовательского интерфейса. Фреймворк автозаполнения предоставляет такой механизм в виде метода AutofillCallback.
Этот класс предоставляет метод onAutofillEvent(View, int), который приложение вызывает после изменения состояния автозаполнения, связанного с представлением.
Существует также перегруженная версия этого метода, которая включает параметр childId, который ваше приложение может использовать с виртуальными представлениями. Доступные состояния определяются как константы в обратном вызове.
Вы можете зарегистрировать обратный вызов с помощью метода registerCallback() класса AutofillManager. В следующем примере кода показано, как объявить обратный вызов для событий автозаполнения:
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;
}
}
});
Чтобы удалить обратный вызов, используйте метод unregisterCallback().
Настройка выделения при автозаполнении
Когда представление заполняется автоматически, платформа отображает поверх него Drawable, чтобы указать, что содержимое представления заполнено автоматически. По умолчанию это сплошной прямоугольник полупрозрачного цвета, который немного темнее цвета фона, используемого в теме. Объект drawable не нужно менять, но его можно настроить, переопределив элемент android:autofilledHighlight темы, используемой приложением или действием, как показано в этом примере:
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">
Аутентификация при автозаполнении
Сервис автозаполнения может требовать аутентификации пользователя, прежде чем заполнять поля в вашем приложении. В этом случае система Android запускает операцию аутентификации сервиса как часть стека операций вашего приложения.
Обновлять приложение для поддержки аутентификации не нужно, поскольку она выполняется в сервисе. Однако вы должны убедиться, что структура представления действия сохраняется при его перезапуске. Например, можно создать структуру представления в onCreate(), а не в onStart() или onResume().
Вы можете проверить, как ведет себя ваше приложение, когда сервис автозаполнения требует аутентификации. Для этого используйте HeuristicsService из примера AutofillFramework и настройте его так, чтобы требовалась аутентификация ответа на заполнение. Вы также можете использовать пример BadViewStructureCreationSignInActivity, чтобы воспроизвести эту проблему.
Назначьте идентификаторы автозаполнения повторно используемым представлениям
Контейнеры, которые повторно используют представления, например класс RecyclerView, полезны для приложений, в которых нужно показывать прокручиваемые списки элементов на основе больших наборов данных. По мере прокрутки контейнера система повторно использует представления в макете, но они содержат новый контент.
Если исходное содержимое повторно используемого представления заполнено, сервис автозаполнения сохраняет логическое значение представлений, используя их идентификаторы автозаполнения. Проблема возникает, когда при повторном использовании представлений в макете их логические идентификаторы остаются прежними, в результате чего неверные пользовательские данные автозаполнения связываются с идентификатором автозаполнения.
Чтобы решить эту проблему на устройствах с Android 9 (уровень API 28) и более поздними версиями, явно управляйте идентификаторами автозаполнения представлений, используемых RecyclerView, с помощью следующих методов:
- Метод
getNextAutofillId()получает новый идентификатор автозаполнения, уникальный для действия. - Метод
setAutofillId()задает уникальный логический идентификатор автозаполнения для этого представления в действии.
Устранение известных проблем
В этом разделе описаны способы устранения известных проблем с фреймворком автозаполнения.
Автозаполнение приводит к сбоям в работе приложений на устройствах с Android 8.0 и 8.1
В Android 8.0 (уровень API 26) и 8.1 (уровень API 27) автозаполнение может приводить к сбоям в работе приложения. Чтобы избежать возможных проблем, пометьте тегом importantForAutofill=no все представления, которые не заполняются автоматически. Вы также можете отметить все занятие как importantForAutofill=noExcludeDescendants.
Диалоговые окна, размер которых был изменен, не учитываются при автозаполнении.
В Android 8.1 (уровень API 27) и более ранних версиях, если размер представления в диалоговом окне изменяется после его отображения, представление не учитывается при автозаполнении. Эти представления не включаются в объект AssistStructure, который система Android отправляет сервису автозаполнения. В результате сервис не может заполнить представления.
Чтобы устранить эту проблему, замените свойство token параметров диалогового окна свойством token действия, которое создает диалоговое окно. Убедившись, что автозаполнение включено, сохраните параметры окна в методе onWindowAttributesChanged() класса, наследующего от Dialog. Затем замените свойство token сохраненных параметров свойством token родительского действия в методе onAttachedToWindow().
В следующем фрагменте кода показан класс, реализующий это решение:
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();
}
}
Чтобы избежать ненужных операций, в следующем фрагменте кода показано, как проверить, поддерживается ли автозаполнение на устройстве и включено ли оно для текущего пользователя, а также требуется ли это обходное решение:
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();
}
}
Как протестировать приложение с автозаполнением
После оптимизации приложения для работы с сервисами автозаполнения проверьте, правильно ли оно работает.
Для тестирования приложения используйте эмулятор или физическое устройство с Android 8.0 (уровень API 26) или более поздней версии. Подробнее о том, как создавать виртуальные устройства.
Установите сервис автозаполнения
Чтобы протестировать приложение с автозаполнением, установите другое приложение, которое предоставляет сервисы автозаполнения. Для этого можно использовать стороннее приложение, но проще воспользоваться примером сервиса автозаполнения, чтобы не регистрироваться в сторонних сервисах.
Чтобы протестировать приложение с сервисами автозаполнения, используйте пример фреймворка автозаполнения Android на Java. В примере приложения есть сервис автозаполнения и клиентские классы Activity, которые можно использовать для тестирования рабочего процесса перед его внедрением в ваше приложение. На этой странице упоминается пример приложения android-AutofillFramework.
После установки приложения включите сервис автозаполнения в системных настройках эмулятора. Для этого выберите Настройки > Система > Язык и ввод > Дополнительно > Помощь при вводе > Сервис автозаполнения.
Анализ требований к данным
Чтобы протестировать приложение с помощью сервиса автозаполнения, у сервиса должны быть данные, которые он может использовать для заполнения вашего приложения. Сервис также должен понимать, какой тип данных ожидается в представлениях вашего приложения. Например, если в вашем приложении есть представление, в котором ожидается имя пользователя, у сервиса должен быть набор данных, содержащий имя пользователя, и некоторый механизм, позволяющий узнать, что представление ожидает такие данные.
Укажите, какой тип данных ожидается в представлениях, задав атрибут android:autofillHints. Некоторые сервисы используют сложные эвристические алгоритмы для определения типа данных, но другие, такие как пример приложения, полагаются на информацию, предоставленную разработчиком. Чтобы приложение лучше работало с сервисами автозаполнения, задайте атрибут android:autofillHints в представлениях, которые подходят для автозаполнения.
Запустите тест
После анализа требований к данным вы можете запустить тест, который включает сохранение тестовых данных в сервисе автозаполнения и запуск автозаполнения в вашем приложении.
Сохранение данных в сервисе
Чтобы сохранить данные в активном сервисе автозаполнения, сделайте следующее:
- Откройте приложение, в котором есть представление, ожидающее тип данных, который вы хотите использовать во время тестирования. Пример приложения android-AutofillFramework предоставляет пользовательский интерфейс с представлениями, которые ожидают несколько типов данных, таких как номера кредитных карт и имена пользователей.
- Выберите представление, содержащее нужный тип данных.
- Введите значение в представление.
- Нажмите кнопку подтверждения, например Войти или Отправить. Обычно для сохранения данных нужно отправить форму.
- Подтвердите запрос разрешения в системном диалоговом окне. В системном диалоговом окне будет показано название активного сервиса и вопрос, хотите ли вы использовать его для тестирования. Если вы хотите использовать сервис, нажмите Сохранить.
Если Android не показывает диалоговое окно разрешения или сервис не тот, который вы хотите использовать в своем тесте, проверьте, активен ли сервис в настоящее время в системных настройках.
Как запустить автозаполнение в приложении
Чтобы запустить автозаполнение в приложении, выполните следующие действия:
- Откройте приложение и перейдите к действию, которое содержит представления, которые вы хотите протестировать.
- Нажмите на представление, которое нужно заполнить.
- Система отображает интерфейс автозаполнения, который содержит наборы данных, которые могут заполнить представление, как показано на рисунке 1.
- Выберите набор данных, который хотите использовать. В представлении отображаются данные, которые ранее хранились в сервисе.
Если Android не показывает интерфейс автозаполнения, попробуйте выполнить следующие действия по устранению неполадок:
- Убедитесь, что в представлениях приложения используется правильное значение атрибута
android:autofillHints. Список возможных значений атрибута приведен в константах с префиксомAUTOFILL_HINTв классеView. - Убедитесь, что атрибут
android:importantForAutofillимеет значение, отличное отno, в представлении, которое нужно заполнить, или значение, отличное отnoExcludeDescendants, в представлении или одном из его родительских элементов.