Qt NFC Overview▲
With the Qt NFC API typical use cases are:
-
Detecting NFC tags.
-
Reading and writing NDEF messages.
-
Registering NDEF message handlers.
-
Sharing files and messages.
The following sections describe how to use Qt NFC C++ classes and QML types for the above use cases.
On Android, Qt Nfc only works in foreground applications. Android services are not supported which is due to API limitations on the Android side.
C++ Overview▲
The C++ API provides access to the full feature set of the Qt NFC API. This section introduces the major features available to developers.
Detecting NFC Tags▲
m_manager = new QNearFieldManager(this);
connect(m_manager, &QNearFieldManager::targetDetected,
this, &MainWindow::targetDetected);
connect(m_manager, &QNearFieldManager::targetLost,
this, &MainWindow::targetLost);
m_manager->startTargetDetection();Finally the detection can be stopped:
m_manager->stopTargetDetection();Although each https:// instance is owned by its related https:// instance it can be beneficial to manually delete each instance. Otherwise they would continue to exist until the https:// instance is deleted. The best way to do that would be in response to the https://() signal:
void MainWindow::targetLost(QNearFieldTarget *target)
{
target->deleteLater();
}The target object should only be deleted via deleteLater() if it is deleted inside the slot.
Reading and Writing NDEF Messages▲
The https:// instance returned by https://() signal is used to interact with the tag. Reading and writing a message is an asynchronous operation. The QNearFieldTarget::RequestId class associates individual operations and their results.
void MainWindow::targetDetected(QNearFieldTarget *target)
{
switch (m_touchAction) {
case NoAction:
break;
case ReadNdef:
connect(target, &QNearFieldTarget::ndefMessageRead, this, &MainWindow::ndefMessageRead);
connect(target, &QNearFieldTarget::error, this, &MainWindow::targetError);
m_request = target->readNdefMessages();
if (!m_request.isValid()) // cannot read messages
targetError(QNearFieldTarget::NdefReadError, m_request);
break;
case WriteNdef:
connect(target, &QNearFieldTarget::ndefMessagesWritten, this, &MainWindow::ndefMessageWritten);
connect(target, &QNearFieldTarget::error, this, &MainWindow::targetError);
m_request = target->writeNdefMessages(QList<QNdefMessage>() << ndefMessage());
if (!m_request.isValid()) // cannot write messages
targetError(QNearFieldTarget::NdefWriteError, m_request);
break;
}
}Once the https://() request was successfully processed, the https://() signal is emitted. Each returned https:// may consist of zero or more https:// entries, which can be identified by their type. For more information about processing of records, see the https:// class documentation. As the above code demonstrates, writing of NDEF messages is triggered via https://(). The successful completion of the write operation is indicated by the emission of the https://() signal. Any type of error during read or write is indicated via https://().
Registering NDEF Message Handlers▲
The above described method (of reading NDEF messages) directly connects to the platform's NFC infrastructure. However on some platforms (in particular mobile platforms) this may not actually trigger the target slot if the application is currently running in the background. This is not desirable in cases where an application wants to be activated if the platform detects a tag of particular type. For this purpose the Qt NFC API provides the possibility to register an NDEF message handler. The handler is called by the operating system, when the detected NDEF message matches the given filter criteria. Depending on the platform it may even be possible to start the application that registered the handler.
This feature is not available on all platforms and, in addition to the code snippets below, may require further platform specific setup.
manager = new QNearFieldManager(this);
if (!manager->isAvailable()) {
qWarning() << "NFC not available";
return;
}
QNdefFilter filter;
filter.setOrderMatch(false);
filter.appendRecord<QNdefNfcTextRecord>(1, UINT_MAX);
filter.appendRecord<QNdefNfcUriRecord>();
// type parameter cannot specify substring so filter for "image/" below
filter.appendRecord(QNdefRecord::Mime, QByteArray(), 0, 1);
int result = manager->registerNdefMessageHandler(filter, this,
SLOT(handleMessage(QNdefMessage,QNearFieldTarget*)));For comparison an application that uses an empty NDEF filter (match all behavior) in combination with https://() would behave similarly to another application that uses https://() while being in the forground. For more information about registration details of NDEF message handlers, see the https:// class description.
The content of handleMessage() may look like the snippet below. Any incoming NDEF message of type text or uri will be processed:
void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target)
{
for (const QNdefRecord &record : message) {
if (record.isRecordType<QNdefNfcTextRecord>()) {
QNdefNfcTextRecord textRecord(record);
title = textRecord.text();
QLocale locale(textRecord.locale());
} else if (record.isRecordType<QNdefNfcUriRecord>()) {
QNdefNfcUriRecord uriRecord(record);
url = uriRecord.uri();
} else if (record.typeNameFormat() == QNdefRecord::Mime &&
record.type().startsWith("image/")) {
pixmap = QPixmap::fromImage(QImage::fromData(record.payload()));
}
}
emit annotatedUrl(url, title, pixmap);
}Sharing Files and Messages▲
The API does not make any guarantees about the actual communication bearer used during the transfer. The bearer is chosen based on the device's capabilities and the properties of the to-be-shared data.
https:// and https:// are responsible for accessing the NFC share feature.
QML Overview▲
The QML API only supports a very small subset of the Qt NFC feature set. This section outlines the available QML features.
Reading NDEF Messages▲
The user can specify NDEF filters and use those filters to register for the automatic reception of NDEF messages which match those filters. The https:// property contains the list of NDEF records of the last NDEF message read matching the given filters.
NearField {
filter: [ NdefFilter { type: "U"; typeNameFormat: NdefRecord.NfcRtd; minimum: 1; maximum: 1 } ]
orderMatch: false
onMessageRecordsChanged: displayMessage()
}If no filter is set, the message handler will match all incoming NDEF messages.


