Porting BlackBerry Java NFC Applications to BlackBerry 10 Part 2: Tag Writing

Native SDK Development

NFC tags

Guest post by John Murray

This is the second part of a six-part series by 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 to NFC tags.

Here’s where we are in the series as a whole:

  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 without further ado, let’s take a look at the aspects you need to deal with:

Key issues for the Java developer

The general pattern you’ll have followed in your Java application will have been to address the following tasks:

  1. Detecting the tag: The application must implement the DetectionListener interface and register it with ReaderWriterManager.addDetectionListener(…). When a tag comes into proximity with the device, there will be a call-back to the DetectionListener.
  2. Creating tag content: To create tag content, we create an NDEFMessage object using methods in NDEFMessageUtils such as createUriNdefMessage (available from BlackBerry 7 device software version 7.1), or by manually create the byte[] payload and building NDEFRecord and NDEFMessage objects.
  3. Writing to the tag: When a tag is found to be in proximity of the BlackBerry device, as indicated by a call-back to the DetectionListener interface, we create an NDEFTagConnection to the Target object indicated in the call-back and then write the tag content to it that we’ve already prepared.

The BlackBerry 10 Native approach

To perform the corresponding tasks in BlackBerry 10, you can take one of two approaches. You may either:

a) Use the Invocation Framework. That is, find another application that can provide a “tag writing service” that your application can use, or:

b) Use BPS (BlackBerry Platform Services) to detect and then write data to the tag.

Writing tags using the Invocation Framework

The easiest way to do this is directly from QML using the QML InvokeActionItem component. The code fragment below shows how to do this. Note that the tag content itself must still be constructed, as an array of bytes, from C++ and, in this example we’re calling our own application code via _ndefFactory.getNdefTextMessage() to accomplish this. We’ll explain this in more detail below.

      actions: [
        InvokeActionItem {
            id: sharedNdefData
            ActionBar.placement: ActionBarPlacement.OnBar
            query {
                mimeType: "application/vnd.rim.nfc.ndef"
                invokeActionId: "bb.action.SHARE"
            }
            handler: InvokeHandler {
                id: shareHandler
                onInvoking: {
                    sharedNdefData.data = 
                         _ndefFactory.getNdefTextMessage(
                             "en",
                            writeText.ndefText
                            );
                    shareHandler.confirm();
                }
            }
         }
      ]

In our example, we construct an invocation framework query whereby we express our need for an application that can “SHARE” data of MIME type “application/vnd.rim.nfc.ndef”. This means we’re looking for an application that can write tags on our behalf. When the action is invoked, we call our _ndefFactory C++ method to create the payload and assign the result to the data attribute of the InvokeActionItem component. Our C++ code is shown below and you can see that the QtMobilitySubset API was used to help create the tag content in the NDEF format.

QByteArray NdefFactory::getNdefTextMessage(
    const QVariant &lang,
    const QVariant &text)
{

    QString ndefLang = lang.toString();
    QString ndefText = text.toString();

    QtMobilitySubset::QNdefRecord ndefRecord =
         QtMobilitySubset::QNdefRecord();

    int langLength = (ndefLang.length() <= 63)
                   ?  ndefLang.length()
                   : 63;

    QByteArray ndefPayload;
    ndefPayload[0] = langLength;

    ndefPayload.append(ndefLang.left(langLength))
               .append(ndefText.toUtf8());

    ndefRecord.setTypeNameFormat(QtMobilitySubset::QNdefRecord::NfcRtd);
    ndefRecord.setType(Settings::NfcRtdText);
    ndefRecord.setPayload(ndefPayload);

    QtMobilitySubset::QNdefMessage ndefMessage =
        QtMobilitySubset::QNdefMessage(ndefRecord);

    return ndefMessage.toByteArray();
}

Writing tags using BPS

BPS processing takes place inside an event loop. Detection of a tag is indicated by delivery to the event loop of a particular type of event object. To receive such events, we must first register our interest by calling:

                nfc_register_tag_readerwriter(TAG_TYPE_NDEF);

On receiving an event with the event code NFC_TAG_READWRITE_EVENT we proceed to construct our tag content in NDEF format and then write it to the tag via a Target object. The following code fragment illustrates this.

void NfcWorker::handleNfcWriteTextTagEvent(bps_event_t *event) {

     uint16_t code = bps_event_get_code(event);

    nfc_event_t *nfcEvent;
    nfc_target_t* target;
    nfc_ndef_record_t* myNdefRecord;
    nfc_ndef_message_t* myNdefMessage;

    if (NFC_TAG_READWRITE_EVENT == code) {

        int rc; // check return codes from NFC calls below
        rc = nfc_get_nfc_event(event, &nfcEvent);
        rc = nfc_get_target(nfcEvent, &target);

        displayTagInformation(target);
        myNdefRecord = makeTextRecord(Settings::LANG_EN, _ndefText);

        rc = nfc_create_ndef_message(&myNdefMessage);
        rc = nfc_add_ndef_record(myNdefMessage, myNdefRecord);
        rc = nfc_write_ndef_message_to_tag(target, myNdefMessage, false);
        rc = nfc_delete_ndef_message(myNdefMessage, true);
        rc = nfc_destroy_target(target);
        rc = nfc_unregister_tag_readerwriter();
        emit message(QString("Tag Type Written Text: %1").arg(_ndefText));
    } else {
        qDebug() << "XXXX NfcWorker::handleNfcWriteTextTagEvent”
                    “ - NFC BPS event that we didn't register for: "
                 << code;
    }
}

So there you have it. Hopefully our exploration of this topic will make it nice and easy for you to port your BlackBerry Java application over to the world of BlackBerry 10 native apps. Good luck!

Resources

Knowledge Base Articles:

Sample Code:

Contacts:

About Alex Kinsella

Promoter of apps. Connoisseur of tacos. By day, I'm a PR and Social Media Manager at BlackBerry.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus