I am trying to read NFC tags on my Android phone using the NFC Qt module.
According to this page, Qt will support NFC on Android starting from version 5.6. This version has not yet been released, so I built it from the source, following the instructions on this page and installed it in the creator of Qt.
The first step is to get work with the tag / card, and I'm stuck there. My test application instantiates a QNearFieldManager , checks to see if NFC is available, and connects the slots to the targetDetected and targetLost . The QNearFieldManager::isAvailable reports that NFC is available (it hasn’t done it since Qt 5.5), but the targetDetected / targetLost never fire.
Below is the code for my test application:
#include <QLabel> #include <QVBoxLayout> #include <QNearFieldManager> #include <QNearFieldTarget> #include <QDebug> #include "window.h" Window::Window(QWidget *parent) : QWidget(parent) { nfcLabel_ = new QLabel(this); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(nfcLabel_, 1); setLayout(mainLayout); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); setWindowTitle(tr("NFC Test")); nfc_ = new QNearFieldManager(this); if (nfc_->isAvailable()) { nfcLabel_->setText("NFC available"); } else { nfcLabel_->setText("NFC not available"); qWarning() << "NFC not available"; } nfc_->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess); // doesn't help nfc_->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*))); // doesn't help connect(nfc_, SIGNAL(targetDetected(QNearFieldTarget*)), this, SLOT(targetDetected(QNearFieldTarget*))); connect(nfc_, SIGNAL(targetLost(QNearFieldTarget*)), this, SLOT(targetLost(QNearFieldTarget*))); if (!nfc_->startTargetDetection()) { qWarning() << "NFC target detection could not be started"; } } Window::~Window() { nfc_->stopTargetDetection(); } void Window::targetDetected(QNearFieldTarget * /*target*/) { nfcLabel_->setText("Target detected"); } void Window::targetLost(QNearFieldTarget *target) { nfcLabel_->setText("Target lost"); target->deleteLater(); } void Window::handleNdefMessage(const QNdefMessage &/*message*/, QNearFieldTarget */*target*/) { qDebug() << "Ndef Message"; }
Something is missing for me ...
UPDATE 1
It looks like the AndroidManifest.xml file needs to be changed. I tried different things, but nobody seems to produce the desired effect. I can only get targetDetected and targetLost events when the manifest defines the filter intent as follows:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>
However, this also causes the application to launch each time the target is scanned, even if the application is already running. I need to run the application and then wait for the target to be verified. How can i do this?
UPDATE 2
Below is the full AndroidManifest.xml file that I tried.
<?xml version="1.0"?> <manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:theme="@android:style/Theme.Holo"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.repository" android:value="default"/> <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/> <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> <meta-data android:name="android.app.background_running" android:value="false"/> </activity> </application> <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <uses-feature android:name="android.hardware.nfc" android:required="true"/> <uses-permission android:name="android.permission.NFC"/> </manifest>