Que classe de tecnologia o código Android deve abrir para uma dada tag?
O nível mais alto que resolve o trabalho. Ndef lê e grava conteúdo em qualquer tipo do NFC Forum, NdefFormatable prepara uma tag virgem, IsoDep carrega APDU, e NfcA ou NfcV enviam comandos brutos quando o conteúdo não basta. Confira getTechList primeiro: três classes são opcionais e nunca aparecem em alguns celulares.
O que getTechList enumera
Toda tag descoberta vem com um objeto Tag, e o getTechList() dele nomeia as classes que o seu código pode abrir nela. Uma tag em geral enumera várias de uma vez: a referência de MifareUltralight observa que NfcA é enumerada ao lado dela em todos os casos, já que toda tag dessas também é uma tag NFC-A.
| Classe | O que ela dá ao seu código | Exigida em todo celular |
|---|---|---|
Ndef | Leitura e gravação NDEF nos tipos 1 a 4 do NFC Forum | Sim |
NdefFormatable | Formatar uma tag virgem e gravar uma primeira mensagem | Só para as tags que o celular consegue formatar |
NfcA, NfcB, NfcF, NfcV | Comandos brutos no nível de rádio de cada tecnologia | Sim |
IsoDep | APDU sobre ISO/IEC 14443-4 | Sim |
MifareClassic | Acesso a setores depois de uma autenticação por chave | Não |
MifareUltralight | Leituras e gravações de páginas | Não |
NfcBarcode | Tags que guardam só um código de barras | Não |
A lista fica fixada na descoberta. A referência de TagTechnology separa cada classe em leitores em cache, que descrevem a tag como ela era quando entrou no campo e nunca se atualizam, e operações de entrada e saída, que falam com a tag e podem ser bloqueantes.
O nível mais alto que resolve
Ndef esconde as diferenças entre os tipos de tag: as mesmas chamadas leem e gravam um adesivo Tipo 2 e um cartão Tipo 4. O código escrito contra ela continua funcionando quando o fornecedor troca de chip.
As classes brutas tiram essa proteção. NfcA.transceive() envia os seus bytes como eles são, o controlador acrescentando só o CRC, então o conjunto de comandos e o mapa de memória passam a ser problema seu, e os dois diferem de um chip para o outro. Eles são definidos na ficha técnica de cada chip, que este site deixa para o wakdev.com.
IsoDep fica entre as duas. Ela carrega APDU até cartões e até tags Tipo 4, e a referência de IsoDep diz que ela mesma fragmenta e remonta as trocas longas, então o seu código envia comandos inteiros.
NdefFormatable serve a um momento da vida de uma tag. A referência dela reconhece que os procedimentos para formatar uma tag não são especificados pelo NFC Forum nem são amplamente conhecidos, e é por isso que a classe aparece só nas tags que um dado celular sabe formatar.
Uma ligação de cada vez
Uma tag aceita uma classe aberta de cada vez. A referência diz isso com todas as letras, e um segundo connect() falha com IOException, então um código que abre Ndef para ler e depois NfcA para consultar o chip tem de fechar a primeira antes de abrir a segunda.
Toda chamada que toca no rádio é bloqueante e tem de ficar fora da thread principal. close() é a saída de uma chamada bloqueante: feita de outra thread, ela cancela a operação pendente com IOException.
Um objeto Tag também está preso a uma aparição. A referência de Tag diz que um objeto novo é criado toda vez que a tag entra no alcance, mesmo para a mesma tag física, e que só o mais recente consegue abrir uma classe. Usar um mais antigo depois que a tag dele saiu levanta SecurityException.
Classes que um celular pode não oferecer
Três classes são opcionais, e a ausência delas é silenciosa. Um celular que não implementa MifareClassic nunca a enumera, então o mesmo cartão declara a classe num celular e não declara no outro, e um código que a presumiu falha só em campo.
Ndef em si só é garantida nos tipos 1 a 4 do NFC Forum. A referência de Ndef trata os formatos de fabricante, o NDEF guardado em MIFARE Classic incluído, como melhor esforço, e recomenda por isso os tipos do NFC Forum para instalações novas.
Então teste a classe, e não o modelo do celular. A lista que a tag em mãos declara é a única resposta que continua valendo no celular seguinte.
Perguntas frequentes
Dá para abrir Ndef e NfcA na mesma tag de uma vez?
Não. Só uma classe pode estar ligada a uma tag de cada vez, então feche a primeira antes de ligar a segunda.
Por que NdefFormatable falta numa tag virgem?
O celular não sabe formatar aquela tag. A referência diz que a classe é enumerada só para as tags que o aparelho consegue formatar, e que nenhum conjunto de tags é obrigatório.
Por que getCachedNdefMessage ainda mostra o conteúdo antigo depois de uma gravação?
Ele devolve a mensagem lida quando a tag entrou no campo e nunca se atualiza. Leia o conteúdo atual com getNdefMessage, que fala com a tag.
Um código novo deve usar MifareClassic?
Só para ler cartões MIFARE Classic que já existem, e com uma reserva para os celulares que não a têm. A classe é opcional, e a referência de Ndef recomenda os tipos do NFC Forum para instalações novas.