Near Field Communication (Comunicación en área próxima)

Los dispositivos BlackBerry que vienen equipados con un transmisor Near Field Communication (NFC) permiten a una aplicación interactuar con etiquetas inteligentes, accesorios inteligentes y otros dispositivos con tecnología NFC. Las etiquetas inteligentes contienen normalmente pequeñas cantidades de datos que describen un objeto en el mundo o se refieren a otro canal de datos en el que los usuarios pueden obtener más información.

Por ejemplo, un altavoz Bluetooth® podría tener una etiqueta inteligente incorporada que contuviera la información de emparejamiento . Una aplicación de reproducción multimedia que detecte las etiquetas inteligentes podría iniciar el emparejamiento y, a continuación, enrutar la salida de audio del dispositivo BlackBerry a los altavoces .

La tecnología NFC está diseñada para transferir pequeñas cantidades de datos en distancias cortas. A continuación le mostramos algunos ejemplos de lo que puede hacer con las etiquetas inteligentes:

  • Proporcionar una dirección Web desde la que el usuario del dispositivo BlackBerry puede recuperar más información sobre un anuncio de un póster inteligente, como una película o un cupón
  • Proporcionar información de emparejamiento para un accesorio
  • Proporcionar información de identificación para una base inteligente

Puede utilizar la API de NFC para leer y redactar etiquetas inteligentes con formato según la especificación técnica de NDEF. Las clases e interfaces de los paquetes net.rim.device.api.io.nfc.readerwriter y net.rim.device.api.io.nfc.ndef le permiten leer y redactar etiquetas inteligentes con formato NDEF. La tecnología NFC es compatible con los tipos de 1 a 4 NDEF. También puede comunicarse con etiquetas inteligentes ISO14443 utilizando las clases e interfaces del paquete net.rim.device.api.io.nfc.readerwriter.

La API de NFC también le permite emular una etiqueta inteligente. Puede utilizar las clases e interfaces del paquete net.rim.device.api.io.nfc.emulation para crear una etiqueta virtual de tipo 4 NDEF o una etiqueta virtual ISO14443-4.

Trabajo con etiquetas inteligentes

La característica NFC de un dispositivo BlackBerry se activa normalmente cuando el usuario de un dispositivo BlackBerry toca una etiqueta inteligente. Si ha registrado un servicio de escucha que coincide con la configuración de la etiqueta inteligente que toca el usuario, el dispositivo puede notificarle a su aplicación que hay una etiqueta disponible.

Puede implementar la interfaz net.rim.device.api.io.nfc.ndef.NDEFMessageListener para recibir mensajes de una etiqueta inteligente configurada según las especificaciones técnicas de NDEF. El dispositivo BlackBerry proporciona un objeto NDEFMessage que contiene los datos de una etiqueta inteligente a NDEFMessageListener. Las aplicaciones que registran un objeto NDEFMessageListener pueden restringir la Definición de Tipo de Registro (RTD) y el tipo de registro que activan la aplicación.

Puede implementar la interfaz net.rim.device.api.io.nfc.readerwriter.DetectionListener para permitir que su aplicación reciba notificaciones de una conexión a cualquier etiqueta inteligente que se ajuste al estándar ISO14443. Cuando se invoca, DetectionListener recibe un objeto Target que contiene el URI necesario para abrir una conexión con la etiqueta.

Cuando se detecta una etiqueta inteligente, el dispositivo se lo notifica a cualquier aplicación que registrara un servicio de escucha para ese tipo de etiqueta. Solamente un objeto DetectionListener puede acceder a una etiqueta inteligente al mismo tiempo cuando la etiqueta se encuentra dentro del alcance del transmisor NFC. Cuando DetectionListener termina con la etiqueta inteligente, otro DetectionListener puede abrir una conexión con la etiqueta inteligente si aún se encuentra dentro del alcance.

Etiquetas inteligentes compatibles con BlackBerry 7

Tipo de etiquetas de NFC Forum

Etiquetas compatibles

Tipo 1

  • Topaz 96
  • Topaz 512

Tipo 2

  • MiFare Ultra Light
  • MiFare Ultra Light C
  • Infineon my-D Move
  • Infineon my-D NFC

Tipo 3

FeliCa RC-S965

Tipo 4

MiFare DESFire EV1 (2k, 4k, 8k)

También puede comunicarse con etiquetas inteligentes utilizando protocolos de nivel inferior, como ISO14443-3 e ISO 14443-4. Para obtener más información acerca de cómo comunicarse con etiquetas inteligentes utilizando protocolos de nivel inferior, consulte la referencia de API para BlackBerry Java SDK y la documentación sobre la etiqueta facilitada por el fabricante.

