Saltar al contenido
Idioma: ES

¿Qué límites del controlador debe comprobar el código Android?

Todo lo que la referencia expone como un descriptor y no como una constante: la longitud máxima de un intercambio, la compatibilidad con las APDU extendidas, el plazo de espera, y qué clases opcionales aparecen siquiera. Dos teléfonos con la misma versión de Android responden distinto, así que el código lee estos valores en la etiqueta que tiene delante.

Cuánto lleva un solo comando

getMaxTransceiveLength(), en NfcA, NfcV o IsoDep, devuelve el mayor número de bytes que puede enviar una sola llamada a transceive(). Depende del controlador del teléfono, y la referencia no da ningún valor que dar por supuesto.

Las APDU añaden un segundo límite. La referencia de IsoDep explica que una APDU normal lleva como mucho 255 bytes de carga, 261 bytes en total, mientras que una APDU de longitud extendida llega a 65535, y que algunos adaptadores no admiten la forma extendida. isExtendedLengthApduSupported() responde por el teléfono que tienes delante.

Una tarjeta que espera APDU extendidas funciona por tanto en un teléfono y falla en otro con el mismo código. Donde la tarjeta acepte también la forma normal, recae en ella en lugar de dar por supuesta la compatibilidad.

Cuánto espera el teléfono

setTimeout() en NfcA o IsoDep fija cuánto espera transceive() una respuesta. La referencia de NfcA sugiere un valor más largo para las operaciones que le llevan tiempo a la etiqueta, como generar una clave, y señala que el valor vuelve al de partida cuando se cierra la conexión.

El valor de partida no está documentado. Léelo con getTimeout() en lugar de fijar en el código la cifra medida en un teléfono, y vuelve a poner el tuyo después de cada connect().

Qué clases existen

Las clases opcionales son la otra variable. MifareClassic, MifareUltralight y NfcBarcode pueden faltar por completo en un teléfono, y NdefFormatable aparece solo para las etiquetas que el teléfono sabe formatear.

La única prueba fiable es getTechList() en la etiqueta que tienes delante, ya que la ausencia es silenciosa. La página de las clases de tecnología cubre lo que da cada una.

Lo que apagan quien usa el teléfono y el sistema

getDefaultAdapter() devuelve null cuando el teléfono no tiene controlador NFC, y isEnabled() devuelve false cuando alguien ha apagado el NFC. La referencia de NfcAdapter sugiere llevar a los ajustes con Settings.ACTION_NFC_SETTINGS en el segundo caso.

Desde Android 16 también se pueden rechazar los intents de etiqueta para una sola aplicación, lo que declara isTagIntentAllowed(). El adaptador está encendido, la aplicación está instalada, y las etiquetas siguen sin llegar, así que vale la pena mirarlo antes de ponerse a buscar el fallo.

Desde el nivel de API 34, getNfcAntennaInfo() devuelve lo que el teléfono sabe de sus antenas, incluida su posición respecto al aparato, y puede devolver null. Donde responde, una aplicación puede enseñar dónde poner la etiqueta en lugar de describirlo con palabras.

Preguntas frecuentes

¿Qué longitud de intercambio se puede dar por segura?

Ninguna. Lee getMaxTransceiveLength en la tecnología conectada y parte los comandos para que quepan.

¿Por qué una APDU funciona en un teléfono y falla en otro?

Puede que use la forma de longitud extendida, que algunos adaptadores no admiten. Mira isExtendedLengthApduSupported y recae en APDU normales donde la tarjeta lo permita.

¿Un plazo fijado con setTimeout se conserva?

No. La referencia dice que vuelve al valor de partida cuando se cierra la conexión, así que vuelve a ponerlo después de cada connect.

¿Puede una aplicación saber dónde está la antena NFC?

Desde el nivel de API 34, getNfcAntennaInfo devuelve información de las antenas, incluida su posición relativa, cuando el teléfono la ofrece. Puede devolver null, así que la aplicación necesita un plan alterno.