Porting BlackBerry Java NFC Applications to BlackBerry 10 – Part 1: Reading NFC Tags

Cascades

find milan

Our buddy Rob Williams included some words of wisdom on porting BlackBerry OS Java applications that read or write NFC tags in a blog post that embraced both these aspects of NFC and Bluetooth, a few months back.

John Murray and I would like to circle back on the subject of porting BlackBerry Java NFC applications to BlackBerry 10 and cover the subject in more detail and across all the primary capabilities and use cases of NFC.

To that end, we’ll be publishing a series of six blog posts about porting NFC apps from BlackBerry Java to BlackBerry 10 native applications over the coming weeks, starting with this one. The full list of posts in this series will be:

  1. Reading NFC Tags
  2. Writing NFC Tags
  3. Peer to Peer Mode
  4. Reading NFC Contactless Cards
  5. NFC Virtual Tag and Card Emulation
  6. NFC Card Emulation

So let’s take it away and discuss reading NFC Tags and how to turn BlackBerry Java apps that do this into BlackBerry 10 native apps.

Key issues for the Java developer:

  1. Registration

The application must implement the NDEFMessageListener interface and register it with ReaderWriterManager.addNDEFMessageListener(…)

  1. Invocation

NDEFMessageListener’s on NDEFMessageDetected method is called directly if the app is already running when tag whose content matches the type registered for is detected.

The application must handle being restarted when a tag is presented as a special case in the code.

  1. Decoding tag content

We decode tag content with classes in net.rim.device.api.io.nfc.ndef.rtd or direct from byte[] payload

Tags contain NDEFMessage and NDEFRecord objects

The BlackBerry 10 Native approach:

1. Registration