Crear un redactor de etiquetas NDEF

  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.NFCException;
    import net.rim.device.api.io.nfc.ndef.NDEFMessage;
    import net.rim.device.api.io.nfc.ndef.NDEFRecord;
    import net.rim.device.api.io.nfc.ndef.NDEFTagConnection;
    import net.rim.device.api.io.nfc.readerwriter.*;
    import net.rim.device.api.ui.component.LabelField;
    import net.rim.device.api.ui.container.MainScreen;
    import net.rim.device.api.ui.Field;
    import net.rim.device.api.ui.UiApplication;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.lang.String;
    import javax.microedition.io.Connector;
  2. Declare la clase de su aplicación e iníciela.
    public class NDEFWriterDemo extends UiApplication
    {
        public static void main(String[] args)
        {
            new NDEFWriterDemo().enterEventDispatcher();
        }
  3. En el constructor de su aplicación, cree un objeto NDEFWriterScreen para representar la pantalla de estado de su aplicación y cree una nueva instancia de su implementación de la interfaz DetectionListener. Cree la clase NDEFWriterScreen en el paso 25. Implemente DetectionListener en el paso 10.
        public NDEFWriterDemo()
        {
            NDEFWriterScreen screen = new NDEFWriterScreen();
            NDEFWriterListener listener = new NDEFWriterListener(screen);
  4. Invoque registerListener() para registrar la implementación de DetectionListener. Cree registerListener() en el paso 6.
            registerListener(listener);
  5. Agregue su objeto NDEFWriterScreen a la pila de visualización.
            pushScreen(screen);
        }
  6. Cree registerListener().
        public void registerListener(NDEFWriterListener listener)
        {
  7. Recupere la instancia única de ReaderWriterManager.
            ReaderWriterManager nfc;
            try
            {
                nfc = ReaderWriterManager.getInstance();
  8. Registre su implementación de DetectionListener. Indique que desea escuchar el tipo de destino de la etiqueta NDEF.
                nfc.addDetectionListener(listener, new int[]{Target.NDEF_TAG});
                // Save your registration state in persistent storage.
            }
  9. Procese cualquier error que se produzca.
            catch (NFCException e)
            {
                // error handling code
            }
        }
  10. Declare su implementación de DetectionListener.
        private class NDEFWriterListener implements DetectionListener
        {
  11. Cree una variable de instancia para almacenar una referencia a la pantalla de estado. En el constructor, asigne un valor a esta variable.
            private NDEFWriterScreen display;
            public NDEFWriterListener(NDEFWriterScreen screen)
            {
                super();
                display = screen;
            }
  12. Implemente el método onTargetDetected().
            public void onTargetDetected(Target target)
            {
  13. Cree una variable para la conexión a la etiqueta inteligente.
                NDEFTagConnection c = null;
  14. Invoque display.message() para actualizar el mensaje en la pantalla de estado. Cree este método en el paso 27.
                display.message("Tag detected. Attempting to write data.");
  15. Cree un objeto NDEFMessage para escribir en la etiqueta inteligente.
                try
                {
                    NDEFMessage smartTag = createSmartTag();
  16. Abra una conexión con la etiqueta inteligente. Asigne la conexión mediante la interfaz NDEFTagConnection. Recupere la URI de la conexión invocando Target.getUri().
                    c = (NDEFTagConnection)Connector.open(
                    target.getUri(Target.NDEF_TAG));
                    c.write(smartTag);
  17. Actualice el mensaje en la pantalla de estado.
                    display.message("Successfully wrote to tag.");
                }
  18. Procese cualquier error que se produzca.
     catch (IOException e)
                {
                    display.message("Could not write to tag.");
                    // Process errors here.
                }
            }
  19. Cree createSmartTag() para definir el contenido para escribir en la etiqueta inteligente.
            private NDEFMessage createSmartTag() throws IOException 
            {
  20. Cree un registro NDEF para escribir en la etiqueta inteligente.
                NDEFRecord titleRec = new NDEFRecord();
                titleRec.setId("1");
                titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); 
                ByteArrayOutputStream payload1 = new ByteArrayOutputStream();
                payload1.write((byte) 0x05);             // Status byte - length of encoding
                payload1.write("en-US".getBytes("UTF-8"));      // Encoding
                payload1.write("My Title".getBytes("UTF-8"));   // Title
                payload1.flush();
                titleRec.setPayload(payload1.toByteArray());
  21. Cree un segundo registro NDEF para escribir en la etiqueta inteligente.
                NDEFRecord uriRec = new NDEFRecord();
                uriRec.setId("2");
                uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U");
                ByteArrayOutputStream payload2 = new ByteArrayOutputStream();
                payload2.write((byte) 0x01);                 // Abbreviation: http://www.
                payload2.write("blackberry.com".getBytes("UTF-8")); // URI
                payload2.flush();
                uriRec.setPayload(payload2.toByteArray());
  22. Cree un objeto NDEFMessage y complételo con los registros NDEF.
                NDEFMessage ndefMessage = new NDEFMessage();
                ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec});
  23. Defina el objeto NDEFMessage para que sea el primer mensaje en la etiqueta inteligente.
                NDEFMessage rootMessage = new NDEFMessage();
                byte[] rootPayload = ndefMessage.getBytes();
                NDEFRecord rootRec = new NDEFRecord();
                rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp");
                rootRec.setPayload(rootPayload);
                rootMessage.setRecords(new NDEFRecord[] {rootRec});
  24. Devuelva NDEFMessage al método de invocación.
                return rootMessage;
            }
        }
  25. Cree la clase NDEFWriterScreen y cree una variable de instancia para almacenar una referencia al objeto LabelField.
        private class NDEFWriterScreen extends MainScreen
        {
            private LabelField lbl;
    
  26. Cree un constructor para la pantalla de estado. Inicialice la etiqueta y agréguela a la pantalla.
            public NDEFWriterScreen()
            {
                lbl = new LabelField("Tap a smart tag to write data.", 
                                            Field.FIELD_HCENTER|Field.FIELD_VCENTER);
                add(lbl);
            }
    
  27. Cree message() para actualizar el texto de la etiqueta cuando se produzcan eventos relacionados con la etiqueta.
            public void message(String msg)
            {
                lbl.setText(msg);
            }
        }
    }

