Sending content

Your app can use NFC to send small amounts of data or larger files. If you're sharing a small amount of data, the NFC service sends it to the target device over NFC. If you're sending a file, a connection handover via Bluetooth or Wi-Fi is negotiated with the target NFC device. Once content sharing begins, your app is notified of the sharing event.

Sending content using the Cascades API

There are two ways to send data or file content using the Cascades APIs: through NFC Share Cards or using the Cascades Share API.

To send data using the Cascades Share API, your app needs to:
  • Create an instance of NfcShareDataContent to define the data to send
  • Create an instance of NfcShareManager and register the data content instance with it
  • Connect the appropriate signals and slots for the NfcShareManager to perform sharing

Flow diagram showing how data content is written with the NFC share API

To send files using the Cascades Share API, your app needs to:
  • Create an instance of NfcShareFileContent to define the file type to send
  • Create an instance of NfcShareManager and register the file content instance with it
  • Connect the appropriate signals and slots for the NfcShareManager to perform sharing

Flow diagram showing how files are written with the NFC share API

Sending content using the NFC C API

To send data using the C API, your app needs to:
  • Connect to the NFC system either through the BlackBerry Platform Services (BPS) or by calling nfc_connect()
  • Register to receive NFC events
  • Handle tag read/write events or SNEP connection events
  • Create and send NDEF messages using API functions defined in nfc.h

Flow diagram showing how data content is written with the NFC C API

To send files using the C API, your app needs to:
  • Connect to the NFC system either through the BlackBerry Platform Services or by calling nfc_connect()
  • Register to receive NFC events
  • When receiving the initial handover event, allow the handover process to proceed
  • When the handover connection is established, get the connection information such as the target, handover role, and transport type
  • Send files using the Bluetooth or Wi-Fi service APIs through the handover connection

Flow diagram showing how files are written with the NFC C API

To transfer files that are stored on the user's device at shared locations, add the following permission to your app's bar-descriptor.xml file:

<permission>access_shared</permission>

See C++

First, create an instance of either NfcShareDataContent or NfcShareFileContent. You also need to create an instance of NfcShareManager.

shareData = new NfcShareDataContent();
shareFile = new NfcShareFileContent();
shareManager = new NfcShareManager();                   
                

The sharing action is triggered when the user selects the type of content that they want to share from a DropDown list UI control. The QML code for the DropDown is as follows. Although the UI is developed using QML, you could substitute a C++ UI without affecting the NFC functionality of the app.

DropDown {
    id: qtMessageSelector
    title: "Message Template"
    function reset() {
        selectedIndex = -1;
    }
    Option {
        text: "Text"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendText();
                textArea.text = "\nText: Welcome to Qt NFC Text";
                qtRadioSelector.reset();
            }
        }
    }
    Option {
        text: "URI"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendUri();
                textArea.text = "\nURI: www.rim.com";
                qtRadioSelector.reset();
            }
        }
    }
    Option {
        text: "Smart Poster"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendSp();
                textArea.text = "\nText: Welcome to Qt NFC Smart Poster\n" + 
                    "URI: www.rim.com";
                    qtRadioSelector.reset();
            }
        }
    }
}

In addition to the DropDown control, we also give the user a RadioGroup , which is a set of radio buttons that they can use to share a contact, a calendar, or a file.

RadioGroup {
    id: qtRadioSelector
    function reset() {
        selectedIndex = -1;
    }
    Option {
        text: "Contact"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendContact();
                qtMessageSelector.reset();
            }
        }
    }
    Option {
        text: "Calendar"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendCal();
                qtMessageSelector.reset();
            }
        }
    }
    Option {
        text: "File"
        onSelectedChanged: {
            if (selected == true) {
                _app.sendFile("/accounts/1000/shared/downloads/IMG 00000001.jpg");
                qtMessageSelector.reset();
            }
        }
    }
}
                

