注釈付きURL
フォーマットされた NFC データ交換フォーマット(NDEF)メッセージを読み取ります。
注釈付き URL の例では、Qt NFC を使用して NFC タグから読み取られたフォーマットされた NFC データ交換フォーマット(NDEF)メッセージの内容を表示します。NDEFメッセージは、URIレコード、オプションのimage/*
MIMEレコード、および1つ以上のローカライズされたテキストレコードを含んでいる必要があります。
これは例の初期状態です:
タグがタッチされると、そのNDEF コンテンツが表示されます。以下は、テキストレコードとURIレコードを含むタグのUIです:
画面がタップされると、URLがブラウザで開かれます。
注釈付きURLクラスの定義
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 メッセージをサ ポートします。正しいメッセージには以下のフィールドが含まれていなければなりません:
- ヘッダーとして使用されるNDEFテキストレコードを少なくとも1つ。
- 正確に1つの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 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()
サンプルを実行する
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
Qt NFCも参照してください 。
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。