Ejemplo de código: creación de un redactor de etiquetas NDEF

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.String;
import javax.microedition.io.Connector;
import net.rim.device.api.io.nfc.NFCException;
import net.rim.device.api.io.nfc.ndef.NDEFMessage;
import net.rim.device.api.io.nfc.ndef.NDEFRecord;
import net.rim.device.api.io.nfc.ndef.NDEFTagConnection;
import net.rim.device.api.io.nfc.readerwriter.*;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
public class NDEFWriterDemo extends UiApplication
{
    public static void main(String[] args)
    {
        new NDEFWriterDemo().enterEventDispatcher();
    }
    public NDEFWriterDemo()
    {
        // Detect whether or not you
        // registered a listener already.
        // If not, then register a listener.
        NDEFWriterScreen screen = new NDEFWriterScreen();
        NDEFWriterListener listener = new NDEFWriterListener(screen);
        registerListener(listener);
        pushScreen(screen);
    }
    public void registerListener(NDEFWriterListener listener)
    {
        ReaderWriterManager nfc;
        try
        {
            nfc = ReaderWriterManager.getInstance();
            nfc.addDetectionListener(listener, new int[]{Target.NDEF_TAG});
            // Save your registration state in persistent storage.
        } catch (NFCException e)
        {
            // Process error here.
        }
    }
    private class NDEFWriterListener implements DetectionListener
    {
        private NDEFWriterScreen display;
        public NDEFWriterListener(NDEFWriterScreen screen)
        {
            super();
            display = screen;
        }
        public void onTargetDetected(Target target)
        {
            NDEFTagConnection c = null;
            display.message("Tag detected. Attempting to write data.");
            try
            {
                NDEFMessage smartTag = createSmartTag();
                c = (NDEFTagConnection)Connector.open(
                target.getUri(Target.NDEF_TAG));
                c.write(smartTag);
                display.message("Successfully wrote to tag.");
            } catch (IOException e)
            {
                display.message("Could not write to tag.");
                // Process error here.
            }
        }
        private NDEFMessage createSmartTag() throws IOException 
        {
            NDEFRecord titleRec = new NDEFRecord();
            titleRec.setId("1");
            titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); 
            ByteArrayOutputStream payload1 = new ByteArrayOutputStream();
            payload1.write((byte) 0x05);             // Status byte - length of encoding
            payload1.write("en-US".getBytes("UTF-8"));      // Encoding
            payload1.write("My Title".getBytes("UTF-8"));   // Title
            payload1.flush();
            titleRec.setPayload(payload1.toByteArray());
            NDEFRecord uriRec = new NDEFRecord();
            uriRec.setId("2");
            uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U");
            ByteArrayOutputStream payload2 = new ByteArrayOutputStream();
            payload2.write((byte) 0x01);                 // Abbreviation: http://www.
            payload2.write("blackberry.com".getBytes("UTF-8")); // URI
            payload2.flush();
            uriRec.setPayload(payload2.toByteArray());
            NDEFMessage ndefMessage = new NDEFMessage();
            ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec});
            // Root message with one record that has a nested 
            // message in the form of bytes.
            NDEFMessage rootMessage = new NDEFMessage();
            byte[] rootPayload = ndefMessage.getBytes();
            NDEFRecord rootRec = new NDEFRecord();
            rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp");
            rootRec.setPayload(rootPayload);
            rootMessage.setRecords(new NDEFRecord[] {rootRec});
            return rootMessage;
        }
    }
    private class NDEFWriterScreen extends MainScreen
    {
        private LabelField lbl;
        public NDEFWriterScreen()
        {
            lbl = new LabelField("Tap a smart tag to write data.", 
                                        Field.FIELD_HCENTER|Field.FIELD_VCENTER);
            add(lbl);
        }
        public void message(String msg)
        {
            lbl.setText(msg);
        }
    }
}

