Os aplicativos que usam visualizações padrão funcionam com a estrutura de preenchimento automático sem necessidade de nenhuma configuração especial. No entanto, é possível otimizar a forma como seu app funciona com esse framework.
Configurar o ambiente de preenchimento automático
Esta seção descreve como configurar a funcionalidade básica de preenchimento automático para seu app.
Configurar um serviço de preenchimento automático
É necessário configurar um serviço de preenchimento automático no seu dispositivo para que o app use a estrutura de preenchimento automático. Embora a maior parte dos smartphones e tablets com Android 8.0 (API de nível 26) e versões mais recentes ofereça preenchimento automático, recomendamos que você use um serviço de teste em seu app, como as amostras da Estrutura de preenchimento automático do Android em Java | Kotlin. Ao usar um emulador, é necessário configurar explicitamente um serviço de preenchimento automático, porque ele pode não ter um serviço padrão.
Depois de instalar o serviço de preenchimento automático de teste do app de exemplo, ative-o navegando para Configurações > Sistema > Idioma e entrada > Avançado > Assistência de entrada > Serviço de preenchimento automático.
Para ver mais informações sobre como configurar um emulador para testar o preenchimento automático, consulte Testar seu app com o preenchimento automático.
Dar dicas para o preenchimento automático
O serviço de preenchimento automático tenta determinar o tipo de visualização usando heurística. No entanto, caso seu app dependa dessas heurísticas, o comportamento de preenchimento automático poderá mudar inesperadamente quando o app for atualizado. Para garantir que o serviço de preenchimento automático identifique corretamente os formatos do seu app, você precisa dar dicas de preenchimento automático.
Você pode configurar essas dicas usando o atributo android:autofillHints
. O exemplo a seguir configura uma dica de "senha" no EditText
:
<EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:autofillHints="password" />
Você também pode definir dicas de forma programática usando o método setAutofillHints()
, conforme mostrado no exemplo a seguir:
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);
Constantes de dicas predefinidas
A estrutura de preenchimento automático não valida dicas. Elas são apenas passadas
sem alteração ou validação para o serviço de preenchimento automático. Embora seja possível usar qualquer
valor, a classe
View
e a classe AndroidX
HintConstants
contêm
listas de constantes de dica com compatibilidade oficial.
Ao usar uma combinação dessas constantes, é possível criar layouts para situações comuns de preenchimento automático:
Credenciais da conta
Ao preencher automaticamente as credenciais da conta, um formulário de login pode incluir dicas
como
AUTOFILL_HINT_USERNAME
e
AUTOFILL_HINT_PASSWORD
.
Ao criar uma nova conta ou quando os usuários mudarem o nome de usuário e a senha,
você poderá usar
AUTOFILL_HINT_NEW_USERNAME
e
AUTOFILL_HINT_NEW_PASSWORD
.
Informações do cartão de crédito
Ao solicitar informações de cartão de crédito, você pode usar dicas como
AUTOFILL_HINT_CREDIT_CARD_NUMBER
e
AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE
.
Para datas de validade do cartão de crédito, siga um destes procedimentos:
- Se você estiver usando uma única visualização para a data de validade, use
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE
. - Se estiver usando uma visualização diferente para cada parte da data de validade, pode usar
AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY
,AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH
eAUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR
para cada visualização.
Endereço físico
Ao realizar o preenchimento automático de um endereço físico, você pode usar dicas como as seguintes:
- Para preencher automaticamente um endereço em uma única visualização, use
AUTOFILL_HINT_POSTAL_ADDRESS
. - Ao usar visualizações separadas para partes diferentes de um endereço, você pode usar qualquer uma das seguintes opções:
Nomes de pessoas
Ao realizar o preenchimento automático de nomes de pessoas, você pode usar dicas como as seguintes:
- Para preencher automaticamente o nome completo de uma pessoa em uma única visualização, use
AUTOFILL_HINT_PERSON_NAME
. - Se você estiver usando uma visualização diferente para cada parte do nome, poderá usar uma das seguintes:
Números de telefone
Para números de telefone, você pode usar o seguinte:
- Ao apresentar um número de telefone completo em uma única visualização, use
AUTOFILL_HINT_PHONE_NUMBER
. - Se você estiver usando visualizações diferentes para partes diferentes de um número de telefone, poderá usar uma das seguintes opções:
Senha única (OTP)
Para uma senha única em uma única visualização, você pode usar
AUTOFILL_HINT_SMS_OTP
.
Ao usar várias visualizações em que cada uma delas mapeia um único dígito da OTP,
você pode usar o método
generateSmsOptHintForCharacterPosition()
para gerar dicas por caracteres.
Marcar campos como importantes para o preenchimento automático
Você pode informar ao sistema se os campos do seu app precisam ser
incluídos em uma estrutura de visualização para fins de preenchimento automático. Por padrão, a visualização usa
o modo IMPORTANT_FOR_AUTOFILL_AUTO
, que permite que o Android use a heurística dele para determinar se a visualização é importante para o preenchimento automático.
Você pode definir a importância usando o atributo android:importantForAutofill
:
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:importantForAutofill="no" />
O valor de importantForAutofill
pode ser qualquer um dos valores definidos em android:importantForAutofill
:
auto
- Permite que o sistema Android use a heurística dele para determinar se a visualização é importante para o preenchimento automático.
no
- Essa visualização não é importante para o preenchimento automático.
noExcludeDescendants
- Essa visualização e as filhas dela não são importantes para o preenchimento automático.
yes
- Essa visualização é importante para o preenchimento automático.
yesExcludeDescendants
- Essa visualização é importante para o preenchimento automático, mas os filhos dela não são.
Você também pode usar o método setImportantForAutofill()
:
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);
Há casos em que uma visualização, uma estrutura de visualização ou toda a atividade não é importante para o preenchimento automático:
- Um campo CAPTCHA em uma atividade de login geralmente não é importante para o preenchimento automático. Em
casos como esse, você pode marcar a visualização como
IMPORTANT_FOR_AUTOFILL_NO
. - Em uma visualização em que o usuário cria conteúdo, como um editor de texto ou planilhas,
a estrutura inteira da visualização geralmente não é importante para o preenchimento automático. Em
casos como esse, você pode marcar a visualização como
IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
para garantir que todos os filhos também sejam marcados como não importantes para preenchimento automático. - Em algumas atividades dentro de jogos, como aquelas que exibem jogabilidade,
nenhuma das visualizações das atividades é importante para o preenchimento automático. Você pode marcar
a visualização raiz como
IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
para garantir que todas as visualizações da atividade sejam marcadas como não importantes para o preenchimento automático.
Associar dados de sites com apps para dispositivos móveis
Serviços de preenchimento automático, como o preenchimento automático do Google, podem compartilhar dados de login de usuários entre navegadores e dispositivos Android após a associação do app com o site. Quando um usuário escolhe o mesmo serviço de preenchimento automático em ambas as plataformas, o login no app da Web disponibiliza as credenciais para o preenchimento automático quando ele faz login no app para Android correspondente.
Para associar seu app para Android com seu site, é necessário hospedar um Digital Asset Link com a
relação delegate_permission/common.get_login_creds
no site. Em seguida,
declare a associação no arquivo AndroidManifest.xml
do seu app. Para ver
instruções detalhadas de como associar seu site ao seu app para Android, consulte
Ativar o login automático em apps e
sites.
Preencher um fluxo de trabalho de preenchimento automático
Esta seção descreve situações específicas em que você pode seguir etapas para melhorar a funcionalidade de preenchimento automático para os usuários do seu app.
Determinar se o preenchimento automático está ativado
Você pode implementar uma funcionalidade de preenchimento automático adicional no seu app ou até
mesmo em visualizações específicas do app, caso o preenchimento automático esteja disponível para o usuário. Por exemplo,
TextView
mostra uma entrada de preenchimento automático no menu flutuante se
o preenchimento automático estiver ativado para o usuário. Para verificar se o preenchimento automático
está ativado, chame o método isEnabled()
do
objeto AutofillManager
.
Os usuários podem ativar ou desativar o preenchimento automático e alterar esse serviço navegando até Configurações > Sistema > Idioma e entrada > Avançado > Assistência de entrada > Serviço de preenchimento automático . Seu app não pode modificar as configurações de preenchimento automático do usuário.
Para garantir que sua experiência de assinatura e login seja otimizada para usuários sem preenchimento automático, considere a implementação do Smart Lock para senhas.
Forçar uma solicitação de preenchimento automático
Às vezes, pode ser necessário forçar uma solicitação de preenchimento automático, que ocorre em resposta
a uma ação do usuário. Por exemplo, TextView
oferece um item de menu
de preenchimento automático quando o usuário toca em uma visualização e a mantém pressionada. O exemplo de código a seguir mostra
como forçar uma solicitação de preenchimento automático:
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); } }
Também é possível usar o método cancel()
para cancelar o contexto atual de preenchimento automático. Isso pode ser útil, por exemplo, se você
tem um botão que limpa os campos em uma página de login.
Usar o tipo de preenchimento automático correto para dados nos controles do seletor
Os seletores são úteis em algumas situações de preenchimento automático, porque fornecem uma IU que permite que os
usuários mudem o valor de um campo que armazena dados de data ou hora. Por exemplo, em um
formulário de cartão de crédito, um seletor de data permite que os usuários insiram ou alterem a data de validade
do cartão de crédito. No entanto, você precisará usar outra visualização, como EditText
, para exibir os dados quando o seletor não estiver visível.
Um objeto EditText
nativamente espera o preenchimento automático de dados do tipo AUTOFILL_TYPE_TEXT
. Caso esteja usando outro tipo de
dados, é necessário criar uma visualização personalizada, herdada de EditText
e
que implemente os métodos necessários para processar o tipo de dados correspondente. Por
exemplo, caso você tenha um campo de data, implemente os métodos com uma lógica
que processe corretamente os valores do tipo AUTOFILL_TYPE_DATE
.
Quando você especifica o tipo de dados de preenchimento automático, esse serviço pode criar uma representação apropriada dos dados exibidos na visualização. Para ver mais informações, consulte Usar seletores com o preenchimento automático.
Concluir o contexto de preenchimento automático
A estrutura de preenchimento automático salva a entrada do usuário para uso futuro mostrando uma caixa de diálogo "Salvar para
preenchimento automático?" depois que o contexto do preenchimento é concluído. Normalmente, o
contexto do preenchimento automático termina quando uma atividade é concluída. No entanto, há algumas
situações em que você precisa notificar explicitamente a estrutura; por exemplo, caso
esteja usando a mesma atividade, mas fragmentos diferentes para suas telas de login e
de conteúdo. Nessas situações especiais, você pode concluir
o contexto explicitamente chamando AutofillManager.commit()
.
Compatibilidade com visualizações personalizadas
As visualizações personalizadas podem especificar os metadados que são expostos à estrutura de preenchimento automático usando a API de preenchimento automático. Algumas visualizações agem como um contêiner de filhos virtuais, como visualizações que contêm IU renderizada por OpenGL. Essas visualizações precisam usar a API para especificar a estrutura das informações usadas no app antes de funcionar com a estrutura de preenchimento automático.
Se seu app usa visualizações personalizadas, considere os seguintes cenários:
- A visualização personalizada fornece uma estrutura de visualização padrão ou uma estrutura de visualização comum.
- A visualização personalizada tem uma estrutura virtual ou uma estrutura de visualização que não está disponível para a estrutura de preenchimento automático.
Visualizações personalizadas com estrutura de visualização padrão
As visualizações personalizadas podem definir os metadados necessários para que o preenchimento automático funcione. Verifique se a visualização personalizada gera os metadados de forma adequada para funcionar com a estrutura de preenchimento automático. Sua visualização personalizada precisa executar as seguintes ações:
- Manipular o valor do preenchimento automático que a estrutura envia para seu app.
- Fornecer o tipo e o valor do preenchimento automático para a estrutura.
Quando o preenchimento automático é acionado, a estrutura chama autofill()
na sua visualização e envia o valor que
a visualização da propriedade precisa usar. Você precisa implementar autofill()
para especificar como
a visualização personalizada processa o valor do preenchimento automático.
Sua visualização precisa especificar um tipo e um valor de preenchimento automático substituindo os métodos getAutofillType()
e getAutofillValue()
, respectivamente. Ao adicionar esse código,
você garante que sua visualização possa fornecer tipos e valores de preenchimento automático adequados
à estrutura.
Por fim, o preenchimento automático não pode preencher a visualização caso o usuário não possa fornecer um valor
para a visualização no estado atual (por exemplo, se a visualização estiver desativada). Nesses
casos, getAutofillType()
retorna AUTOFILL_TYPE_NONE
, getAutofillValue()
retorna null
e autofill()
não faz nada.
Os casos a seguir exigem outras etapas para que possam funcionar corretamente na estrutura:
- A visualização personalizada é editável.
- A visualização personalizada contém dados confidenciais.
A visualização personalizada é editável.
Se a visualização for editável, você precisará notificar a estrutura de preenchimento automático sobre as alterações
chamando notifyValueChanged()
no objeto AutofillManager
.
A visualização personalizada contém dados confidenciais
Caso a visualização contenha informações de identificação pessoal, como
endereços de e-mail, números de cartão de crédito e senhas, ela precisará ser marcada
como tal. Em geral, as visualizações cujo conteúdo é proveniente de recursos estáticos não
contêm dados confidenciais, mas aquelas cujo conteúdo é definido de modo dinâmico podem conter
dados confidenciais. Por exemplo, um rótulo que contenha digite seu nome de usuário não
contém dados confidenciais, enquanto um rótulo que contenha Olá, João, sim. Para marcar
se a visualização contém dados confidenciais ou não, implemente onProvideAutofillStructure()
e
chame setDataIsSensitive()
no objeto ViewStructure
.
O exemplo de código a seguir mostra como marcar os dados na estrutura da visualização como confidenciais ou não:
Kotlin
override fun onProvideAutofillStructure(structure: ViewStructure, flags: Int) { super.onProvideAutofillStructure(structure, flags) // Content that comes from static resources generally isn't sensitive. val sensitive = !contentIsSetFromResources() structure.setDataIsSensitive(sensitive) }
Java
@Override public void onProvideAutofillStructure(ViewStructure structure, int flags) { super.onProvideAutofillStructure(structure, flags); // Content that comes from static resources generally isn't sensitive. boolean sensitive = !contentIsSetFromResources(); structure.setDataIsSensitive(sensitive); }
Se a visualização aceita apenas valores predefinidos, use o método setAutofillOptions()
para
definir as opções que podem ser usadas para o preenchimento automático dessa visualização. Especificamente, as visualizações
cujo tipo de preenchimento automático é AUTOFILL_TYPE_LIST
precisam usar
esse método porque o serviço de preenchimento automático pode realizar um trabalho melhor se
conhecer as opções disponíveis para preencher a visualização.
As visualizações que usam um adaptador, como um Spinner
, são
casos parecidos. Por exemplo, um controle giratório que fornece anos criados dinamicamente
(com base no ano atual) para usar em campos de validade de cartão de crédito pode
implementar o método getAutofillOptions()
da
interface Adapter
para fornecer uma lista de anos.
Visualizações que usam um ArrayAdapter
também podem fornecer listas
de valores. ArrayAdapter
define automaticamente as opções de preenchimento automático para recursos estáticos.
No entanto, se você fornecer os valores de maneira dinâmica, precisará substituir getAutofillOptions()
.
Visualizações personalizadas com estrutura virtual
A estrutura de preenchimento automático exige uma estrutura de visualização para que possa editar e salvar as informações na IU do seu app. Existem algumas situações em que a estrutura de visualização não está disponível para a estrutura:
- O app usa um mecanismo de renderização de nível inferior, como OpenGL, para renderizar a IU.
- O app usa uma instância de
Canvas
para desenhar a IU.
Nesses casos, você pode especificar uma estrutura de visualização implementando
onProvideAutofillVirtualStructure()
e seguindo estas etapas:
- Aumente a contagem de filhos da estrutura de visualização chamando
addChildCount()
. - Adicione uma filha chamando
newChild()
. - Defina o ID de preenchimento automático da filha chamando
setAutofillId()
. - Defina as propriedades relevantes, como o valor e o tipo de preenchimento automático.
- Se os dados da filha virtual forem confidenciais, será necessário passar
true
parasetDataIsSensitive()
, oufalse
, caso não forem.
O snippet de código a seguir mostra como criar uma nova filha na estrutura virtual:
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. For example, if 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, if // 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. For example, if the child is // a spinner. CharSequence childAutofillOptions[] = { "option1", "option2" }; child.setAutofillOptions(childAutofillOptions); // Just like other types of views, mark the data as sensitive, if // appropriate. boolean sensitive = !contentIsSetFromResources(); child.setDataIsSensitive(sensitive); }
Quando os elementos em uma estrutura virtual mudam, é necessário notificar a estrutura realizando as seguintes tarefas:
- Se o foco dentro das filhas mudou , chame
notifyViewEntered()
enotifyViewExited()
no objetoAutofillManager
. - Se o valor de uma filha mudou, chame
notifyValueChanged()
no objetoAutofillManager
. - Se a hierarquia de visualização não estiver mais disponível porque o usuário concluiu
uma etapa no fluxo de trabalho (por exemplo, o usuário fez login usando um formulário de login),
chame
commit()
no objetoAutofillManager
. - Se a hierarquia de visualização não for mais válida porque o usuário cancelou uma etapa
no fluxo de trabalho (por exemplo, se o usuário clicou em um botão que limpa um formulário
de login), chame
cancel()
no objetoAutofillManager
.
Usar callbacks em eventos de preenchimento automático
Se seu app fornecer visualizações próprias de preenchimento automático, você precisará de um mecanismo que instrua
o app a ativar ou desativar as visualizações em resposta a alterações na affordance de preenchimento automático
da IU. A estrutura de preenchimento automático fornece esse mecanismo na forma de AutofillCallback
.
Essa classe fornece o método onAutofillEvent(View, int)
,
que o app chama depois de uma alteração no estado de preenchimento automático associado a uma visualização.
Existe também uma versão sobrecarregada desse método, que inclui um parâmetro childId
que seu app pode usar com visualizações virtuais. Os estados disponíveis são
definidos como
constantes no callback.
Você pode registrar um callback usando o método registerCallback()
da classe AutofillManager
. O exemplo de código a seguir mostra
como declarar um callback para eventos de preenchimento automático:
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; } } });
Quando for o momento de remover o callback, use o método
unregisterCallback()
.
Personalizar o drawable destacado com preenchimento automático
Quando uma visualização é preenchida automaticamente, a plataforma renderiza um
Drawable
sobre a visualização para indicar que o conteúdo da visualização foi preenchido automaticamente. Por padrão, esse desenho é um
retângulo sólido com uma cor translúcida, ligeiramente mais escura do que a
cor do tema usada para desenhar o plano de fundo. O drawable não precisa ser alterado,
mas pode ser personalizado substituindo o item android:autofilledHighlight
do
tema usado pelo app
ou atividade, como mostrado neste exemplo:
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">
Autenticar para o preenchimento automático
Um serviço de preenchimento automático pode exigir que o usuário faça a autenticação antes que o serviço possa preencher campos no seu app. Nesse caso, o sistema Android inicia a atividade de autenticação do serviço como parte da pilha da atividade.
Você não precisa atualizar seu app para oferecer compatibilidade com a autenticação porque
a autenticação ocorre no serviço. No entanto, você precisa garantir
que a estrutura de visualização da atividade seja preservada quando a atividade for reiniciada (por
exemplo, criando a estrutura de visualização em
onCreate()
,
não em onStart()
ou
onResume()
).
Você pode verificar como seu app se comporta quando um serviço de preenchimento automático requer autenticação usando HeuristicsService da amostra AutofillFramework e configurando-o para exigir autenticação de resposta de preenchimento. Você também pode usar a amostra BadViewStructureCreationSignInActivity para emular esse problema.
Atribuir IDs de preenchimento automático a visualizações recicladas
Os contêineres que reciclam visualizações, como a classe
RecyclerView
, são muito úteis para apps que precisam
exibir listas de rolagem de elementos com base em grandes conjuntos de dados. À medida que o contêiner
rola, o sistema reutiliza as visualizações no layout, mas elas mostram
conteúdo novo. Se o conteúdo inicial da visualização estiver preenchido, o serviço
de preenchimento automático mantém o significado lógico das visualizações usando os IDs de preenchimento automático. Ocorre
um problema quando, enquanto o sistema reutiliza as visualizações no layout, os IDs
lógicos das visualizações permanecem os mesmos, fazendo com que dados errados de preenchimento automático do usuário sejam
associados a um ID de preenchimento automático.
Para resolver esse problema em dispositivos com o Android 9 (API de nível 28) ou mais recentes,
é possível gerenciar explicitamente o ID de preenchimento automático de visualizações usadas por
RecyclerView
usando esses novos métodos:
- O método
getNextAutofillId()
recebe um novo ID de preenchimento automático exclusivo para a atividade. - O método
setAutofillId()
define o ID de preenchimento automático lógico e exclusivo dessa visualização na atividade.
Resolver problemas conhecidos
Esta seção apresenta soluções alternativas para problemas conhecidos na estrutura de preenchimento automático.
O preenchimento automático faz com que os apps falhem no Android 8.0 e 8.1
No Android 8.0 (API de nível 26) e no 8.1 (API de nível 27), o preenchimento automático pode fazer com que seu app falhe em determinadas situações. Para contornar possíveis problemas, marque todas as visualizações que não são preenchidas automaticamente com importantForAutofill=no
. Você também pode marcar toda a atividade com importantForAutofill=noExcludeDescendants
.
As caixas de diálogo redimensionadas não são consideradas para o preenchimento automático
No Android 8.1 (API de nível 27) e versões anteriores, se uma visualização em uma
caixa de diálogo for redimensionada depois de ser exibida,
a visualização não será considerada para preenchimento automático. Essas visualizações não são incluídas
no objeto AssistStructure
que o sistema Android envia
ao serviço de preenchimento automático. Como resultado, o serviço não pode preencher as visualizações.
Para contornar esse problema, substitua a propriedade token
dos parâmetros da caixa de diálogo
pela propriedade token
da atividade que cria a caixa de diálogo.
Depois de confirmar que o preenchimento automático está ativado, salve os parâmetros no método
onWindowAttributesChanged()
da classe que herda de Dialog
. Em seguida, substitua
a propriedade token
dos parâmetros
salvos pela propriedade token
da atividade principal no método onAttachedToWindow()
.
O snippet de código a seguir mostra uma classe que implementa a solução alternativa:
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(); } }
Para evitar operações desnecessárias, o snippet de código a seguir mostra como verificar se o preenchimento automático é compatível com o dispositivo, se está ativado para o usuário atual e se essa alternativa é necessária:
Kotlin
// AutofillExtensions.kt fun Context.isDialogResizedWorkaroundRequired(): Boolean { // After the issue is resolved on Android, you should check if 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 only 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, you should check if 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 only 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(); } }
Testar seu app com o preenchimento automático
A maioria dos apps funciona com serviços de preenchimento automático sem nenhuma alteração. No entanto, você pode otimizar seu app para garantir que ele funcione da melhor forma possível com os serviços de preenchimento automático. Depois de otimizar seu app, é necessário testá-lo para garantir que ele funcione como pretendido com os serviços de preenchimento automático.
Use um emulador ou um dispositivo físico com o Android 8.0 (API de nível 26) ou mais recente para testar seu app. Para ver mais informações sobre como criar um emulador, consulte Criar e gerenciar dispositivos virtuais.
Instalar um serviço de preenchimento automático
Antes de testar seu app com o preenchimento automático, você precisa instalar outro app que forneça serviços de preenchimento automático. Você pode usar um app de terceiros para esse fim, mas é mais fácil usar um serviço de preenchimento automático de amostra para não precisar se inscrever em serviços de terceiros.
Use a amostra da estrutura de preenchimento automático
do Android para testar seu app com serviços de preenchimento automático em
Java
|
Kotlin. O app de amostra fornece um serviço
de preenchimento automático e classes Activity
cliente que podem ser usados para testar
o fluxo de trabalho antes de usá-lo com seu app. Esta página faz referência ao app de amostra
android-AutofillFramework.
Depois de instalar o app, ative o serviço de preenchimento automático nas configurações do sistema. É possível ativar o serviço navegando para Configurações > Sistema > Idioma e entrada > Avançado > Assistência de entradas > Serviço de preenchimento automático.
Analisar requisitos de dados
Para testar seu app com o serviço de preenchimento automático, o serviço precisa ter dados que possam ser usados para preencher o app. Ele também precisa entender os tipos de dados esperados nas visualizações do seu app. Por exemplo, se seu aplicativo tiver uma visualização que espera um nome de usuário, o serviço deverá ter um conjunto de dados que contenha um nome de usuário e algum mecanismo para saber que a visualização espera tais dados.
É preciso permitir que o serviço saiba que tipo de dados é esperado nas suas visualizações,
definindo o atributo android:autofillHints
. Alguns serviços usam heurística sofisticada para determinar o tipo de
dado, mas outros, como o app de amostra, dependem do desenvolvedor para fornecer essas
informações. Seu app funciona melhor com os serviços de preenchimento automático se você definir o
android:autofillHints
nas visualizações relevantes para o preenchimento automático.
Executar seu teste
Depois de analisar os requisitos de dados, você pode executar o teste, o que inclui salvar os dados de teste no serviço de preenchimento automático e acionar o preenchimento automático no app.
Salvar dados no serviço
As etapas a seguir mostram como salvar dados no serviço de preenchimento automático ativo:
- Abra um app que contenha uma visualização que precise do tipo de dados que você quer usar durante o teste. O app de amostra android-AutofillFramework fornece à IU visualizações que esperam vários tipos de dados, como números de cartão de crédito e nomes de usuários.
- Toque na visualização que contém o tipo de dados que você precisa.
- Digite um valor na visualização.
Toque no botão de confirmação, como Fazer login ou Enviar.
Geralmente, você precisa enviar o formulário antes que o serviço tente salvar os dados.
O sistema exibe uma caixa de diálogo solicitando sua permissão para salvar os dados. A caixa de diálogo mostra o nome do serviço que está ativo no momento.
Verifique se esse é o serviço que você quer usar no seu teste e toque em Salvar.
Se o Android não exibir a caixa de diálogo de permissão ou se o serviço não for o que você quer usar no teste, verifique se o serviço está ativo nas configurações do sistema.
Acionar o preenchimento automático no seu app
As etapas a seguir mostram como acionar o preenchimento automático no seu app:
- Abra seu app e acesse a atividade que tem as visualizações que você quer testar.
- Toque na visualização que precisa ser preenchida.
- O sistema deve exibir a IU de preenchimento automático, que contém os conjuntos de dados que podem preencher a visualização, como mostrado na Figura 1.
- Toque no conjunto que contém os dados que você quer usar. A visualização precisa exibir os dados armazenados anteriormente no serviço.

Se o Android não exibir a UI de preenchimento automático, tente as seguintes opções de solução de problemas:
- Verifique se as visualizações no seu app usam o valor correto no atributo
android:autofillHints
. Para ver uma lista de valores possíveis para o atributo, consulte as constantes prefixadas comAUTOFILL_HINT
na classeView
. - Verifique se o atributo
android:importantForAutofill
está definido como um valor diferente deno
na visualização que precisa ser preenchida, ou configure com um valor diferente denoExcludeDescendants
na visualização ou em um dos pais dela.