注释URL
读取格式化的NFC数据交换格式(NDEF)消息。
示例使用 Qt NFC 来显示从NFC标签中读取的特定格式化NFC数据交换格式(NDEF)消息的内容。NDEF消息应包含一个URI记录,一个可选的 image/*
MIME记录,以及一个或多个本地化的文本记录。
这是示例的初始状态
如果触摸标签,其NDEF内容将显示出来。以下是包含文本记录和URI记录的标签的用户界面
当屏幕被轻触时,将在浏览器中打开URL。
注释Url类定义
AnnotatedUrl
类封装了提供NFC标签检测功能的 QNearFieldManager 类。NDEF消息由 QNearFieldManager 读取,并转发到 AnnotatedUrl
类中包含的处理程序。解析NDEF消息后,该类发出 annotatedUrl()
信号。用户界面对该信号做出反应,以显示NDEF消息的内容。
class AnnotatedUrl : public QObject { Q_OBJECT public: explicit AnnotatedUrl(QObject *parent = 0); ~AnnotatedUrl(); void startDetection(); signals: void annotatedUrl(const QUrl &url, const QString &title, const QPixmap &pixmap); void nfcStateChanged(bool enabled); void tagError(const QString &error); public slots: void targetDetected(QNearFieldTarget *target); void targetLost(QNearFieldTarget *target); void handleMessage(const QNdefMessage &message, QNearFieldTarget *target); void handlePolledNdefMessage(QNdefMessage message); void handleAdapterStateChange(QNearFieldManager::AdapterState state); private: QNearFieldManager *manager; QNdefFilter messageFilter; };
注意:使用 startDetection()
方法延迟实际标签检测,直到 UI 和 NFC 相关逻辑之间的所有连接都已建立。当应用程序在触摸 NFC 标签后自动启动时,这种用法非常重要。目前该用法在 Android 上得到支持。
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow mainWindow; AnnotatedUrl annotatedUrl; QObject::connect(&annotatedUrl, &AnnotatedUrl::annotatedUrl, &mainWindow, &MainWindow::displayAnnotatedUrl); QObject::connect(&annotatedUrl, &AnnotatedUrl::nfcStateChanged, &mainWindow, &MainWindow::nfcStateChanged); QObject::connect(&annotatedUrl, &AnnotatedUrl::tagError, &mainWindow, &MainWindow::showTagError); annotatedUrl.startDetection(); mainWindow.show(); return a.exec(); }
消息过滤
如上所述,该应用程序支持特定格式的NDEF消息。正确的消息应包含以下字段
- 至少一个 NDEF 文本记录,它将用作标题。
- 确切一个 NDEF URI 记录。
- 可选的 带图标的 MIME 记录。
记录的顺序没有严格规定。
使用 QNdefFilter 的一个实例来验证NDEF消息。过滤器按照以下方式填充
messageFilter.setOrderMatch(false); messageFilter.appendRecord<QNdefNfcTextRecord>(1, 100); messageFilter.appendRecord<QNdefNfcUriRecord>(1, 1); messageFilter.appendRecord(QNdefRecord::Mime, "", 0, 1);
如果传入的消息与过滤器不匹配,则显示错误消息
注意:可以使用 NDEF 编辑器 示例应用程序创建具有正确或错误消息结构的标签。
注释Url处理程序实现
QNearFieldManager 读取的NFC消息被转发到 AnnotatedUrl::handleMessage
。
void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target) {
首先使用 QNdefFilter::match() 方法来验证消息
if (!messageFilter.match(message)) { emit tagError("Invalid message format"); return; }
如果消息具有正确的格式,则继续解析。
因为NFC消息由多个NDEF记录组成,所以通过遍历所有记录可以提取 UI 中要显示的 3 个参数:Uri、标题和图象。
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())); }
最终提取完NFC消息参数后,将发出相应的信号,以便UI可以处理。
} emit annotatedUrl(url, title, pixmap); }
适配器状态处理
在Android操作系统上,可以通过连接到QNearFieldManager::adapterStateChanged() 信号来检测适配器状态的变化。这允许在NFC适配器被禁用时停止检测,并且当适配器再次被启用时重新启动。此方法在 AnnotatedUrl::handleAdapterStateChange
插槽中实现。
void AnnotatedUrl::handleAdapterStateChange(QNearFieldManager::AdapterState state) { if (state == QNearFieldManager::AdapterState::Online) { startDetection(); } else if (state == QNearFieldManager::AdapterState::Offline) { manager->stopTargetDetection(); emit nfcStateChanged(false); } }
自动应用启动
Android支持在接触NDEF标签时自动启动应用。有关修改Android清单文件的必要更改,请参阅Android上的Qt NFC。
引入自定义AndroidManifest.xml需要在构建系统方面进行特殊步骤。
使用qmake构建
使用qmake时,需要将以下内容添加到.pro
文件中
android { ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android DISTFILES += \ android/AndroidManifest.xml }
使用CMake构建
使用CMake时,需要将以下内容添加到CMakeLists.txt
中
if(ANDROID) set_property(TARGET annotatedurl APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android ) endif()
运行示例
要从Qt Creator中运行示例,打开
另请参阅 Qt NFC.
© 2024 The Qt Company Ltd. 本文档中的贡献是相应所有者的版权。本提供的文档是根据GNU自由文档许可证版本1.3的条款许可的,该许可证由自由软件基金会发布。Qt及其相关商标是世界各地的芬兰和/或其他国家的The Qt Company Ltd的商标。所有其他商标均为其各自所有者的财产。