Selecting any of the radio buttons triggers a C++ function that creates an NDEF message with the selected NDEF Record type, and specifies that it be sent by the NfcShareManager. The sending process begins as soon as the user gently taps their device against an NFC target. The code to create and send the NDEF message of a specified type is as follows:

void ApplicationUI::sendText() {
    QString text = "Welcome to Qt NFC Text";
    QString uri = "";
    QString type = "text/plain";
    QByteArray data = createTextRecordNdef(text);
                    
    shareData.setMimeType(type);
    shareData.setData(data);
                    
    shareManager->setShareMode(NfcShareMode::Data);
    shareManager->setShareContent(shareData);
}
                    
void ApplicationUI::sendUri() {
    QString text = "";
    QString uri = "www.blackberry.com";
    QString type = "application/vnd.rim.nfc.ndef";
    QByteArray data = createUriRecordNdef(uri);
                    
    shareData.setMimeType(type);
    shareData.setData(data);
                    
    shareManager->setShareMode(NfcShareMode::Data);
    shareManager->setShareContent(shareData);
}
                    
void ApplicationUI::sendSp() {
    QString text = "Welcome to Qt NFC Smart Poster";
    QString uri = "www.blackberry.com";
    QString type = "application/vnd.rim.nfc.ndef";
    QByteArray data = createSpRecordNdef(text, uri);
                    
    shareData.setMimeType(type);
    shareData.setData(data);
                    
    shareManager->setShareMode(NfcShareMode::Data);
    shareManager->setShareContent(shareData);
}
                    
void ApplicationUI::sendContact() {
    QString type = "text/vcard";
    QByteArray data = getContactData();
                    
    shareData.setMimeType(type);
    shareData.setData(data);
                    
    shareManager->setShareMode(NfcShareMode::Data);
    shareManager->setShareContent(shareData);
}
                    
void ApplicationUI::sendCal() {
    QString type = "text/calendar";
    QByteArray data = getCalData();
                    
    shareData.setMimeType(type);
    shareData.setData(data);
                    
    shareManager->setShareMode(NfcShareMode::Data);
    shareManager->setShareContent(shareData);
}
                    
void ApplicationUI::sendFile(const QString& path) {
    QList<QUrl> *files = new QList<QUrl>();
    files->append(QUrl::fromLocalFile(path));
    shareFile.setFileUrls(*files);
                    
    shareManager->setShareMode(NfcShareMode::File);
    shareManager->setShareContent(shareFile);
}
                

The NfcShareDataContent::setData() function expects data as QByteArray. A QByteArray is the shared data container, which in this case is a binary representation of an NDEF message. The classes in QtLocationSubset allow your apps to create instances of NDEF messages, and serialize them into binary representations as QByteArray objects. The following C++ code sample creates the NDEF messages and serializes them into QByteArray objects:

QByteArray ApplicationUI::getText(const QString& text)
                    
QByteArray ApplicationUI::createUriRecordNdef(const QString& uri)
                    
QByteArray ApplicationUI::createSpRecordNdef(const QString& title, const QString& uri) 
                    
QByteArray ApplicationUI::getContactData() 
                    
QByteArray ApplicationUI::getCalendarData() 
                    
QByteArray ApplicationUI::getFilePath(const QString& path)
                

At this point your app is ready to send its content. All it has to do is to wait for user to tap another NFC target and the sharing starts.

Your app can stop sharing by setting its share mode to disabled. Disabling the share mode is useful when your app wants to receive content, but does not want to do it while sharing. The following C++ code sample demonstrates how to programmatically switch your app's sharing and receiving modes so they're exclusive:

void ApplicationUI::startReceiving() {
    shareManager->setShareMode(NfcShareMode::Disabled);
    _invokeManager->connect(_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)),
                    this, SLOT(receivedInvokeTarget(const bb::system::InvokeRequest&)));
}
                    
void ApplicationUI::startExpSharing() {
    shareManager->setShareMode(NfcShareMode::Disabled);
    _invokeManager->disconnect(_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)),
                    this, SLOT(receivedInvokeTarget(const bb::system::InvokeRequest&)));
}
                    