Crear un lector de etiquetas NDEF

  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.NFCException;
    import net.rim.device.api.io.nfc.readerwriter.*;
    import net.rim.device.api.io.nfc.ndef.*;
    import net.rim.device.api.ui.component.ButtonField;
    import net.rim.device.api.ui.component.Dialog;
    import net.rim.device.api.ui.component.LabelField;
    import net.rim.device.api.ui.container.MainScreen;
    import net.rim.device.api.ui.container.VerticalFieldManager;
    import net.rim.device.api.ui.Field;
    import net.rim.device.api.ui.FieldChangeListener;
    import net.rim.device.api.ui.UiApplication;
    import java.lang.String;
  2. Declare la clase de su aplicación e iníciela.
    public class NDEFReaderDemo extends UiApplication 
    {
        public static void main(String[] args)
        {
            new NDEFReaderDemo().enterEventDispatcher();
        }
  3. En el constructor de su aplicación, agregue una pantalla a la pila de visualización para permitir que el usuario de un dispositivo BlackBerry pueda interactuar con la aplicación. Creó esta pantalla en el paso 11.
        public NDEFReaderDemo()
        {
            pushScreen(new NDEFReaderScreen());
        }
  4. Cree registerListener().
        public void registerListener(NDEFReaderListener listener)
        {
  5. Recupere la instancia única de ReaderWriterManager.
            try
            {
                ReaderWriterManager nfc = ReaderWriterManager.getInstance();
  6. Registre su implementación de NDEFMessageListener. Indique que desea escuchar un póster inteligente.
                nfc.addNDEFMessageListener(listener, NDEFRecord.TNF_WELL_KNOWN, "Sp", true);
            }
  7. Procese cualquier error que se produzca.
            catch(NFCException e)
            {
                Dialog.alert(e.toString());
            }
        }
  8. Cree deregisterListener() para anular el registro del servicio de escucha.
        public void deregisterListener()
        {
            try
            {
                ReaderWriterManager nfc = ReaderWriterManager.getInstance();
                nfc.removeNDEFMessageListener(NDEFRecord.TNF_WELL_KNOWN, "Sp");
            } catch(NFCException e)
            {
                Dialog.alert(e.toString());
            }
        }
  9. Implemente la interfaz NDEFMessageListener. Cree una variable de instancia para almacenar una referencia a la pantalla. En el constructor, asigne un valor a esta variable.
        private class NDEFReaderListener implements NDEFMessageListener
        {
            private NDEFReaderScreen display;
            private NDEFReaderListener(NDEFReaderScreen screen)
            {
                super();
                display = screen;
            }
  10. Implemente onNDEFMessageDetected(). Pase los registros NDEF como un parámetro al constructor de la clase de pantalla.
            public void onNDEFMessageDetected(final NDEFMessage msg)
            {
                NDEFReaderDemo.this.invokeLater(new Runnable() {
                    public void run() {
                        display.displayRecs(msg.getRecords());
                    }
                });
            }
        }
  11. Cree la clase NDEFReaderScreen para mostrar los registros NDEF del póster inteligente. Cree variables de instancia para mantener las referencias a los objetos ButtonField en la pantalla.
        private class NDEFReaderScreen extends MainScreen implements FieldChangeListener
        {
            ButtonField btn1, btn2;
  12. En el constructor, cree sus propios botones y agréguelos a la pantalla.
            private NDEFReaderScreen()
            {
                btn1 = new ButtonField("Register Persistent Listener",Field.FIELD_HCENTER|Field.FIELD_VCENTER);
                btn1.setChangeListener(this);
                add(btn1);
                btn2 = new ButtonField("Deregister Persistent Listener",Field.FIELD_HCENTER|Field.FIELD_VCENTER);
                btn2.setChangeListener(this);
                add(btn2);
            }
  13. Cree displayRecs() para mostrar todos los registros que reciba de la etiqueta inteligente. Determine si alguno de los registros se ha pasado a este método.
            public void displayRecs(NDEFRecord[] records)
            {
                int numRecords = records.length;
                if (numRecords > 0)
                {
  14. Si existen registros NDEF, cree una matriz de objetos LabelField y agréguelos a un gestor de campo vertical. Agregue el gestor de campo vertical a la pantalla que contiene las etiquetas.
                    VerticalFieldManager vfm = new VerticalFieldManager();
                    LabelField lbl[] = new LabelField[numRecords];
                    for (int j = numRecords - 1; j >= 0; j--)
                    {
                        lbl[j] = new LabelField();
                        lbl[j].setText(new String(records[j].getPayload(),“UTF-8”));
                        vfm.add(lbl[j]);
                    }
                    add(vfm);
                }
  15. Si no se leyó ningún registro NDEF desde la etiqueta, agregue una etiqueta a la pantalla para informar al usuario.
                else
                {
                    LabelField lbl = new LabelField("This tag contains no records",
                                            Field.FIELD_HCENTER|Field.FIELD_VCENTER);
                    add(lbl);
                }
            }
    
  16. Implemente fieldChanged para responder cuando el usuario pulse los botones de la pantalla.
            public void fieldChanged(Field field, int context)
            {
                if (field == btn1)
                {
                    registerListener(new NDEFReaderListener(this));
                } else if (field == btn2)
                {
                    deregisterListener();
                }
            }
        }
    }

Ejemplo de código: creación de un lector de etiquetas NDEF

import net.rim.device.api.io.nfc.NFCException;
import net.rim.device.api.io.nfc.readerwriter.*;
import net.rim.device.api.io.nfc.ndef.*;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import java.lang.String;
public class NDEFReaderDemo extends UiApplication 
{
    public static void main(String[] args)
    {
        new NDEFReaderDemo().enterEventDispatcher();
    }
    public NDEFReaderDemo()
    {
        pushScreen(new NDEFReaderScreen());
    }
    public void registerListener(NDEFReaderListener listener)
    {
        try
        {
            ReaderWriterManager nfc = ReaderWriterManager.getInstance();
            nfc.addNDEFMessageListener(listener, NDEFRecord.TNF_WELL_KNOWN, "Sp", true);
            // Save your registration state in persistent storage.
        } catch(NFCException e)
        {
            Dialog.alert(e.toString());
        }
    }
    public void deregisterListener()
    {
        try
        {
            ReaderWriterManager nfc = ReaderWriterManager.getInstance();
            nfc.removeNDEFMessageListener(NDEFRecord.TNF_WELL_KNOWN, "Sp");
        } catch(NFCException e)
        {
            Dialog.alert(e.toString());
        }
    }
    private class NDEFReaderListener implements NDEFMessageListener
    {
        private NDEFReaderScreen display;
        private NDEFReaderListener(NDEFReaderScreen screen)
        {
            super();
            display = screen;
        }
        public void onNDEFMessageDetected(final NDEFMessage msg)
        {
            NDEFReaderDemo.this.invokeLater(new Runnable() {
                public void run() {
                    display.displayRecs(msg.getRecords());
                }
            });
        }
    }
    private class NDEFReaderScreen extends MainScreen implements FieldChangeListener
    {
        ButtonField btn1, btn2;
        private NDEFReaderScreen()
        {
            btn1 = new ButtonField("Register Persistent Listener",Field.FIELD_HCENTER|Field.FIELD_VCENTER);
            btn1.setChangeListener(this);
            add(btn1);
            btn2 = new ButtonField("Deregister Persistent Listener",Field.FIELD_HCENTER|Field.FIELD_VCENTER);
            btn2.setChangeListener(this);
            add(btn2);
        }
        public void displayRecs(NDEFRecord[] records)
        {
            int numRecords = records.length;
            if (numRecords > 0)
            {
                VerticalFieldManager vfm = new VerticalFieldManager();
                LabelField lbl[] = new LabelField[numRecords];
                for (int j = numRecords - 1; j >= 0; j--)
                {
                    lbl[j] = new LabelField();
                    lbl[j].setText(new String(records[j].getPayload()));
                    vfm.add(lbl[j]);
                }
                add(vfm);
            } else
            {
                LabelField lbl = new LabelField("This tag contains no records",
                                        Field.FIELD_HCENTER|Field.FIELD_VCENTER);
                add(lbl);
            }
        }
        public void fieldChanged(Field field, int context)
        {
            if (field == btn1)
            {
                registerListener(new NDEFReaderListener(this));
            } else if (field == btn2)
            {
                deregisterListener();
            }
        }
    }
}

