Está en la página 1de 4

Leer un tag NFC

La lectura de un tag NFC se realiza una vez se ha decidido qué actividad se hace cargo del mismo. El
tag y su contenido se proveen a la actividad en la intención, que contiene también la acción que
permite determinar qué tipo de mensaje contiene el tag; basta con comprobar el valor de la acción de
la intención para saber qué método utilizar para descifrar el o los mensajes.

if(intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
Log.d(TAG,"Lectura de un tag NDEF");
else
if(intent.getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED))
Log.d(TAG,"Lectura de un tag TECH");

Veremos con detalle la lectura de los distintos tipos de mensajes NDEF.

1. Determinar el contenido de un tag NDEF


En el caso de un tag que contenga mensajes NDEF, la lectura se lleva a cabo recuperando en forma
de ParcelableArrayExtra el valor parseable con
nombre Nf cAdapter.EXTRA_NDEF_MESSAGES contenido en la intención y, a continuación,
convirtiendo cada elemento de la tabla en un objeto de tipo NdefMessage(no hay que olvidar que un
tag NDEF puede contener varios mensajes con formato NDEF).

Parcelable[] parcelableNedfMessages =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

if(parcelableNedfMessages==null)
return;

NdefMessage[] messages =
new NdefMessage[parcelableNedfMessages.length];

for(int i =0;i<parcelableNedfMessages.length;i++)
messages[i] = (NdefMessage)parcelableNedfMessages[i];

Cada Nde fMessageque se extrae contiene uno o varios NdefRecord, que son las entidades que
contienen los mensajes propiamente dichos.

En cada objeto Nd efRecord, el mensaje se almacena como una tabla de bytes, llamada Payload, a
la que se accede mediante el método ge tPayload()del objeto NdefRecord. Es preciso convertir
estos datos en función del formato del registro NdefRecord. Para ello, el
objeto NdefRecordexpone los métodos: getTnf(), que devuelve el formato del NdefRecord,
yg etType(), que devuelve el subtipo en el caso de que el tipo
de Nde fRecordsea TNF_WELL_KNOWN.
La API 16 de Android presenta varios métodos para la clase NdefRecord, que facilitan la lectura e
interpretación de los registros. Veremos cómo leer el contenido de registros NdefRecord mediante
estos métodos, y cómo reemplazar estos métodos cuando la aplicación está preparada para una API
anterior.

2. Leer una URI


La API 16 de Android provee el método toUri()que permite extraer una URI de un NdefRecord.

Uri tagUri= ndefRecord.toUri();


En las versiones anteriores de Android es preciso hacer referencia a las especificaciones del formato
de los registros NdefRecord, disponibles en la siguiente dirección: http://www.nfc-forum.org/specs/
Estas especificaciones indican que la codificación sigue las siguientes reglas:

El payload es una tabla de bytes.

El primer byte (pay load[0]) contiene un indicador que define el protocolo de la URI. Este
formato se utiliza para aumentar la memoria disponible para el detalle de la URI, ahorrando
así el espacio necesario para escribir el protocolo.

El resto del payload constituye la URI propiamente dicha, codificada en UTF-8.

El protocolo puede decodificarse según las correspondencias dadas en la tabla siguiente (extracto):

Decimal Hex Protocolo

0 0x00 N/A. No prepending is done, and the URI field contains the
unabridged URI.

1 0x01 http://www.

2 0x02 https://www.

3 0x03 http://

4 0x04 https://

5 0x05 tel:

6 0x06 mailto:

7 0x07 ftp://anonymous:anonymous@

8 0x08 ftp://ftp.

9 0x09 ftps://

… … …

Codificación del prefijo de la URI (extraído de NFC Forum)

La extracción de una URI se realiza de la siguiente manera:

private Uri readUri(byte[] payload) {


String[] protocolo = new String[] {
"http://www.",
"https://www.",
"http://",
"https://",
"tel:",
"mailto:",
"ftp://anonymous:anonymous@",
"ftp://ftp.",
"ftps://"
[...] // Todos los protocolos.
};

if(payload.length<2)
return null;

int prefijoIndice = (payload[0] & (byte)0xFF);

if (prefijoIndice < 0 || prefijoIndice >= protocolo.length)


return null;

String prefijo = protocolo[prefijoIndice];


String sufijo = null;
try {
sufijo = new String(Arrays.copyOfRange(payload, 1,
payload.length),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return Uri.parse(prefijo + sufijo);
}

El método se invoca de la siguiente manera:

Uri miURI = readUri(ndefRecord.getPayload());

3. Leer una cadena de caracteres


En el caso de un Ndef Record cuyo subtipo sea RTD_TEXT, los primeros bytes del payload
contienen información acerca de la codificación del contenido.

Un primer elemento define la codificación, UTF-8 o UTF-16, así como la longitud del código que
le sigue.

El siguiente elemento define el código del lenguaje utilizado.

La extracción del texto del registro consiste, por tanto, en determinar la codificación de la cadena de
caracteres "útiles" de payload y, a continuación, transcribir la tabla de bytes como una cadena de
caracteres en función de su codificación.

private String readText(byte[] payload) throws


UnsupportedEncodingException {

String formatoCodificacion =
((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";

int longitudCodigoLenguaje = payload[0] & 0077;

String codigoLenguaje =
new String(payload, 1, longitudCodigoLenguaje, "US-ASCII");

return new String(payload,


longitudCodigoLenguaje + 1,
payload.length - longitudCodigoLenguaje - 1,
formatoCodificacion);
}

4. Leer un tipo MIME


La lectura de un registro de tipo TNF_ MIME_MEDIA es muy sencilla, pues existen métodos
fuertemente tipados disponibles desde la versión 9 de Android.

Un tag de tipo TNF_MIME_MEDIA incluye dos campos: el tipo MIME, que debe leerse mediante el
método ge tType()del objeto NdefRecord, y un contenido (value), al que se accede mediante el
método ge tValue().

private void readMimeTypeTag(NdefRecord record) {


String mimeType=new String(record.getType());
String value =new String(record.getPayload());
}

5. Leer un tag de tipo TNF_WELL_KNOWN


Android trata los tags de tipo TNF_WELL_KNOWNdel mismo modo que los tags de tipo equivalente:
si el subtipo del tag TNF _WELL_KNOWN es RTD_URI, el tag se leerá como un tag de
tipo TNF_ABSOLUTE_URI.
El método ge tType()del objeto NdefRecord devuelve el subtipo del tag, tal y como se indica en la
siguiente tabla:

Subtipo (RTD) Descripción

RTD_SMART_POSTER Registro de tipo URI, basado en el análisis del payload.

RTD_TEXT Registro de tipo MIME de valor text/plain.

RTD_URI URI.

Basta, entonces, con determinar el subtipo del tag TNF_WELL_KNOWN, y procesar el payload del tag
en función del subtipo.

if(record.getType()==NdefRecord.RTD_TEXT) {
//... tratar el payload como para leer una cadena de
caracteres
}
else if (record.getType()==NdefRecord.RTD_URI) {
//... tratar el payload como para leer una URI
}

También podría gustarte