Este documento presenta conceptos clave sobre programación de aplicaciones NFC en Android. Explica el formato NDEF para intercambio de datos NFC, incluyendo mensajes, registros y banderas. También describe la API de Android NFC, incluyendo clases como NfcManager, NfcAdapter, NdefMessage y NdefRecord. Por último, cubre temas como el sistema de despacho de etiquetas, filtros de intenciones y operaciones de entrada/salida.
2. Índice – día 2
Características de los mensajes NFC
– NDEF (NFC Data Exchange Format)
– NFC RTD (NFC Record Type Definition)
Android NFC API
– Android Manifest
– Paquete android.nfc
– Tag Dispatch System
– NFC Intents
– NDEF Record Types
Práctica 1
3. NDEF
¿Qué es?
– Especificación que define el formato de
encapsulamiento de mensajes para el intercambio
de información en un enlace NFC.
– Un mensaje NDEF es un mensaje binario:
• ligero
• encapsula varios registros
4. NDEF Message / NDEF Record
Un mensaje NDEF contiene uno o varios registros:
5. NDEF Record Flags
MB (Message Begin): Indica que es el primer NDEF record del
mensaje.
ME (Message End): Indica que es el último NDEF record del
mensaje.
CF (Chunk Flag): Indica que la información se encapsula en
varios NDEF records. Todos los records menos el
último deben llevar este flag activado.
SR (Short Record): Se utiliza para indicar que la longitud del
payload es un octeto (tamaño de payload menor de
255 bytes). Implica la ausencia de PAYLOAD
LENGTH 3, 2, 1
IL (ID Length): Este flag a uno indica que la se incluye un
campo de tamaño de ID en la cabecera. Su
ausencia implica la no existencia del campo ID
LENGTH y del campo ID
7. Record Type Definition (RTD)
Tipos de registros reconocidos por el NFC Forum,
que pueden ser incluidos en los mensajes NDEF.
Son los tipos well-known type (TNF=0x01)
– Texto
– URI
– SmartPoster
– Control genérico
– Firma digital
Formato URN [RFC 2141]
– urn:nfc:wkt:Sp
8. NDEF Fields
TYPE LENGTH: Número de octetos
dentro de TYPE.
PAYLOAD LENGTH (0-3): Número
de octetos dentro del
PAYLOAD.
ID LENTGH: Número de octetos
dentro de ID.
TYPE: Identifica el tipo de datos
dentro de PAYLOAD.
9. NDEF Fields
ID:
Identificador en forma de
URI. Sólo el primer registro
lleva ID
PAYLOAD:
La estructura interna del
payload es transparente
para NDEF
Terminator TLV opcional:
0xFE
18. Ejemplo NDEF MIME vCard (III)
Analisis del payload :
12 bytes mime-type: text/x-vCard
Resto binario del archivo: BEGIN:VCARD.VERSION:2.1.
FN:Xabier Losada.
TEL;CELL;VOICE: (666) 666-666.
END:VCARD
19.
20. Android NFC
Primer paso en la versión 2.3 API Level 9
Gran paso en la 2.3.3 API Level 10
Google Wallet
Beam API Level 14
Nuevas features en API Level 16
22. Paquete android.nfc: NfcManager
Gestor de alto nivel que se usa para obtener una instancia de
NfcAdapter:
NfcManager nm = getSystemService(NFC_SERVICE);
NfcAdapter na = nm.getDefaultAdapter();
Alternativa getDefaultAdapter(android.content.Context):
NfcAdapter na = NfcManager.getDefaultAdapter(this);
23. Paquete android.nfc: NfcAdapter
Representa la interfaz con el CLF
Métodos principales:
– disableForegroundDispatch(Activity activity):
• Desactiva el foreground dispatch a la activity que pasamos como parámetro.
– enableForegroundDispatch(Activity activity, PendingIntent intent,
IntentFilter[] filters, String[][] techLists):
• Activa el foreground dispatch a la activity que pasamos como parámetro.
– getDefaultAdapter(Context context):
• Permite obtener una instancia del adaptador NFC por defecto
– isEnabled():
• Devuelve true si la conectividad NFC está habilitada
24. Paquete android.nfc: NdefMessage
Constructores:
– NdefMessage(byte[] data)
• Construye un mensaje NDEF a partir de raw bytes.
– NdefMessage(NdefRecord[] records)
y
NdefMessage(NdefRecord record, NdefRecord... records)
(API level16)
• Construye un mensaje NDEF formado por los registros
NDEF que pasamos como parámetro.
25. Paquete android.nfc: NdefMessage
Métodos principales:
– getRecords()
• Obtenemos el array de NDEF records presentes en el
mensaje.
– toByteArray()
• Devuelve el mensaje en raw bytes.
– getByteArrayLength() (API level 16)
• Devuelve la longitud en bytes del mensaje NDEF si se
pasara a formato raw bytes.
26. Paquete android.nfc: NdefRecord
Constructor:
– NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload)
• Construye un registro NDEF a partir de los parámetros que le pasamos.
Métodos principales:
– getId()
– getPayload()
– getTnf()
– getType()
– toMimeType() (API level 16)
• Mapea el registro a un MIME type, o devuelve null en caso de que no pueda.
– toUri() (API level 16)
• Mapea el registro a una URI, o devuelve null en caso de que no pueda.
31. OBTENIENDO INFORMACIÓN DE LOS INTENTS
EXTRA_TAG (obligatorio): Un objeto Tag
representando el tag escaneado.
EXTRA_NDEF_MESSAGES (opcional): Un array
de mensajes NDEF del TAG. Si es un
NDEF_DISCOVERED es obligatorio.
EXTRA_ID (opcional): Identificador a bajo nivel
del tag (UID).
33. NDEF Programáticamente: RTD_URI
NdefRecord uriRecord = new NdefRecord(
NdefRecord.TNF_ABSOLUTE_URI ,
"http://developer.android.com/index.html".getBytes(Charset.forName(
"US- ASCII")),
new byte[0], new byte[0]);
34. NDEF Programáticamente: MIME
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA ,
"application/com.example.android.beam".getBytes(
Charset.forName("US-ASCII")
),
new byte[0],
"Beam me up, Android!".getBytes(Charset.forName(
"US-ASCII "
))
);
35. Operaciones I/O
La mayoría son bloqueantes, por lo que no
pueden (MUST desde API level 14) ser
llamadas desde el hilo principal
Leer, escribir, formatear,…
36. Foreground Dispatcher
1. Creamos un PendingIntent que se utilizará cuando se escanee un tag:
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
2. Declarar un filtro de Intents que queremos procesar (Null = todos. Fallback TAG_DISCOVERED)
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
You should specify only the ones that you need. */
}
catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
intentFiltersArray = new IntentFilter[] {ndef, };
3. Creamos un filtro de tecnologías con las que trabajar:
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
37. Foreground Dispatcher
4. Override de los métodos del ciclo de vide de la activity
public void onPause() {
super.onPause();
mAdapter.disableForegroundDispatch(this);
}
public void onResume() {
super.onResume();
mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
}
public void onNewIntent(Intent intent) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//do something with tagFromIntent
}
38. Práctica I
Elaborar una aplicación que:
- Detecte la presencia de Tags
- Permita leer mensajes NDEF