Comunicarse con una etiqueta inteligente ISO14443

  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.NFCException;
    import net.rim.device.api.io.nfc.readerwriter.*;
    import net.rim.device.api.ui.component.LabelField;
    import net.rim.device.api.ui.container.MainScreen;
    import net.rim.device.api.ui.Field;
    import net.rim.device.api.ui.UiApplication;
    import java.io.IOException;
    import java.lang.String;
    import javax.microedition.io.Connector;
  2. Declare la clase de su aplicación e iníciela.
    public class ISO14443Demo extends UiApplication
    {
        public static void main(String[] args)
        {
            new ISO14443Demo().enterEventDispatcher();
        }
  3. En el constructor de su aplicación, invoque un método para registrar su implementación de DetectionListener.
        public ISO14443Demo()
        {
            registerListener();
        }
  4. Cree registerListener().
        public void registerListener()
        {
  5. Recupere la instancia única de ReaderWriterManager.
            ReaderWriterManager nfc;
            try
            {
                nfc = ReaderWriterManager.getInstance();
  6. Registre su implementación de DetectionListener.
                nfc.addDetectionListener(new ISO14443Listener());
            }
  7. Procese cualquier error que se produzca.
            catch (NFCException e)
            {
                // error handling code
            }
        }
  8. Declare su implementación de DetectionListener.
        private class ISO14443Listener implements DetectionListener
        {
  9. Implemente onTargetDetected(). Cree variables locales para almacenar las referencias a los siguientes recursos:
    • Conexión a la etiqueta inteligente
    • Comando para enviar a la etiqueta inteligente
    • Respuesta de la etiqueta inteligente
       public void onTargetDetected(Target target)
            {
                ISO14443Part3Connection c = null;
                // 0x30 - read command, 0x03 - starting from page 3
                byte[] ISO14443Command = {(byte) 0x30, (byte) 0x03};
                byte[] response = null;
  10. Invoque Connector.open() para abrir una conexión con la etiqueta inteligente. Asigne la conexión mediante la interfaz ISO14443Part3. Recupere la URI de la conexión invocando Target.getUri().
                try
                {
                    c = (ISO14443Part3Connection)Connector.open(
                    target.getUri(Target.ISO_14443_3));
  11. Envíe su comando a la etiqueta inteligente y recupere la respuesta.
                    response = c.transceive(ISO14443Command);
                }
  12. Procese cualquier error que se produzca.
                catch (IOException e)
                {
                    // error handling code
                    // make sure to set a non-null value for response
                }
  13. Agregue una pantalla a la pila de visualización para mostrar la respuesta de la etiqueta inteligente. Pase la variable response como un parámetro al constructor de la pantalla.
                pushScreen(new ISO14443DemoStatusScreen(response));
            }
        }
  14. Declare la clase de pantalla para mostrar los datos de la respuesta de la etiqueta inteligente. En el constructor, cree un objeto LabelField. Rellene la etiqueta con los datos de la respuesta de la etiqueta inteligente y agregue la etiqueta a la pantalla para mostrar los datos.
        private class ISO14443DemoStatusScreen extends MainScreen
        {
            public ISO14443DemoStatusScreen(byte[] response)
            {
                LabelField lbl = new LabelField(response, Field.FIELD_HCENTER);
                add(lbl);
            }
        }
    }

Ejemplo de código: comunicación con una etiqueta ISO 14443

import net.rim.device.api.io.nfc.NFCException;
import net.rim.device.api.io.nfc.readerwriter.*;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
import java.io.IOException;
import java.lang.String;
import javax.microedition.io.Connector;
public class ISO14443Demo extends UiApplication
{
    public static void main(String[] args)
    {
        new ISO14443Demo().enterEventDispatcher();
    }
    public ISO14443Demo()
    {
        // Detect whether or not you
        // registered a listener already.
        // If not, then register a listener.
        registerListener();
    }
    public void registerListener()
    {
        ReaderWriterManager nfc;
        try
        {
            nfc = ReaderWriterManager.getInstance();
            nfc.addDetectionListener(new ISO14443Listener());
            // Save your registration state in persistent storage.
        } catch (NFCException e)
        {
            // Process error condition.
        }
    }
    private class ISO14443Listener implements DetectionListener
    {
        public void onTargetDetected(Target target)
        {
            ISO14443Part3Connection c = null;
            // 0x30 - read command, 0x03 - starting from page 3
            byte[] ISO14443Command = {(byte) 0x30, (byte) 0x03};
            byte[] response = null;
            try
            {
                c = (ISO14443Part3Connection)Connector.open(
                target.getUri(Target.ISO_14443_3));
                response = c.transceive(ISO14443Command);
            } catch (IOException e)
            {
                // Process error condition.
                // Make sure to set a non-null value for response.
            }
            pushScreen(new ISO14443DemoStatusScreen(response));
        }
    }
    private class ISO14443DemoStatusScreen extends MainScreen
    {
        public ISO14443DemoStatusScreen(byte[] response)
        {
            LabelField lbl = new LabelField(response, Field.FIELD_HCENTER);
            add(lbl);
        }
    }
}

Emulación de etiquetas inteligentes

La API de NFC permite crear etiquetas inteligentes virtuales. Esta capacidad de crear etiquetas inteligentes de forma dinámica permite que la aplicación comparta pequeñas cantidades de datos entre los smartphones con tecnología NFC y los lectores de etiquetas. Algunos ejemplos de lo que puede hacer su aplicación utilizando una etiqueta virtual son:
  • Entradas sencillas para un evento
  • Intercambio de información de contacto
  • Identificación básica

