summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Schmertmann <Lars.Schmertmann@governikus.de>2018-04-27 14:30:14 +0200
committerLars Schmertmann <lars.schmertmann@governikus.de>2018-05-30 17:28:59 +0000
commitc8e6dae2d9749179327df460755282cf5102e902 (patch)
tree27cccae4d5975163ec65019b67df479ab95232de
parent7ecded9968550011fb4d4d2e2dd02dd29c1054b3 (diff)
Use Android broadcast ACTION_ADAPTER_STATE_CHANGED
To avoid polling of the NFC adapter state a signal is added to the QNearFieldManager. Change-Id: If9e1e8025cca2deb1338fa7db255ebe171cab823 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/android/nfc/nfc.pro3
-rw-r--r--src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver.java72
-rw-r--r--src/nfc/qnearfieldmanager.cpp31
-rw-r--r--src/nfc/qnearfieldmanager.h8
-rw-r--r--src/nfc/qnearfieldmanager_android.cpp30
-rw-r--r--src/nfc/qnearfieldmanager_p.h1
6 files changed, 144 insertions, 1 deletions
diff --git a/src/android/nfc/nfc.pro b/src/android/nfc/nfc.pro
index 89026b75..a725fb7d 100644
--- a/src/android/nfc/nfc.pro
+++ b/src/android/nfc/nfc.pro
@@ -7,7 +7,8 @@ PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/nfc
JAVACLASSPATH += $$PWD/src/
JAVASOURCES += \
- $$PWD/src/org/qtproject/qt5/android/nfc/QtNfc.java
+ $$PWD/src/org/qtproject/qt5/android/nfc/QtNfc.java \
+ $$PWD/src/org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver.java \
# install
target.path = $$[QT_INSTALL_PREFIX]/jar
diff --git a/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver.java b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver.java
new file mode 100644
index 00000000..ea650ede
--- /dev/null
+++ b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver.java
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Governikus GmbH & Co. KG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNfc module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.nfc;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NfcAdapter;
+
+
+public class QtNfcBroadcastReceiver extends BroadcastReceiver
+{
+ private Context qtContext;
+
+ public QtNfcBroadcastReceiver(Context context)
+ {
+ qtContext = context;
+ IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
+ qtContext.registerReceiver(this, filter);
+ }
+
+ public void unregisterReceiver()
+ {
+ qtContext.unregisterReceiver(this);
+ }
+
+ public void onReceive(Context context, Intent intent)
+ {
+ final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_OFF);
+ jniOnReceive(state);
+ }
+
+ public native void jniOnReceive(int state);
+}
diff --git a/src/nfc/qnearfieldmanager.cpp b/src/nfc/qnearfieldmanager.cpp
index 8b46d420..73b0c360 100644
--- a/src/nfc/qnearfieldmanager.cpp
+++ b/src/nfc/qnearfieldmanager.cpp
@@ -119,6 +119,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QNearFieldManager::AdapterState
+
+ \since 5.12
+
+ This enum describes the different states a NFC adapter can have.
+
+ \value Offline The nfc adapter is offline.
+ \value TurningOn The nfc adapter is turning on.
+ \value Online The nfc adapter is online.
+ \value TurningOff The nfc adapter is turning off.
+*/
+
+/*!
\enum QNearFieldManager::TargetAccessMode
This enum describes the different access modes an application can have.
@@ -133,6 +146,16 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn void QNearFieldManager::adapterStateChanged(AdapterState state)
+
+ \since 5.12
+
+ This signal is emitted whenever the state of the NFC adapter changed.
+
+ \note Currently, this signal is only emitted on Android.
+*/
+
+/*!
\fn void QNearFieldManager::targetDetected(QNearFieldTarget *target)
This signal is emitted whenever a target is detected. The \a target parameter represents the
@@ -169,6 +192,10 @@ QT_BEGIN_NAMESPACE
QNearFieldManager::QNearFieldManager(QObject *parent)
: QObject(parent), d_ptr(new QNearFieldManagerPrivateImpl)
{
+ qRegisterMetaType<AdapterState>();
+
+ connect(d_ptr, &QNearFieldManagerPrivate::adapterStateChanged,
+ this, &QNearFieldManager::adapterStateChanged);
connect(d_ptr, SIGNAL(targetDetected(QNearFieldTarget*)),
this, SIGNAL(targetDetected(QNearFieldTarget*)));
connect(d_ptr, SIGNAL(targetLost(QNearFieldTarget*)),
@@ -186,6 +213,10 @@ QNearFieldManager::QNearFieldManager(QObject *parent)
QNearFieldManager::QNearFieldManager(QNearFieldManagerPrivate *backend, QObject *parent)
: QObject(parent), d_ptr(backend)
{
+ qRegisterMetaType<AdapterState>();
+
+ connect(d_ptr, &QNearFieldManagerPrivate::adapterStateChanged,
+ this, &QNearFieldManager::adapterStateChanged);
connect(d_ptr, SIGNAL(targetDetected(QNearFieldTarget*)),
this, SIGNAL(targetDetected(QNearFieldTarget*)));
connect(d_ptr, SIGNAL(targetLost(QNearFieldTarget*)),
diff --git a/src/nfc/qnearfieldmanager.h b/src/nfc/qnearfieldmanager.h
index 1dcb3485..500b9631 100644
--- a/src/nfc/qnearfieldmanager.h
+++ b/src/nfc/qnearfieldmanager.h
@@ -56,6 +56,13 @@ class Q_NFC_EXPORT QNearFieldManager : public QObject
Q_DECLARE_PRIVATE(QNearFieldManager)
public:
+ enum class AdapterState {
+ Offline = 1,
+ TurningOn = 2,
+ Online = 3,
+ TurningOff = 4
+ };
+ Q_ENUM(AdapterState)
enum TargetAccessMode {
NoTargetAccess = 0x00,
NdefReadTargetAccess = 0x01,
@@ -92,6 +99,7 @@ public:
bool unregisterNdefMessageHandler(int handlerId);
Q_SIGNALS:
+ void adapterStateChanged(AdapterState state);
void targetDetected(QNearFieldTarget *target);
void targetLost(QNearFieldTarget *target);
diff --git a/src/nfc/qnearfieldmanager_android.cpp b/src/nfc/qnearfieldmanager_android.cpp
index dd814787..ecefa801 100644
--- a/src/nfc/qnearfieldmanager_android.cpp
+++ b/src/nfc/qnearfieldmanager_android.cpp
@@ -48,22 +48,52 @@
#include "qdebug.h"
#include "qlist.h"
+#include <QScopedPointer>
#include <QtCore/QMetaType>
#include <QtCore/QMetaMethod>
+#include <QtCore/private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
+Q_GLOBAL_STATIC(QAndroidJniObject, broadcastReceiver)
+Q_GLOBAL_STATIC(QList<QNearFieldManagerPrivateImpl *>, broadcastListener)
+
+extern "C"
+{
+ JNIEXPORT void JNICALL Java_org_qtproject_qt5_android_nfc_QtNfcBroadcastReceiver_jniOnReceive(
+ JNIEnv */*env*/, jobject /*javaObject*/, jint state)
+ {
+ QNearFieldManager::AdapterState adapterState = static_cast<QNearFieldManager::AdapterState>((int) state);
+
+ for (const auto listener : *broadcastListener) {
+ Q_EMIT listener->adapterStateChanged(adapterState);
+ }
+ }
+}
+
QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl() :
m_detecting(false), m_handlerID(0)
{
qRegisterMetaType<QAndroidJniObject>("QAndroidJniObject");
qRegisterMetaType<QNdefMessage>("QNdefMessage");
+
+ if (!broadcastReceiver->isValid()) {
+ *broadcastReceiver = QAndroidJniObject("org/qtproject/qt5/android/nfc/QtNfcBroadcastReceiver",
+ "(Landroid/content/Context;)V", QtAndroidPrivate::context());
+ }
+ broadcastListener->append(this);
+
connect(this, SIGNAL(targetDetected(QNearFieldTarget*)), this, SLOT(handlerTargetDetected(QNearFieldTarget*)));
connect(this, SIGNAL(targetLost(QNearFieldTarget*)), this, SLOT(handlerTargetLost(QNearFieldTarget*)));
}
QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
{
+ broadcastListener->removeOne(this);
+ if (broadcastListener->isEmpty()) {
+ broadcastReceiver->callMethod<void>("unregisterReceiver");
+ *broadcastReceiver = QAndroidJniObject();
+ }
}
void QNearFieldManagerPrivateImpl::handlerTargetDetected(QNearFieldTarget *target)
diff --git a/src/nfc/qnearfieldmanager_p.h b/src/nfc/qnearfieldmanager_p.h
index 8e86ce4b..351c844a 100644
--- a/src/nfc/qnearfieldmanager_p.h
+++ b/src/nfc/qnearfieldmanager_p.h
@@ -129,6 +129,7 @@ public:
}
signals:
+ void adapterStateChanged(QNearFieldManager::AdapterState state);
void targetDetected(QNearFieldTarget *target);
void targetLost(QNearFieldTarget *target);