Ir para o conteúdo
Idioma: PT

Por que um leitor alcança outro aplicativo em vez do seu?

Porque outro serviço registrou o mesmo identificador, e o Android resolve o conflito antes de o seu código rodar: o aplicativo de carteira padrão ganha, depois um serviço registrado único, e senão o usuário é quem decide. Uma atividade em primeiro plano consegue passar por cima do resultado com setPreferredService.

A tabela de encaminhamento decide primeiro

O controlador NFC guarda uma tabela de encaminhamento: uma lista finita de regras, cada uma associando um identificador a um destino, o processador do host onde os aplicativos rodam ou um elemento seguro conectado. Quando um leitor envia um SELECT, o controlador casa o identificador e manda esse comando e cada comando depois dele para esse destino, até outro SELECT chegar ou o enlace se romper. O guia da emulação de cartão do Android descreve a tabela e diz que os aplicativos nunca a configuram; a plataforma a constrói a partir dos serviços instalados e do que o usuário escolheu.

Duas consequências se seguem. As correspondências parciais, que a ISO/IEC 7816-4 permite, não são suportadas pela emulação de cartão pelo host do Android, então um identificador casa inteiro ou não casa. E a tabela tem um tamanho, ainda que o guia exija dos aparelhos que encaminhem ao host os identificadores que o seu aplicativo registrou.

Como o Android resolve um conflito

Vários serviços conseguem registrar o mesmo identificador, e o guia dá a ordem. O aplicativo de carteira padrão ganha se registrou o identificador. Na falta dele, o serviço único que o registrou é invocado. Se mais de um registrou, o Android pergunta ao usuário qual usar.

A categoria de pagamento estreita isso ainda mais. Só um grupo de pagamento fica ativado no aparelho de cada vez, e um aplicativo que registra identificadores de pagamento só faz transação como titular do papel de carteira, a partir do Android 15, ou a partir do primeiro plano. Um esquema que funciona num só comerciante pertence à outra categoria, cujos grupos conseguem ficar ativos o tempo todo e que não disputa essa vaga única.

Um aplicativo consegue pedir o papel em vez de torcer por ele: RoleManager.ROLE_WALLET com createRequestRoleIntent, e isRoleHeld para saber como está a situação.

O que uma atividade em primeiro plano muda

setPreferredService nomeia o serviço a preferir enquanto uma atividade está retomada, e ele passa por cima da resolução acima. A referência do CardEmulation o pede em onResume e pede unsetPreferredService em onPause, já que o sistema não guarda a preferência: ela tem de ser posta de novo toda vez que a atividade é retomada.

A chamada falha em dois casos, os dois sobre pagamento. Se o serviço registra identificadores de pagamento e o usuário não permite que aplicativos em primeiro plano passem por cima do serviço de pagamento padrão. E se ele registra identificadores na outra categoria que o serviço de pagamento padrão também trata, sob a mesma escolha do usuário. categoryAllowsForegroundPreference responde antes de você tentar.

O que conferir quando um toque vai parar em outro lugar

Pergunte à plataforma o que ela acha. isDefaultServiceForCategory responde por uma categoria, mas a referência avisa que ele sempre devolve falso quando o modo de seleção é perguntar sempre ou perguntar se houver conflito; nesses modos, isDefaultServiceForAid é a pergunta que faz sentido. getSelectionModeForCategory diz a você em que modo está.

Depois olhe para fora do seu aplicativo. Outro aplicativo instalado pode registrar o mesmo identificador, e um serviço fora do host pode reivindicá-lo para um elemento seguro, caso em que a troca nunca chega a código algum no host. Ler os identificadores que o seu serviço registrou, e compará-los com o que o leitor seleciona, resolve a maior parte disso mais rápido do que raciocinar a respeito: a página das APDU cobre o próprio SELECT.

Perguntas frequentes

Quem ganha quando dois aplicativos registram o mesmo identificador?

O aplicativo de carteira padrão, se ele o registrou. Senão o serviço único que registrou, e se vários registraram, o Android pergunta ao usuário.

Por que setPreferredService devolve falso?

O serviço registra identificadores de pagamento, ou identificadores que o serviço de pagamento padrão também trata, e o usuário não permitiu que aplicativos em primeiro plano passem por cima desse serviço.

O Android casa parte de um identificador?

Não. As correspondências parciais existem na ISO/IEC 7816-4 mas a emulação de cartão pelo host do Android não as suporta.

Como um aplicativo vira a carteira padrão?

Pedindo o papel de carteira com RoleManager.createRequestRoleIntent, e conferindo com isRoleHeld. O usuário é quem concede.