Puede crear una etiqueta inteligente virtual que se ajuste al estándar de tipo 4 NDEF o ISO14443-4. Necesita los siguientes componentes para crear una etiqueta:

Componente

Descripción

Datos

Si crea una etiqueta virtual NDEF, es necesario que proporcione los datos de la etiqueta pasando un objeto NDEFMessage cuando crea una VirtualNDEFTag.

Para obtener una etiqueta virtual ISO14443-4, puede devolver datos de su implementación del método VirtualISO14443Part4TargetCallback.processCommand().

Objeto del objetivo virtual

Puede crear una instancia de las siguientes clases para controlar la emulación de etiquetas virtuales:

Interfaz de llamada

Si crea una etiqueta virtual NDEF, puede implementar la interfaz VirtualNDEFTagCallback para recibir notificaciones cuando un lector de etiquetas interactúe con la etiqueta inteligente virtual.

Si crea una etiqueta inteligente virtual ISO14443-4, puede interactuar con el lector de etiquetas implementando el método VirtualISO14443Part4TargetCallback.processCommand().

Emular una etiqueta inteligente NDEF

Las siguientes tareas describen cómo crear una aplicación simple que emule una etiqueta inteligente de tipo 4 NDEF:
Crear una aplicación para BlackBerry
  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.emulation.VirtualNDEFTag; 
    import net.rim.device.api.io.nfc.NFCException; 
    import net.rim.device.api.io.nfc.ndef.NDEFMessage; 
    import net.rim.device.api.ui.component.ButtonField; 
    import net.rim.device.api.ui.component.Dialog; 
    import net.rim.device.api.ui.container.MainScreen;
    import net.rim.device.api.ui.Field;
    import net.rim.device.api.ui.FieldChangeListener; 
    import net.rim.device.api.ui.UiApplication;
  2. Declare la clase de su aplicación e iníciela.
    public class TagEmulatorApp extends UiApplication
    {
        public static void main(String[] args)
        {
            TagEmulatorApp theApp = new TagEmulatorApp();       
            theApp.enterEventDispatcher();
        }
  3. En el constructor de su aplicación, cree un nuevo objeto Screen para controlar la etiqueta virtual. Agregue su pantalla a la pila de visualización.
        public TagEmulatorApp()
        {        
            pushScreen(new TagEmulatorScreen());
        }
  4. Declare la clase de pantalla que utiliza para controlar su etiqueta virtual. Implemente la interfaz FieldChangeListener para responder a la interacción por parte del usuario.
        private class TagEmulatorScreen extends MainScreen implements 
                                                              FieldChangeListener
        {
  5. Declare dos variables de instancia:
    • Una referencia al botón que el usuario puede utilizar para iniciar y detener la emulación de etiquetas
    • Una referencia a la etiqueta virtual
            private ButtonField _btnStartStop;
            private VirtualNDEFTag _tag;
  6. En el constructor de su pantalla, defina el título para la misma e inicie el botón.
            public TagEmulatorScreen()
            {        
                setTitle("Smart Tag Emulator");
                _btnStartStop = new ButtonField("Start emulation", 
                                                    Field.FIELD_HCENTER);
  7. Especifique la clase de pantalla como FieldChangeListener para el botón y agregue el botón a la pantalla.
                _btnStartStop.setChangeListener(this);
                add(_btnStartStop);
  8. Recupere un mensaje NDEF para escribir en la etiqueta virtual NDEF.
                NDEFMessage msg = null;
                try {
                    msg = TagEmulatorData.getMessage();
                } catch (IOException e) {
                    // process error here
                }
  9. Si el mensaje NDEF se ha creado correctamente, cree una nueva etiqueta. Pase el mensaje NDEF y un objeto de devolución de llamada al constructor de su etiqueta.
                if(msg != null)
                {
                    _tag = new VirtualNDEFTag(msg, new TagEmulatorCallback());
                } else
                {
                    _tag = null;
                }
            }
  10. Implemente el método fieldChanged desde la interfaz FieldChangeListener. Compruebe si la etiqueta virtual es válida y si el usuario ha hecho clic en un botón.
    • Si la etiqueta virtual está activa, entonces desactívela y cambie la etiqueta del botón para indicar que el usuario puede activar la emulación de etiquetas.
    • Si la etiqueta virtual está inactiva, actívela y cambie la etiqueta del botón para indicar al usuario que puede desactivar la etiqueta.
            public void fieldChanged(Field field, int arg1) {
                if(_tag != null)
                {
                    if(field == _btnStartStop)
                    {
                        try {
                            boolean blnEmulating = _tag.isEmulating();
                            if(blnEmulating)
                            {
                                _tag.stopEmulation();
                                _btnStartStop.setLabel("Start emulation");
                            } else
                            {
                                _tag.startEmulation();
                                _btnStartStop.setLabel("Stop emulation");
                            }
    • Si la etiqueta virtual está activa, entonces desactívela y cambie la etiqueta del botón para indicar que el usuario puede activar la emulación de etiquetas.
    • Si la etiqueta virtual está inactiva, actívela y cambie la etiqueta del botón para indicar al usuario que puede desactivar la etiqueta.
  11. Procese cualquier error que se produzca durante la comunicación con la etiqueta.
                        } catch (NFCException e) 
                        {
                            Dialog.alert("Could not communicate with 
                                                          virtual tag.");
                        }
                    }
  12. Si la etiqueta no es válida, notifique al usuario que no se puede activar la emulación.
                } else
                {
                    Dialog.alert("Cannot create smart tag data for emulation.");
                }
            }
        }
    }
Crear un mensaje NDEF
  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.ndef.NDEFMessage;
    import net.rim.device.api.io.nfc.ndef.NDEFRecord;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
  2. Declare la clase de creación de los datos.
    public class TagEmulatorData {
        public TagEmulatorData()
        {
        }
  3. Declare un método estático llamado getMessage. Si utiliza la palabra clave static en este método, puede evitar el requisito de crear una instancia de esta clase cuando desee recuperar datos de la etiqueta virtual. Los métodos invocados durante la creación pueden provocar una IOException. Especifique que el método puede emitir una IOException.
        public static NDEFMessage getMessage() throws IOException
        {
            NDEFRecord titleRec = new NDEFRecord();
            titleRec.setId("1");
            titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); 
            ByteArrayOutputStream payload1 = new ByteArrayOutputStream();
            payload1.write((byte) 0x05);             // Status byte - length of encoding
            payload1.write("en-US".getBytes("UTF-8"));      // Encoding
            payload1.write("My Title".getBytes("UTF-8"));   // Title
            payload1.flush();
            titleRec.setPayload(payload1.toByteArray());
            NDEFRecord uriRec = new NDEFRecord();
            uriRec.setId("2");
            uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U");
            ByteArrayOutputStream payload2 = new ByteArrayOutputStream();
            payload2.write((byte) 0x01);                 // Abbreviation: http://www.
            payload2.write("blackberry.com".getBytes("UTF-8")); // uri
            payload2.flush();
            uriRec.setPayload(payload2.toByteArray());
            NDEFMessage ndefMessage = new NDEFMessage();
            ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec});
            // Root message with one record that has in payload a nested message in the form of bytes
            NDEFMessage rootMessage = new NDEFMessage();
            byte[] rootPayload = ndefMessage.getBytes();
            NDEFRecord rootRec = new NDEFRecord();
            rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp");
            rootRec.setPayload(rootPayload);
            rootMessage.setRecords(new NDEFRecord[] {rootRec});
            return rootMessage;
        }
    }
