このページについて

注釈付きURL

フォーマット済みのNFCデータ交換フォーマット(NDEF)メッセージを読み取ります。

「注釈付きURL」の例では、 Qt NFC を使用して、NFCタグから読み取った特定の形式のNFCデータ交換フォーマット(NDEF)メッセージの内容を表示します。NDEFメッセージには、URIレコード、オプションのimage/* MIMEレコード、および1つ以上のローカライズされたテキストレコードが含まれている必要があります。

以下は、この例の初期状態です:

注釈付きURL NFCメイン画面

タグにタッチすると、そのNDEFコンテンツが表示されます。以下は、テキストレコードとURIレコードを含むタグのUIです:

注釈付きURLのNFCタグの詳細

画面をタップすると、URLがブラウザで開かれます。

AnnotatedUrlクラスの定義

AnnotatedUrl クラスは、NFCタグ検出機能を提供するQNearFieldManager クラスをラップしています。NDEFメッセージはQNearFieldManager によって読み取られ、AnnotatedUrl クラスに含まれるハンドラに転送されます。NDEFメッセージの解析後、このクラスはannotatedUrl() シグナルを発行します。UIはこのシグナルに応答し、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メッセージをサポートしています。正しいメッセージには、以下のフィールドが含まれている必要があります:

  • ヘッダーとして使用される、少なくとも1つのNDEFテキストレコード。
  • NDEF URIレコードが1つだけ。
  • アイコンを含むオプションのMIME レコード。

レコードの順序は厳密には指定されていません。

NDEFメッセージの検証には、QNdefFilter のインスタンスが使用されます。フィルタは次のように設定されます:

    messageFilter.setOrderMatch(false);
    messageFilter.appendRecord<QNdefNfcTextRecord>(1, 100);
    messageFilter.appendRecord<QNdefNfcUriRecord>(1, 1);
    messageFilter.appendRecord(QNdefRecord::Mime, "", 0, 1);

受信したメッセージがフィルターに一致しない場合、エラーメッセージが表示されます:

注釈付きURLのNFCタグデータ表示

注: NDEF Editorサンプルアプリケーション を使用すると、メッセージ構造が正しいタグや間違ったタグを作成できます。

AnnotatedUrl ハンドラの実装

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、Title、Pixmap)を抽出できます:

    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のマニフェストファイルに必要な変更については、「Qt NFC on Android」を参照してください。

カスタム `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()

例のプログラムの実行

サンプルは次の手順で実行できます:

code.qt.io のサンプルプロジェクト

関連項目 Qt NFC.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.