Qt NFC 概述

使用 Qt NFC API 的典型用例包括

  • 检测 NFC 标签。
  • 读取和写入 NDEF 消息。
  • 注册 NDEF 消息处理器。
  • 共享文件和消息。

以下几节将描述如何使用 Qt NFC C++ 类和 QML 类型来实现上述用例。

注意:在 Android 上,只有在前台应用程序中才能检测到新的 NFC 标签。因为 Android 侧的 API 限制,Android 服务不支持此功能。在服务中使用 Tag 的唯一方法是提供一个 AIDL 接口接受 Tag 并将其转发给 Qt,如下例所示。

public void setTag(Tag pTag) {
    Intent newIntent = new Intent();
    newIntent.putExtra(NfcAdapter.EXTRA_TAG, pTag);
    QtNative.onNewIntent(newIntent);
}

C++ 概述

C++ API 提供了对 Qt NFC API 全部功能集的访问。本节介绍了开发人员可使用的重大功能。

检测 NFC 标签

QNearFieldManager 类负责检测新的 NFC 标签进入设备的作用范围。当标签进入或离开范围时,将发出 QNearFieldManager::targetDetected() 和 QNearFieldManager::targetLost() 信号。传递的 QNearFieldTarget 参数作为每个检测到的标签的主要交互点。但是,直到调用 QNearFieldManager::startTargetDetection(),检测实际上才启动。

m_manager = new QNearFieldManager(this);
connect(m_manager, &QNearFieldManager::targetDetected,
        this, &MainWindow::targetDetected);
connect(m_manager, &QNearFieldManager::targetLost,
        this, &MainWindow::targetLost);
m_manager->startTargetDetection(QNearFieldTarget::NdefAccess);

最后,可以停止检测

m_manager->stopTargetDetection();

尽管每个 QNearFieldTarget 实例都由其相关的 QNearFieldManager 实例所有,但手动删除每个实例可能是有益的。否则,它们将继续存在,直到 QNearFieldManager 实例被删除。最好在响应到 QNearFieldManager::targetLost() 信号时这样做。

void MainWindow::targetLost(QNearFieldTarget *target)
{
    target->deleteLater();
}

注意:如果对象在槽内被删除,则应仅通过 deleteLater() 删除目标对象。

连接 NFC 标签

QNearFieldTarget 的所有需要连接的功能将自行创建一个连接。活动的连接将阻止其他实例创建连接,因为此时只允许一个连接。

Qt 5 在函数结束时断开标签,以允许其他实例连接。QNearFieldManager::setKeepConnection() 允许更改此行为。

从 Qt 6 开始,QNearFieldTarget 默认保留连接。仅当 QNearFieldTarget 被销毁或调用 QNearFieldManager::disconnect() 时,连接才会关闭。

读取和写入NDEF消息

QNearFieldTarget接口返回的实例用于与标签交互。读取和写入消息是一种异步操作。QNearFieldTarget::RequestId类关联各个操作及其结果。

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::requestCompleted, 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;
    }
}

一旦QNearFieldTarget::readNdefMessages()请求成功处理,就会发射QNearFieldTarget::ndefMessageRead()信号。每个返回的QNdefMessage可能包含零个或多个QNdefRecord条目,可以通过其类型进行识别。有关记录处理的信息,请参阅QNdefRecord类文档。如上代码所示,通过QNearFieldTarget::writeNdefMessages()触发NDEF消息的写入。写入操作的完成通过带有相应请求id的QNearFieldTarget::requestCompleted()信号指示。读取或写入过程中的任何类型的错误都通过QNearFieldTarget::error()指示。

© 2024 Qt公司。本文档中的贡献包含其各自所有者的版权。本文档根据自由软件基金会发布的《GNU自由文档许可证》版本1.3中的条款进行许可。Qt及其相关标志是芬兰的Qt公司和/或其他国家/地区的商标。所有其他商标均为各自所有者的财产。