Implementar la interfaz de devolución de llamada NDEF
  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.io.nfc.emulation.VirtualNDEFTagCallback;
    import net.rim.device.api.ui.component.Dialog;
  2. Declare su implementación de la interfaz VirtualNDEFTagCallback.
    public class TagEmulatorCallback implements VirtualNDEFTagCallback
    {
  3. Implemente el método onVirtualTargetEvent(). Cada vez que se produzca un evento, notifíqueselo al usuario.
        public void onVirtualTargetEvent(int event) {
            switch(event)
            {
                case VirtualNDEFTagCallback.EMULATION_STOPPED:
                    Dialog.alert("Emulation stopped.");
                    break;
                case VirtualNDEFTagCallback.READER_LEFT:
                    Dialog.alert("Smart tag reader moved out of range.");
                    break;
                case VirtualNDEFTagCallback.SELECTED:
                    Dialog.alert("This tag was selected by a smart tag reader.");
                    break;
                case VirtualNDEFTagCallback.TARGET_READ:
                    Dialog.alert("This tag was read by a smart tag reader.");
                    break;
                case VirtualNDEFTagCallback.TARGET_UPDATED:
                    Dialog.alert("A smart tag writer changed the contents of this tag.");				
                    break;
            }
        }
    }

Ejemplo de código: emulación de una etiqueta inteligente NDEF

Crear una aplicación para BlackBerry

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.io.nfc.NFCException;
import net.rim.device.api.io.nfc.emulation.VirtualNDEFTag;
import net.rim.device.api.io.nfc.ndef.NDEFMessage;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.container.MainScreen;
import java.io.IOException;
public class TagEmulatorApp extends UiApplication
{
    public static void main(String[] args)
    {
        TagEmulatorApp theApp = new TagEmulatorApp();       
        theApp.enterEventDispatcher();
    }
    public TagEmulatorApp()
    {        
        pushScreen(new TagEmulatorScreen());
    }
    private class TagEmulatorScreen extends MainScreen implements FieldChangeListener
    {
        private ButtonField _btnStartStop;
        private VirtualNDEFTag _tag;
        public TagEmulatorScreen()
        {        
            setTitle("Smart Tag Emulator");
            _btnStartStop = new ButtonField("Start emulation", Field.FIELD_HCENTER);
            _btnStartStop.setChangeListener(this);
            add(_btnStartStop);
            NDEFMessage msg = null;
            try {
                msg = TagEmulatorData.getMessage();
            } catch (IOException e) {
                // process error here
            }
            if(msg != null)
            {
                _tag = new VirtualNDEFTag(msg, new TagEmulatorCallback());
            } else
            {
                _tag = null;
            }
        }
        public void fieldChanged(Field field, int arg1) {
            if(_tag != null)
            {
                if(field == _btnStartStop)
                {
                    try {
                        boolean blnEmulating = _tag.isEmulating();
                        if(blnEmulating)
                        {
                            _tag.stopEmulation();
                            _btnStartStop.setLabel("Start emulation");
                        } else
                        {
                            _tag.startEmulation();
                            _btnStartStop.setLabel("Stop emulation");
                        }
                    } catch (NFCException e) 
                    {
                        Dialog.alert("Could not communicate with virtual tag.");
                    }
                }
            } else
            {
                Dialog.alert("Cannot create smart tag data for emulation.");
            }
        }
    }
}

Crear un mensaje NDEF