void ApplicationUI::startImpSharing() {
    shareManager->setShareMode(NfcShareMode::Data);
    _invokeManager->disconnect(_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)),
                    this, SLOT(receivedInvokeTarget(const bb::system::InvokeRequest&)));
}
                

The following code samples illustrate how to write to an NFC tag or an NFC device using the NFC C API (libnfc and libnfc_bps) and how to receive NFC events using BlackBerry Platform Services. This approach allows BlackBerry Platform Services to manage your app's connection to the NFC system and to deliver NFC events to your app.

Alternatively, you can set up and manage your NFC connection directly. In this approach, you receive NFC events using nfc_connect() and nfc_read_event(), manage events using nfc_get_fd() and nfc_free_event(), and disconnect from the NFC system using nfc_disconnect().

#include <bps/bps.h>
#include <nfc/nfc_bps.h>
#include <nfc/nfc.h>
#include <nfc/nfc_types.h>
#include <nfc/nfc_ndef.h>

void handle_write_event(bps_event_t event);

/* Register for both tag events and SNEP events.
 * Write an NDEF message to target.
 */
void main () {
    nfc_result_t rc = -1;

    if (bps_initialize() != BPS_SUCCESS) {
        // handle error
        ...

        return;
    }
    if (nfc_request_events() != BPS_SUCCESS) {
        // handle error
        bps_shutdown();
        return;
    }
    rc = nfc_register_tag_readerwriter(TAG_TYPE_NDEF);
    if (rc != NFC_RESULT_SUCCESS) {
        // handle error
        bps_shutdown();
        return;
    }

    // register as a SNEP client in order to
    // receive LLCP connection events
    rc = nfc_register_snep_client();
    if (rc != NFC_RESULT_SUCCESS) {
        // handle error
        bps_shutdown();
        return;
    }

    for (;;) {
        bps_event_t *event;
        if (bps_get_event(&event, BPS_EVENT_TIMEOUT) 
                != BPS_SUCCESS) {
            // handle error
            ...
        };

        handle_write_event(event);
    }
    bps_shutdown();
}

/* Write an NDEF message that contains a smart poster
 * record to a tag.
 * Write an NDEF message that contains a text record
 * to another device (through an LLCP connection).
 */
void handle_write_event(bps_event_t event) {

    nfc_ndef_record_t* rec; 
    nfc_ndef_message_t* myNdefMessage; 

    int domain = bps_event_get_domain( event );
    if( nfc_get_domain() != domain ){
        return;
    }
    ...

    if (bps_event_get_code(event) ==
               NFC_TAG_READWRITE_EVENT) {
        rc = nfc_get_nfc_event(event, &nfcEvent);

        // get target
        nfc_get_target(nfcEvent, &target);

        // create an NDEF message with an sp record 
        nfc_create_sp_record("http://abc.de", &rec);
        nfc_set_sp_type(rec, "test");

        nfc_create_ndef_message(&myNdefMessage);
        nfc_add_ndef_record(myNdefMessage, rec);

        nfc_write_ndef_message_to_tag(target, 
                                      myNdefMessage, 
                                      false);
        
        // free memory
        nfc_delete_ndef_message(myNdefMessage, true);

        nfc_destroy_target(target);
    } 

    if (bps_event_get_code(event) == 
               NFC_SNEP_CONNECTION_EVENT) {
        nfc_get_nfc_event(event, &nfc_event);
        nfc_get_target (nfc_event, &target );
    
        // create an NDEF message with a text record  
        char *textstr = "Hello";
        char *langstr = "en";
    
        nfc_create_text_record(textstr, langstr, &rec);
    
        nfc_create_ndef_message(&myNdefMessage);
        nfc_add_ndef_record(myNdefMessage, rec);
    
        nfc_push_ndef_message(target, myNdefMessage);    
    }
    // free memory
    nfc_delete_ndef_message(myNdefMessage, true);    
    nfc_destroy_target(target);
}   
                

Last modified: 2015-07-24



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus