Files:
The NFC Sender example allows a user to send content to another NFC enabled device.
In this example we'll learn how to send text data to another NFC enabled device. The business logic is encapsulated in the C++ class NfcSender, which is exported to QML under the name '_nfcSender'.
NfcSender nfcSender; QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(&app); qml->setContextProperty("_nfcSender", &nfcSender);
The UI contains a TextField and a Label with the usage description. Once the user enters some text into the field, this data will be shared with another NFC enabled device, or written to an NFC tag (through tag writing).
// The input field for the NDEF message payload TextField { inputMode: TextFieldInputMode.Text hintText: qsTr("Enter some text") onTextChanging: { _nfcSender.payload = text } } // Guide message to display to the user Label { text: qsTr("Type some text into the text field and then tap an NFC tag or device to share content") multiline: true textStyle { base: SystemDefaults.TextStyles.BodyText color: Color.White textAlign: TextAlign.Center } }
The following class is responsible for sending a text payload, using the NFC SNEP push protocol, to another NFC enabled device, or to write to an NFC tag.
NfcSender::NfcSender(QObject *parent) : QObject(parent) , m_payload(QLatin1String("Hello NFC")) { bps_initialize(); subscribe(nfc_get_domain()); const int rc = nfc_request_events(); if (rc == NFC_RESULT_SUCCESS) { qDebug() << "[INFO] Request NFC Events: NFC_RESULT_SUCCESS" << endl; } else { nfc_stop_events(); unsubscribe(nfc_get_domain()); bps_shutdown(); qDebug() << "[ERRO] Request NFC Events: NFC_RESULT_FAILURE" << endl; } nfc_register_snep_client(); }
This code does the Bps initialization for use with the current thread and subscribes to receive NFC events and registers as a snep client.
void NfcSender::event(bps_event_t *event) { uint16_t code = bps_event_get_code(event); nfc_event_t *nfc_event = 0; if (nfc_get_nfc_event(event, &nfc_event) != BPS_SUCCESS) { qDebug() << "[ERRO] Get NFC event: BPS_FAILURE" << endl; } nfc_target_t *target = 0; nfc_get_target(nfc_event, &target); switch (code) { case NFC_SNEP_CONNECTION_EVENT: { qDebug() << "[INFO] Received NFC_NDEF_PUSH_EVENT" << endl; handleSnepPush(target); } break; case NFC_NDEF_PUSH_SUCCEED_EVENT: { qDebug() << "[INFO] Received NFC_NDEF_PUSH_SUCCEED_EVENT" << endl; } break; case NFC_NDEF_PUSH_FAILURE_MSG_OVER_SIZE_EVENT: { qDebug() << "[ERRO] Received NFC_NDEF_PUSH_FAILURE_MSG_OVER_SIZE_EVENT" << endl; } break; case NFC_NDEF_PUSH_FAILURE_REJECTED_EVENT: { qDebug() << "[ERRO] Received NFC_NDEF_PUSH_FAILURE_REJECTED_EVENT" << endl; } break; case NFC_NDEF_PUSH_FAILURE_IO_ERROR_EVENT: { qDebug() << "[ERRO] Received NFC_NDEF_PUSH_FAILURE_IO_ERROR_EVENT" << endl; } break; default: { qDebug() << "[WARN] Event not handled: " << code << endl; } break; } nfc_destroy_target(target); }
This method listens to the NFC events, and upon receiving a successful NFC SNEP connection it invokes the handleSnepPush() method to deal with sending the data.
void NfcSender::handleSnepPush(nfc_target_t *target) { nfc_ndef_message_t *ndef_message; nfc_create_ndef_message(&ndef_message); nfc_ndef_record_t *record; const char* record_type = "text/plain"; const uchar_t *payload = (const uchar_t *)m_payload.toUtf8().constData(); //TODO: Kind of sketchy. const int payload_length = m_payload.toUtf8().length(); nfc_create_ndef_record(NDEF_TNF_MEDIA, record_type, payload, payload_length, 0, &record); nfc_add_ndef_record(ndef_message, record); nfc_push_ndef_message(target, ndef_message); nfc_delete_ndef_message(ndef_message, true); }
This method creates a ndefrecord that houses the payload (data), this record is than added to a standard ndefmessage which is than pushed to the other device using the SNEP protocol.