import net.rim.device.api.io.nfc.ndef.NDEFMessage;
import net.rim.device.api.io.nfc.ndef.NDEFRecord;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class TagEmulatorData {
    public TagEmulatorData()
    {
    }
    public static NDEFMessage getMessage() throws IOException
    {
        NDEFRecord titleRec = new NDEFRecord();
        titleRec.setId("1");
        titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); 
        ByteArrayOutputStream payload1 = new ByteArrayOutputStream();
        payload1.write((byte) 0x05);             // Status byte - length of encoding
        payload1.write("en-US".getBytes("UTF-8"));      // Encoding
        payload1.write("My Title".getBytes("UTF-8"));   // Title
        payload1.flush();
        titleRec.setPayload(payload1.toByteArray());
        NDEFRecord uriRec = new NDEFRecord();
        uriRec.setId("2");
        uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U");
        ByteArrayOutputStream payload2 = new ByteArrayOutputStream();
        payload2.write((byte) 0x01);                 // Abbreviation: http://www.
        payload2.write("blackberry.com".getBytes("UTF-8")); // URI
        payload2.flush();
        uriRec.setPayload(payload2.toByteArray());
        NDEFMessage ndefMessage = new NDEFMessage();
        ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec});
        // root message with one record that has in payload a nested message in the form of bytes
        NDEFMessage rootMessage = new NDEFMessage();
        byte[] rootPayload = ndefMessage.getBytes();
        NDEFRecord rootRec = new NDEFRecord();
        rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp");
        rootRec.setPayload(rootPayload);
        rootMessage.setRecords(new NDEFRecord[] {rootRec});
        return rootMessage;
    }
}

Implementar la interfaz de devolución de llamada NDEF

import net.rim.device.api.io.nfc.emulation.VirtualNDEFTagCallback;
import net.rim.device.api.ui.component.Dialog;
public class TagEmulatorCallback implements VirtualNDEFTagCallback
{
    public void onVirtualTargetEvent(int event) {
        switch(event)
        {
            case VirtualNDEFTagCallback.EMULATION_STOPPED:
                Dialog.alert("Emulation stopped.");
                break;
            case VirtualNDEFTagCallback.READER_LEFT:
                Dialog.alert("Smart tag reader moved out of range.");
                break;
            case VirtualNDEFTagCallback.SELECTED:
                Dialog.alert("This tag was selected by a smart tag reader.");
                break;
            case VirtualNDEFTagCallback.TARGET_READ:
                Dialog.alert("This tag was read by a smart tag reader.");
                break;
            case VirtualNDEFTagCallback.TARGET_UPDATED:
                Dialog.alert("A smart tag writer changed the contents of this tag.");				
                break;
        }
    }
}

Detectando la capacidad de NFC

La clase DeviceCapability le puede ayudar a determinar si un dispositivo BlackBerry dispone de una radio NFC y si la característica NFC está disponible.

Algunas de las razones por las que la característica NFC podría no estar disponible son:
  • El usuario ha desactivado la radio NFC
  • La característica NFC ha sido desactivada por una política de TI
  • Otra aplicación está utilizando la radio NFC

Puede utilizar el método DeviceCapability.isNFCSupported() para determinar si el dispositivo dispone de una radio NFC. El método DeviceCapability.isNFCAvailable() indica si la característica NFC está disponible para utilizarse en su aplicación.

Detectar la capacidad NFC

  1. Importe las clases y las interfaces necesarias.
    import net.rim.device.api.system.capability.DeviceCapability;
    import net.rim.device.api.ui.*;
    import net.rim.device.api.ui.component.LabelField;
    import net.rim.device.api.ui.container.*;
  2. Declare la clase de su aplicación e iníciela.
    public class NFCDemo extends UiApplication
    {
        public static void main(String[] args)
        {
            NFCDemo theApp = new NFCDemo();
            theApp.enterEventDispatcher();
        }
  3. En el constructor de su aplicación, cree un nuevo objeto Screen para controlar la etiqueta virtual. Agregue su pantalla a la pila de visualización.
        public NFCDemo()
        {
            pushScreen(new NFCPropertiesScreen());
        }
  4. Declare la clase de pantalla que utiliza para mostrar el estado de la característica NFC.
        private class NFCPropertiesScreen extends MainScreen
        {
  5. En el constructor de la pantalla, defina el título para la misma e inicie dos etiquetas.
            public NFCPropertiesScreen()
            {
                setTitle("NFC Capability Reporter");
                LabelField lbl[] = new LabelField[2];
                lbl[0] = new LabelField();
                lbl[1] = new LabelField();
  6. Compruebe si el dispositivo BlackBerry dispone de una radio NFC. Informe del resultado al usuario definiendo el texto adecuado en la primera etiqueta.
                if(DeviceCapability.isNFCSupported())
                {
                    lbl[0].setText("supported true");
                } else
                {
                    lbl[0].setText("supported false");
                }
  7. Compruebe si la característica NFC está disponible. Informe del resultado al usuario definiendo el texto adecuado en la segunda etiqueta.
                if(DeviceCapability.isNFCAvailable())
                {
                    lbl[1].setText("available true");
                } else
                {
                    lbl[1].setText("available false");
                }
  8. Agregue las etiquetas a su pantalla.
                add(lbl[0]);
                add(lbl[1]);
            }
        }
    }

Ejemplo de código: detección de la capacidad NFC

import net.rim.device.api.system.capability.DeviceCapability;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.*;
public class NFCDemo extends UiApplication
{
    public static void main(String[] args)
    {
        new NFCDemo().enterEventDispatcher();
    }
    public NFCDemo()
    {
        pushScreen(new NFCPropertiesScreen());
    }
    private class NFCPropertiesScreen extends MainScreen
    {
        public NFCPropertiesScreen()
        {
            setTitle("NFC Capability Reporter");
            LabelField lbl[] = new LabelField[2];
            lbl[0] = new LabelField();
            lbl[1] = new LabelField();
            if(DeviceCapability.isNFCSupported())
            {
                lbl[0].setText("supported true");
            } else
            {
                lbl[0].setText("supported false");
            }
            if(DeviceCapability.isNFCAvailable())
            {
                lbl[1].setText("available true");
            } else
            {
                lbl[1].setText("available false");
            }
            add(lbl[0]);
            add(lbl[1]);
        }
    }
}
Tema siguiente: Glosario

¿Le ha resultado útil esta información? Envíenos sus comentarios.