Package net.rim.device.api.io.nfc

Provides access to the Near Field Communication (NFC) feature.

See:
          Description

Interface Summary
NFCFieldListener Receives notifications when an emulated target detects changes in the NFC field.
NFCStatusListener Receives notifications related to changes in NFC service information.
 

Class Summary
NFCManager Manages the status of NFC on the device.
 

Exception Summary
NFCException Represents an error that occurs during operations of the NFC API.
NFCInUseException Indicates that some exclusive NFC functionality, such as NFC virtual target emulation, is already in use.
 

Package net.rim.device.api.io.nfc Description

Provides access to the Near Field Communication (NFC) feature.

NFC is a wireless connectivity technology that enables convenient short-range contactless communication between electronic devices, tags and cards.

NFC operates at 13.56 MHz, and enables data transfers of up to 424 kb per second. NFC is designed to work when two NFC-compatible devices are brought within four to ten centimeters of each other.

The NFC API provides the ability to :

Listen for NFC targets in the vicinity

Applications can listen for NFC tartets as follows:

Listen for any supported NFC target

public class NfcTargetDetector implements DetectionListener {

    public void onTargetDetected( final Target target ) {
        // do something with the target here
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addDetectionListener( new NFCTargetDetector(), new int[]{Target.NDEF_TAG} );

        } 
        catch ( NFCException e ) {
                // log error
        }
    }
}

Listen for NDEF messages


public class NDEFMessageDetector implements NDEFMessageListener {

    public void onNDEFMessageDetected( NDEFMessage msg ) {
        // do something with the NDEFMessage here
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addNDEFMessageListener( new NDEFMessageDetector(), NDEFRecord.TNF_ANY, null, false );
        } 
        catch ( NFCException e ) {
                // log error
        }
    }

}

Read from NFC tags

Applications can read NFC tags as follows:

Read a detected NDEF tag

public class NfcTargetDetector implements DetectionListener {

    public void onTargetDetected( final Target target ) {
        NDEFTagConnection c = null;
        try {
            c = (NDEFTagConnection)Connector.open(target.getUri(Target.NDEF_TAG));
            NDEFMessage ndefMessage = c.read();
            NDEFRecord[] ndefRecords = ndefMessage.getRecords();
            // do something with the NDEF records here
        } 
        catch (IOException e) {
            // error handling here
        }    
        finally {
            try {
                if (c != null) {
                    c.close();
                }
            } 
            catch (IOException e) {
            }
        }
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addDetectionListener( new NFCTargetDetector(), new int[]{Target.NDEF_TAG} );
        } 
        catch ( NFCException e ) {
                // log error
        }
    }

}

Read a detected non-NDEF tag


public class NfcTargetDetector implements DetectionListener {

    public void onTargetDetected( final Target target ) {
        ISO14443Part3Connection c = null;
        InputStream in = null;
        try {
            c = (ISO14443Part3Connection)Connector.open(target.getUri(Target.ISO_14443_3));
            // send request bytes to tag and get response
            byte[] response = c.transceive( new byte[] {0,1,2,3,4} );
        } 
        catch (IOException e) {
                // error handling here
        } 
        finally {
            try {
                if (in != null) {
                    in.close();
                }
                c.close();
            } 
            catch (IOException e) {
            }
        }
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addDetectionListener( new NFCTargetDetector(), new int[]{Target.ISO_14443_3} );
        }
        catch ( NFCException e ) {
                // error handling
        }
    }

}

Write NFC tags

Applications can write NFC tags as follows:

Write to a detected NDEF tag


public class NfcTargetDetector implements DetectionListener {

    public void onTargetDetected( final Target target ) {
        NDEFTagConnection c = null;
        try {
            c = (NDEFTagConnection)Connector.open(target.getUri(Target.NDEF_TAG));
            NDEFMessage ndefMessage = new NDEFMessage();
            NDEFRecord rec1 = new NDEFRecord();
            rec1.setId("1");
            rec1.setType(NDEFRecord.TNF_MEDIA, "text/plain");
            rec1.setPayload("Welcome to the NFC Forum".getBytes());
            NDEFRecord rec2 = new NDEFRecord();
            rec2.setId("2");
            rec2.setType(NDEFRecord.TNF_MEDIA, "text/plain");
            rec2.setPayload("http://www.nfc-forum.org".getBytes());
            ndefMessage.setRecords(new NDEFRecord[]{rec1, rec2});
            c.write(ndefMessage);
        } 
        catch (IOException e) {
                // error handling here
        }
        finally {
            try {
                if (c != null)
                    c.close();
            }
            catch (IOException e) {
            }   
        }
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addDetectionListener( new NFCTargetDetector(), new int[]{Target.NDEF_TAG} );
        } 
        catch ( NFCException e ) {
            // error handling here
        }
    }

}

Write to a detected non-NDEF tag


public class NfcTargetDetector implements DetectionListener {

    public void onTargetDetected( final Target target ) {
        if (target.isType(Target.ISO_14443_3)) {
            ISO14443Part3Connection c = null;
            OutputStream out = null;
            try {
                c = (ISO14443Part3Connection)Connector.open(target.getUri(Target.ISO_14443_3));
                // Note: not a real command.  Command bytes need 
                // to be determined based on type of tag being written to
                byte[] response = c.transceive(new byte[]{0,1,2,3,4});
            } 
            catch (IOException e) {
                    // error handling here
            } 
            finally {
                try {
                    if (out != null)
                        out.close();
                } 
                catch (IOException e) {
                }
                try {
                    if (c != null)
                        c.close();
                }    
                catch (IOException e) {
                }
            }
        }
    }

}

public class MyNFCApp extends Application {

    public void myAppInitializationMethod() {
        try {
            ReaderWriterManager myRWManager = ReaderWriterManager.getInstance();
            myRWManager.addDetectionListener( new NFCTargetDetector(), new int[]{Target.ISO_14443_3} );
        } 
        catch ( NFCException e ) {
            // error hanlding here
        }
    }

}

Emulate tags or cards

Applications can emulate an NDEF tag to be read by an NFC capable reader by doing the following:

public class VirtualNDEFTagListener implements VirtualNDEFTagCallback {

    public void onVirtualTargetEvent(int tagEvent) {
        switch (tagEvent) {
            case VirtualNDEFTagCallback.EMULATION_STOPPED:
                    // emulation has stopped
                    break;
            case VirtualNDEFTagCallback.SELECTED:
                    // external reader has selected the tag
                    break;
            case VirtualNDEFTagCallback.TARGET_READ:
                    // external reader has read the tag
                    break;
            case VirtualNDEFTagCallback.TARGET_UPDATED:
                    // external reader has updated the tag
                    break;
            case VirtualNDEFTagCallback.READER_LEFT:
                    // external reader has left 
            default:
                    // ...
        }
    }

}

public class MyNFCApp extends Application {

    private VirtualNDEFTag vt;

    public void startNDEFEmulation() throws NFCException {
        NDEFMessage ndefMessage = new NDEFMessage();
        NDEFRecord rec1 = new NDEFRecord();
        rec1.setId("1");
        rec1.setType(NDEFRecord.TNF_MEDIA, "text/plain");
        rec1.setPayload("I am a scintilating emulator".getBytes());
        NDEFRecord rec2 = new NDEFRecord();
        rec2.setId("2");
        rec2.setType(NDEFRecord.TNF_MEDIA, "text/plain");
        rec2.setPayload("Yours truly".getBytes());
        ndefMessage.setRecords(new NDEFRecord[]{rec1, rec2});
        vt = new VirtualNDEFTag(ndefMessage, new VirtualNDEFTagListener());
        vt.startEmulation();
    }
    
    public void stopNDEFEmulation() throws NFCException {
        if (vt != null ) {
            vt.stopEmulation();
        }
    }

}

Register menu item actions for specific patterns

Applications can create specific actions, and then register this action with a pattern so that if the pattern is found in an NFC SmartPoster tag, the BlackBerry Data Tags application will create a button for users to execute the corresponding command. The code below is not specific to the NFC API, and in fact, registers this pattern globally on the device. When this pattern is found in other places, the pattern will be underlined and a context menu item will be created to run the corresponding command.

Pattern registration can be done using the net.rim.device.api.stringpattern.PatternRepository, which uses regular expressions for the matching, and takes in a menu item object to define the action. The following extends the menu item object, and then registers it with a corresponding regular expression:

public class NFCMenuItem extends ApplicationMenuItem {

    //using the default constructors here.
    NFCMenuItem(int order) {
        super(order);
    }

    //methods we must implement
    //Run is called when the menuItem is invoked
    public Object run(Object context) {
        // Context object should be a string containing the URL pattern
        // Do something with the URL
    }

    //toString should return the string we want to
    //use as the lable of the menu item
    public String toString() {
        return "NFC Action";
    }

}

public class NFCPatternMain {

    public NFCPatternMain() {
        // Create an array of menu items to be associated with pattern
        NFCMenuItem myMenuItem = new NFCMenuItem(0);
        ApplicationMenuItem[] myMenuItemArray = new ApplicationMenuItem[1];
        myMenuItemArray[0] = myMenuItem;

        // Add a pattern to the Pattern Repository.
        // The regular expression used to search matches anything with "nfc://" - and
        // then grabs all the characters that follow
        PatternRepository.addPattern( ApplicationDescriptor.currentApplicationDescriptor(),
            "(nfc://)(.*)", PatternRepository.PATTERN_TYPE_REGULAR_EXPRESSION, myMenuItemArray );
    }

}






Copyright 1999-2011 Research In Motion Limited. 295 Phillip Street, Waterloo, Ontario, Canada, N2L 3W8. All Rights Reserved.
Java is a trademark of Oracle America Inc. in the US and other countries.
Legal