Applications must register for particular tag content with an entry in the bar-descriptor.xml file as shown here:

        <invoke-target id="com.example.TouchTicTacTen.ndef">
                    <require-source-permissions>invoke_across_perimeters</require-source-permissions>
                    <type>APPLICATION</type>
                    <filter>
                        <!-- The action(s) we support-->
                        <action>bb.action.OPEN</action>

                       <mime-type>application/vnd.rim.nfc.ndef</mime-type>

                        <!-- ndef:// means that we want to register for ALL NDEF messages,
                            in most cases we want to be more specific; we can filter these
                            messages further with the following format ndef://TNF/RECORD_TYPE
                            (e.g. ndef://1/Sp for tnf: Well Known, record type: smart posters).
                            for URI record types the record type needs to be URL encoded
                            (e.g. ndef://3/http%3A%2F%2F for tnf: Uri, record type: http://).
                            for external record types the colon (:) needs to be replaced with a
                            forward slash (/)
                            (e.g. ndef://4/rim.com/bbm for tnf: External, record type: rim.com:bbm).

                            TNF VALUES:
                            0 : Empty Tag
                            1 : Well Known
                            2 : Media (MIME)
                            3 : Uri
                            4 : External -->      
                      <property var="uris" value="ndef://4/com.blackberry.nfc.sample/G1"/>
                    </filter>
                </invoke-target>

2. Invocation

When a tag containing content that matches the details registered for in the bar-descriptor.xml file is detected, the invocation framework determines which application to dispatch the tag content to and if it is not already running, launches it. Developers should use the InvokeManager class and signals/slots to receive a callback when this happens and extract the tag payload from the InvokeRequest object. Here’s an example:

MyApp::MyApp(Application *app) {
  _invokeManager = new bb::system::InvokeManager();
  QObject::connect(_invokeManager,
                   SIGNAL(invoked(const bb::system::InvokeRequest&)),
                                  this,
                   SLOT(receivedInvokeRequest(const bb::system::InvokeRequest&)));
....
}
void MyApp::receivedInvokeRequest(const bb::system::InvokeRequest& request) {
                QByteArray data = request.data();
                if (request.mimeType().compare("application/vnd.rim.nfc.ndef") == 0) {
                                qDebug("XXXX launched because an NFC tag has been presented");
// next we decode the content of the InvokeRequest
                }
}

3. Decoding tag content

There are two APIs to choose from:

3.1 Qt

BlackBerry 10’s APIs includes the QtMobilitySubset API. This contains some useful methods for handling tag data in the NDEF format. For example:

QtMobilitySubset::QNdefMessage ndefMessage = QtMobilitySubset::QNdefMessage::fromByteArray(data);
QList<QtMobilitySubset::QNdefRecord>::const_iterator ndefRecord;

for ( ndefRecord = ndefMessage.begin(); ndefRecord != ndefMessage.end(); 
      ndefRecord++) {

  if (ndefRecord->typeNameFormat() == QtMobilitySubset::QNdefRecord::ExternalRtd)
  {
    if (QString(ndefRecord->type()).compare("my.rim.com:myrecordtype") == 0 ) {
// ......
    }
   }
}

3.2 BPS

The BlackBerry Platform Services (BPS) APIs include methods intended for transforming byte [] format tag payloads into NDEF structures. Code fragments:

nfc_get_ndef_message(target, ndefMsgIndex, &ndefMessage);
for (int ndefMsgIndex = 0; ndefMsgIndex < ndefMsgCount; ++ndefMsgIndex) {
  unsigned int ndefRecordCount = 0;
  CHECK(nfc_get_ndef_record_count(ndefMessage, &ndefRecordCount));
  for (unsigned int ndefRecordIndex = 0;
    ndefRecordIndex < ndefRecordCount; ++ndefRecordIndex) {
    nfc_ndef_record_t *ndefRecord;
    CHECK(nfc_get_ndef_record(ndefMessage, ndefRecordIndex, &ndefRecord));
    uchar_t* ndefRecordPayloadData;
    size_t ndefRecordPayloadLength;
    CHECK(nfc_get_ndef_record_payload(ndefRecord, &ndefRecordPayloadData, &ndefRecordPayloadLength));
    tnf_type_t ndefRecordTnf;
   CHECK(nfc_get_ndef_record_tnf(ndefRecord, &ndefRecordTnf));
    char *ndefRecordNdefType;
    CHECK(nfc_get_ndef_record_type(ndefRecord, &ndefRecordNdefType));
    char *ndefRecordIdentifier;
    CHECK(nfc_get_ndef_record_id(ndefRecord, &ndefRecordIdentifier));
    QString ndefRecordPayloadAsHex = QString::fromAscii(
    reinterpret_cast<const char *>(ndefRecordPayloadData),
                ndefRecordPayloadLength).toAscii().toHex();
    QByteArray payLoadData = QByteArray::fromRawData(
                reinterpret_cast<const char *>(ndefRecordPayloadData),
                ndefRecordPayloadLength);
    if (strcmp(ndefRecordNdefType, Settings::NfcRtdSmartPoster) == 0) {
      char *utf_title;
      char *found_lang;
      char *uri;
      nfc_ndef_rtd_encoding_t rtd_encoding;
      rtd_encoding = UTF_8;

      CHECK(nfc_get_sp_title(ndefRecord, Settings::LANG_EN, &utf_title, &found_lang, &rtd_encoding, true));
      CHECK(nfc_get_sp_uri(ndefRecord, &uri));
      free(utf_title);
      free(uri);
} else if (strcmp(ndefRecordNdefType, Settings::NfcRtdUri) == 0) {
// etc

That’s it! Reading NFC tags using the BlackBerry 10 APIs is very easy, unarguably easier than it was using BlackBerry Java. Porting this aspect of your application should take very little time and effort indeed.

Resources: Helpful knowledge base articles can be found here.

Sample Code: Tag reading via Invocation Framework and then decoding using the BPS APIs is demonstrated by the NfcTool application can be found here.

Tag reading via Invocation Framework and then decoding using the Qt APIs is demonstrated by the NfcRaceTimeWay application can be found here.

Have questions or comments? Reach out to us on Twitter at @mdwrim, @jcmrim and @robbieDubya.

About mdwrim

My name’s Martin Woolley and I work in BlackBerry's Developer Relations team as a Senior Application Development Consultant. I’ve been with BlackBerry since 2009 but have worked in software development in various capacities for 30 years in a whole range of industry sectors and on numerous computing platforms small and large. These days I specialise in areas such as Bluetooth Low Energy, NFC, Internet of Things (Iot) and wearable technologies amongst other things.

Join the conversation

Show comments Hide comments
+ -
  • Ransom gudi

    I love bb messager, I ll love to ve it nw in my smart phone

  • http://devblog.blackberry.com/2013/09/porting-blackberry-java-nfc-applications-to-blackberry-10-part-2-tag-writing/ Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 2: Tag Writing | BlackBerry Developer Blog

    […] Martin Woolley and me on porting BlackBerry Java applications that use NFC to BlackBerry 10. In our last post, we looked at Tag Reading. This time, we’ll review the way in which you’d port code that writes […]

  • http://www.sdknews.com/blackberry/porting-blackberry-java-nfc-applications-to-blackberry-10-part-2-tag-writing Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 2: Tag Writing | SDK News

    […] Martin Woolley and me on porting BlackBerry Java applications that use NFC to BlackBerry 10. In our last post, we looked at Tag Reading. This time, we’ll review the way in which you’d port code that writes […]

  • http://devblog.blackberry.com/2013/09/porting-blackberry-java-nfc-applications-to-blackberry-10-part-3-peer-to-peer-snep-simple-ndef-exchange-protocol/ Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 3: Peer to Peer – SNEP (Simple NDEF Exchange Protocol) | BlackBerry Developer Blog

    […] I on porting BlackBerry Java applications that use NFC to BlackBerry 10. So far we’ve looked at Tag Reading and Tag Writing. This time, we’ll review the porting of code that exploits NFC’s Peer to Peer […]

  • http://www.sdknews.com/blackberry/porting-blackberry-java-nfc-applications-to-blackberry-10-part-3-peer-to-peer-snep-simple-ndef-exchange-protocol Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 3: Peer to Peer – SNEP (Simple NDEF Exchange Protocol) | SDK News

    […] I on porting BlackBerry Java applications that use NFC to BlackBerry 10. So far we’ve looked at Tag Reading and Tag Writing. This time, we’ll review the porting of code that exploits NFC’s Peer to Peer […]

  • http://devblog.blackberry.com/2013/10/porting-blackberry-java-nfc-applications-to-blackberry-10-part-4-reading-a-contactless-card/ Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 4: Reading a Contactless Card | BlackBerry Developer Blog

    […] on porting BlackBerry Java applications that use NFC to BlackBerry 10. So far, we’ve looked at Tag Reading, Tag Writing and Peer to Peer mode. This time, we’ll review the porting of code that deals with […]

  • http://devblog.blackberry.com/2013/10/porting-blackberry-java-nfc-applications-to-blackberry-10-part-5-virtual-tag-and-card-emulation/ Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 5: Virtual Tag and Card Emulation | BlackBerry Developer Blog

    […] I on porting BlackBerry Java applications that use NFC to BlackBerry 10. So far we’ve looked at Tag Reading, Tag Writing, Peer to Peer mode and the Reading of contactless cards. In this post, we’ll review […]

blog comments powered by Disqus