summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/android.pro1
-rw-r--r--src/android/nfc/AndroidManifest.xml7
-rw-r--r--src/android/nfc/bundledjar.pro3
-rw-r--r--src/android/nfc/distributedjar.pro2
-rw-r--r--src/android/nfc/nfc.pri13
-rw-r--r--src/android/nfc/nfc.pro3
-rw-r--r--src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java152
-rw-r--r--src/nfc/android/androidjninfc.cpp185
-rw-r--r--src/nfc/android/androidjninfc_p.h83
-rw-r--r--src/nfc/android/androidmainnewintentlistener.cpp88
-rw-r--r--src/nfc/android/androidmainnewintentlistener_p.h68
-rw-r--r--src/nfc/nfc.pro37
-rw-r--r--src/nfc/qllcpserver_android_p.cpp129
-rw-r--r--src/nfc/qllcpserver_android_p.h83
-rw-r--r--src/nfc/qllcpsocket_android_p.cpp326
-rw-r--r--src/nfc/qllcpsocket_android_p.h125
-rw-r--r--src/nfc/qnearfieldmanager.cpp2
-rw-r--r--src/nfc/qnearfieldmanager_android.cpp299
-rw-r--r--src/nfc/qnearfieldmanager_android_p.h103
-rw-r--r--src/nfc/qnearfieldtarget_android.cpp499
-rw-r--r--src/nfc/qnearfieldtarget_android_p.h111
21 files changed, 2315 insertions, 4 deletions
diff --git a/src/android/android.pro b/src/android/android.pro
index 07feb78f..f8f5c05e 100644
--- a/src/android/android.pro
+++ b/src/android/android.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
qtHaveModule(bluetooth): SUBDIRS += bluetooth
+qtHaveModule(nfc): SUBDIRS += nfc
diff --git a/src/android/nfc/AndroidManifest.xml b/src/android/nfc/AndroidManifest.xml
new file mode 100644
index 00000000..2ba062ae
--- /dev/null
+++ b/src/android/nfc/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.qt5.android.nfc"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
+</manifest>
diff --git a/src/android/nfc/bundledjar.pro b/src/android/nfc/bundledjar.pro
new file mode 100644
index 00000000..37f7fc82
--- /dev/null
+++ b/src/android/nfc/bundledjar.pro
@@ -0,0 +1,3 @@
+TARGET = QtNfc-bundled
+CONFIG += bundled_jar_file
+include(nfc.pri)
diff --git a/src/android/nfc/distributedjar.pro b/src/android/nfc/distributedjar.pro
new file mode 100644
index 00000000..ed65c50a
--- /dev/null
+++ b/src/android/nfc/distributedjar.pro
@@ -0,0 +1,2 @@
+TARGET = QtNfc
+include(nfc.pri)
diff --git a/src/android/nfc/nfc.pri b/src/android/nfc/nfc.pri
new file mode 100644
index 00000000..65f197ca
--- /dev/null
+++ b/src/android/nfc/nfc.pri
@@ -0,0 +1,13 @@
+CONFIG += java
+DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
+API_VERSION = android-10
+
+PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/nfc
+
+JAVACLASSPATH += $$PWD/src/
+JAVASOURCES += \
+ $$PWD/src/org/qtproject/qt5/android/nfc/QtNfc.java
+
+# install
+target.path = $$[QT_INSTALL_PREFIX]/jar
+INSTALLS += target
diff --git a/src/android/nfc/nfc.pro b/src/android/nfc/nfc.pro
new file mode 100644
index 00000000..70373fe1
--- /dev/null
+++ b/src/android/nfc/nfc.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += bundledjar.pro distributedjar.pro
+
diff --git a/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java
new file mode 100644
index 00000000..b838fac1
--- /dev/null
+++ b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java
@@ -0,0 +1,152 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.nfc;
+
+import java.lang.Thread;
+import java.lang.Runnable;
+
+import android.os.Parcelable;
+import android.os.Looper;
+import android.content.Context;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NfcAdapter;
+import android.content.IntentFilter.MalformedMimeTypeException;
+import android.os.Bundle;
+//import android.util.Log;
+import android.content.BroadcastReceiver;
+
+public class QtNfc
+{
+ /* static final QtNfc m_nfc = new QtNfc(); */
+ static private final String TAG = "QtNfc";
+ static public NfcAdapter m_adapter = null;
+ static public PendingIntent m_pendingIntent = null;
+ static public IntentFilter[] m_filters;
+ static public Activity m_activity;
+
+ static public void setActivity(Activity activity, Object activityDelegate)
+ {
+ //Log.d(TAG, "setActivity " + activity);
+ m_activity = activity;
+ m_adapter = NfcAdapter.getDefaultAdapter(m_activity);
+ if (m_adapter == null) {
+ //Log.e(TAG, "No NFC available");
+ return;
+ }
+ m_pendingIntent = PendingIntent.getActivity(
+ m_activity,
+ 0,
+ new Intent(m_activity, m_activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
+ 0);
+
+ //Log.d(TAG, "Pending intent:" + m_pendingIntent);
+
+ IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+
+ m_filters = new IntentFilter[]{
+ filter
+ };
+
+ try {
+ filter.addDataType("*/*");
+ } catch(MalformedMimeTypeException e) {
+ throw new RuntimeException("Fail", e);
+ }
+
+ //Log.d(TAG, "Thread:" + Thread.currentThread().getId());
+ }
+
+ static public void start()
+ {
+ if (m_adapter == null) return;
+ m_activity.runOnUiThread(new Runnable() {
+ public void run() {
+ //Log.d(TAG, "Enabling NFC");
+ IntentFilter[] filters = new IntentFilter[2];
+ filters[0] = new IntentFilter();
+ filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
+ filters[0].addCategory(Intent.CATEGORY_DEFAULT);
+ try {
+ filters[0].addDataType("*/*");
+ } catch (MalformedMimeTypeException e) {
+ throw new RuntimeException("Check your mime type.");
+ }
+ // some tags will report as tech, even if they are ndef formated/formatable.
+ filters[1] = new IntentFilter();
+ filters[1].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
+ String[][] techList = new String[][]{
+ {"android.nfc.tech.Ndef"},
+ {"android.nfc.tech.NdefFormatable"}
+ };
+ try {
+ m_adapter.enableForegroundDispatch(m_activity, m_pendingIntent, filters, techList);
+ } catch(IllegalStateException e) {
+ throw new RuntimeException("Fail", e);
+ }
+ }
+ });
+ }
+
+ static public void stop()
+ {
+ if (m_adapter == null) return;
+ m_activity.runOnUiThread(new Runnable() {
+ public void run() {
+ //Log.d(TAG, "Disabling NFC");
+ m_adapter.disableForegroundDispatch(m_activity);
+ }
+ });
+ }
+
+ static public boolean isAvailable()
+ {
+ m_adapter = NfcAdapter.getDefaultAdapter(m_activity);
+ if (m_adapter == null) {
+ //Log.e(TAG, "No NFC available (Adapter is null)");
+ return false;
+ }
+ return m_adapter.isEnabled();
+ }
+}
diff --git a/src/nfc/android/androidjninfc.cpp b/src/nfc/android/androidjninfc.cpp
new file mode 100644
index 00000000..424db381
--- /dev/null
+++ b/src/nfc/android/androidjninfc.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjninfc_p.h"
+
+#include <android/log.h>
+
+#include "androidmainnewintentlistener_p.h"
+
+#include "qglobal.h"
+#include "qbytearray.h"
+#include "qdebug.h"
+
+static JavaVM *javaVM = 0;
+static jclass nfcClass;
+
+static jmethodID startDiscoveryId;
+static jmethodID stopDiscoveryId;
+static jmethodID isAvailableId;
+
+static AndroidNfc::MainNfcNewIntentListener mainListener;
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+AttachedJNIEnv::AttachedJNIEnv()
+{
+ Q_ASSERT_X(javaVM != 0, "constructor", "javaVM pointer is null");
+ attached = false;
+ if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
+ if (javaVM->AttachCurrentThread(&jniEnv, NULL) < 0) {
+ __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
+ jniEnv = 0;
+ return;
+ }
+ attached = true;
+ }
+}
+
+AttachedJNIEnv::~AttachedJNIEnv()
+{
+ if (attached)
+ javaVM->DetachCurrentThread();
+}
+
+bool startDiscovery()
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "QtNfc::startDiscovery()");
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ aenv.jniEnv->CallStaticObjectMethod(nfcClass, startDiscoveryId);
+ return true;
+}
+
+bool isAvailable()
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "QtNfc::isAvailable()");
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ return aenv.jniEnv->CallStaticBooleanMethod(nfcClass, isAvailableId);
+}
+
+bool stopDiscovery()
+{
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ aenv.jniEnv->CallStaticObjectMethod(nfcClass, stopDiscoveryId);
+ return true;
+}
+
+bool registerListener(AndroidNfcListenerInterface *listener)
+{
+ return mainListener.registerListener(listener);
+}
+
+bool unregisterListener(AndroidNfcListenerInterface *listener)
+{
+ return mainListener.unregisterListener(listener);
+}
+
+jobject getTag(JNIEnv *env, jobject intent)
+{
+ jclass intentClass = env->GetObjectClass(intent);
+ Q_ASSERT_X(intentClass != 0, "getTag", "could not get Intent class");
+
+ jmethodID getParcelableExtraMID = env->GetMethodID(intentClass,
+ "getParcelableExtra",
+ "(Ljava/lang/String;)Landroid/os/Parcelable;");
+ Q_ASSERT_X(getParcelableExtraMID != 0, "getTag", "could not get method ID for getParcelableExtra()");
+
+ jclass nfcAdapterClass = env->FindClass("android/nfc/NfcAdapter");
+ Q_ASSERT_X(nfcAdapterClass != 0, "getTag", "could not find NfcAdapter class");
+
+ jfieldID extraTagFID = env->GetStaticFieldID(nfcAdapterClass, "EXTRA_TAG", "Ljava/lang/String;");
+ Q_ASSERT_X(extraTagFID != 0, "getTag", "could not get field ID for EXTRA_TAG");
+
+ jobject extraTag = env->GetStaticObjectField(nfcAdapterClass, extraTagFID);
+ Q_ASSERT_X(extraTag != 0, "getTag", "could not get EXTRA_TAG");
+
+ jobject tag = env->CallObjectMethod(intent, getParcelableExtraMID, extraTag);
+ Q_ASSERT_X(tag != 0, "getTag", "could not get Tag object");
+
+ return tag;
+}
+
+QT_END_ANDROIDNFC_NAMESPACE
+
+static const char logTag[] = "Qt";
+static const char classErrorMsg[] = "Can't find class \"%s\"";
+static const char methodErrorMsg[] = "Can't find method \"%s%s\"";
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+ clazz = env->FindClass(CLASS_NAME); \
+ if (!clazz) { \
+ return JNI_FALSE; \
+ }
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ return JNI_FALSE; \
+ }
+
+Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "JNI_OnLoad for QtNfc");
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return -1;
+ }
+
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/nfc/QtNfc");
+ nfcClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+ GET_AND_CHECK_STATIC_METHOD(startDiscoveryId, nfcClass, "start", "()V");
+ GET_AND_CHECK_STATIC_METHOD(stopDiscoveryId, nfcClass, "stop", "()V");
+ GET_AND_CHECK_STATIC_METHOD(isAvailableId, nfcClass, "isAvailable", "()Z");
+ javaVM = vm;
+
+ return JNI_VERSION_1_6;
+}
diff --git a/src/nfc/android/androidjninfc_p.h b/src/nfc/android/androidjninfc_p.h
new file mode 100644
index 00000000..dbd2867a
--- /dev/null
+++ b/src/nfc/android/androidjninfc_p.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDJNINFC_H
+#define ANDROIDJNINFC_H
+
+#include "qglobal.h"
+
+#include <jni.h>
+
+#define QT_USE_ANDROIDNFC_NAMESPACE using namespace ::AndroidNfc;
+#define QT_BEGIN_ANDROIDNFC_NAMESPACE namespace AndroidNfc {
+#define QT_END_ANDROIDNFC_NAMESPACE }
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+class AndroidNfcListenerInterface
+{
+public:
+ virtual ~AndroidNfcListenerInterface(){}
+ virtual void newIntent(jobject intent) = 0;
+};
+
+class AttachedJNIEnv
+{
+public:
+ AttachedJNIEnv();
+ virtual ~AttachedJNIEnv();
+ bool attached;
+ JNIEnv *jniEnv;
+
+private:
+ Q_DISABLE_COPY(AttachedJNIEnv)
+};
+
+bool startDiscovery();
+bool stopDiscovery();
+bool isAvailable();
+bool registerListener(AndroidNfcListenerInterface *listener);
+bool unregisterListener(AndroidNfcListenerInterface *listener);
+jobject getTag(JNIEnv *env, jobject intent);
+
+QT_END_ANDROIDNFC_NAMESPACE
+
+#endif
diff --git a/src/nfc/android/androidmainnewintentlistener.cpp b/src/nfc/android/androidmainnewintentlistener.cpp
new file mode 100644
index 00000000..d27dac18
--- /dev/null
+++ b/src/nfc/android/androidmainnewintentlistener.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 BasysKom GmbH
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidmainnewintentlistener_p.h"
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+MainNfcNewIntentListener::MainNfcNewIntentListener()
+ : listeners(), listenersLock()
+{
+ QtAndroidPrivate::registerNewIntentListener(this);
+}
+
+MainNfcNewIntentListener::~MainNfcNewIntentListener()
+{
+ QtAndroidPrivate::unregisterNewIntentListener(this);
+}
+
+bool MainNfcNewIntentListener::handleNewIntent(JNIEnv *env, jobject intent)
+{
+ AndroidNfc::AttachedJNIEnv aenv;
+ listenersLock.lockForRead();
+ foreach (AndroidNfc::AndroidNfcListenerInterface *listener, listeners) {
+ // Making new global reference for each listener.
+ // Listeners must release reference when it is not used anymore.
+ jobject newIntentRef = env->NewGlobalRef(intent);
+ listener->newIntent(newIntentRef);
+ }
+ listenersLock.unlock();
+ return true;
+}
+
+bool MainNfcNewIntentListener::registerListener(AndroidNfcListenerInterface *listener)
+{
+ listenersLock.lockForWrite();
+ if (!listeners.contains(listener))
+ listeners.push_back(listener);
+ listenersLock.unlock();
+ return true;
+}
+
+bool MainNfcNewIntentListener::unregisterListener(AndroidNfcListenerInterface *listener)
+{
+ listenersLock.lockForWrite();
+ listeners.removeOne(listener);
+ listenersLock.unlock();
+ return true;
+}
+
+QT_END_ANDROIDNFC_NAMESPACE
diff --git a/src/nfc/android/androidmainnewintentlistener_p.h b/src/nfc/android/androidmainnewintentlistener_p.h
new file mode 100644
index 00000000..34541214
--- /dev/null
+++ b/src/nfc/android/androidmainnewintentlistener_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 BasysKom GmbH
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDMAINNEWINTENTLISTENER_P_H_
+#define ANDROIDMAINNEWINTENTLISTENER_P_H_
+
+#include <QtCore/private/qjnihelpers_p.h>
+
+#include "qlist.h"
+#include "qreadwritelock.h"
+#include "androidjninfc_p.h"
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+class MainNfcNewIntentListener : public QtAndroidPrivate::NewIntentListener
+{
+public:
+ MainNfcNewIntentListener();
+ ~MainNfcNewIntentListener();
+ bool handleNewIntent(JNIEnv *env, jobject intent);
+ bool registerListener(AndroidNfcListenerInterface *listener);
+ bool unregisterListener(AndroidNfcListenerInterface *listener);
+protected:
+ QList<AndroidNfc::AndroidNfcListenerInterface*> listeners;
+ QReadWriteLock listenersLock;
+};
+
+QT_END_ANDROIDNFC_NAMESPACE
+
+#endif /* ANDROIDMAINNEWINTENTLISTENER_P_H_ */
diff --git a/src/nfc/nfc.pro b/src/nfc/nfc.pro
index 7c6b6ff7..9ef57dad 100644
--- a/src/nfc/nfc.pro
+++ b/src/nfc/nfc.pro
@@ -98,9 +98,8 @@ CONFIG(blackberry) {
qnearfieldsharemanagerimpl_p.h \
qnearfieldsharetargetimpl_p.h
}
-}
-linux:qtHaveModule(dbus) {
+} else:linux:!android:qtHaveModule(dbus) {
NFC_BACKEND_AVAILABLE = yes
QT += dbus
@@ -123,9 +122,8 @@ linux:qtHaveModule(dbus) {
qnearfieldmanager_neard.cpp
include(neard/neard.pri)
-}
-simulator {
+} else:simulator {
NFC_BACKEND_AVAILABLE = yes
QT *= gui
@@ -146,6 +144,37 @@ simulator {
qllcpserver_simulator_p.cpp \
qnearfieldsharemanagerimpl_p.cpp \
qnearfieldsharetargetimpl_p.cpp
+} else:android:!android-no-sdk {
+ NFC_BACKEND_AVAILABLE = yes
+ ANDROID_PERMISSIONS = \
+ android.permission.NFC
+ ANDROID_BUNDLED_JAR_DEPENDENCIES = \
+ jar/QtNfc-bundled.jar:org.qtproject.qt5.android.nfc.QtNfc
+ ANDROID_JAR_DEPENDENCIES = \
+ jar/QtNfc.jar:org.qtproject.qt5.android.nfc.QtNfc
+ DEFINES += ANDROID_NFC
+ QT += core-private
+
+ PRIVATE_HEADERS += \
+ qllcpserver_android_p.h \
+ qllcpsocket_android_p.h \
+ android/androidjninfc_p.h \
+ qnearfieldmanager_android_p.h \
+ qnearfieldtarget_android_p.h \
+ qnearfieldsharemanagerimpl_p.h \
+ qnearfieldsharetargetimpl_p.h \
+ android/androidmainnewintentlistener_p.h
+
+
+ SOURCES += \
+ qllcpserver_android_p.cpp \
+ qllcpsocket_android_p.cpp \
+ android/androidjninfc.cpp \
+ qnearfieldmanager_android.cpp \
+ qnearfieldtarget_android.cpp \
+ qnearfieldsharemanagerimpl_p.cpp \
+ qnearfieldsharetargetimpl_p.cpp \
+ android/androidmainnewintentlistener.cpp
}
isEmpty(NFC_BACKEND_AVAILABLE) {
diff --git a/src/nfc/qllcpserver_android_p.cpp b/src/nfc/qllcpserver_android_p.cpp
new file mode 100644
index 00000000..9a8f7dd0
--- /dev/null
+++ b/src/nfc/qllcpserver_android_p.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver_android_p.h"
+//#include "qnx/qnxnfcmanager_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QLlcpServerPrivate::QLlcpServerPrivate(QLlcpServer *q)
+ : q_ptr(q), m_llcpSocket(0), m_connected(false)
+{
+}
+
+bool QLlcpServerPrivate::listen(const QString &/*serviceUri*/)
+{
+ /*//The server is already listening
+ if (isListening())
+ return false;
+
+ nfc_result_t result = nfc_llcp_register_connection_listener(NFC_LLCP_SERVER, 0, serviceUri.toStdString().c_str(), &m_conListener);
+ m_connected = true;
+ if (result == NFC_RESULT_SUCCESS) {
+ m_serviceUri = serviceUri;
+ qQNXNFCDebug() << "LLCP server registered" << serviceUri;
+ } else {
+ qWarning() << Q_FUNC_INFO << "Could not register for llcp connection listener";
+ return false;
+ }
+ QNXNFCManager::instance()->registerLLCPConnection(m_conListener, this);*/
+ return true;
+}
+
+bool QLlcpServerPrivate::isListening() const
+{
+ return m_connected;
+}
+
+void QLlcpServerPrivate::close()
+{
+ /*nfc_llcp_unregister_connection_listener(m_conListener);
+ QNXNFCManager::instance()->unregisterLLCPConnection(m_conListener);
+ m_serviceUri = QString();
+ m_connected = false;*/
+}
+
+QString QLlcpServerPrivate::serviceUri() const
+{
+ return m_serviceUri;
+}
+
+quint8 QLlcpServerPrivate::serverPort() const
+{
+ /*unsigned int sap;
+ if (nfc_llcp_get_local_sap(m_target, &sap) == NFC_RESULT_SUCCESS) {
+ return sap;
+ }*/
+ return -1;
+}
+
+bool QLlcpServerPrivate::hasPendingConnections() const
+{
+ return m_llcpSocket != 0;
+}
+
+QLlcpSocket *QLlcpServerPrivate::nextPendingConnection()
+{
+ /*QLlcpSocket *socket = m_llcpSocket;
+ m_llcpSocket = 0;
+ return socket;*/
+ return 0;
+}
+
+QLlcpSocket::SocketError QLlcpServerPrivate::serverError() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
+
+/*void QLlcpServerPrivate::connected(nfc_target_t *target)
+{
+ m_target = target;
+ if (m_llcpSocket != 0) {
+ qWarning() << Q_FUNC_INFO << "LLCP socket not cloesed properly";
+ return;
+ }
+ m_llcpSocket = new QLlcpSocket();
+ m_llcpSocket->bind(serverPort());
+}*/
+
+QT_END_NAMESPACE
+
+
diff --git a/src/nfc/qllcpserver_android_p.h b/src/nfc/qllcpserver_android_p.h
new file mode 100644
index 00000000..24e7854e
--- /dev/null
+++ b/src/nfc/qllcpserver_android_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_ANDROID_P_H
+#define QLLCPSERVER_ANDROID_P_H
+
+#include "qllcpserver_p.h"
+//#include "nfc/nfc.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLlcpServerPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QLlcpServerPrivate(QLlcpServer *q);
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ bool hasPendingConnections() const;
+ QLlcpSocket *nextPendingConnection();
+
+ QLlcpSocket::SocketError serverError() const;
+
+ //Q_INVOKABLE void connected(nfc_target_t *);
+
+private:
+ QLlcpServer *q_ptr;
+ QLlcpSocket *m_llcpSocket;
+ //We can not use m_conListener for the connection state
+ bool m_connected;
+ //nfc_llcp_connection_listener_t m_conListener;
+ QString m_serviceUri;
+ //nfc_target_t *m_target;
+};
+
+QT_END_NAMESPACE
+
+#endif // QLLCPSERVER_ANDROID_P_H
diff --git a/src/nfc/qllcpsocket_android_p.cpp b/src/nfc/qllcpsocket_android_p.cpp
new file mode 100644
index 00000000..db1bb972
--- /dev/null
+++ b/src/nfc/qllcpsocket_android_p.cpp
@@ -0,0 +1,326 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket_android_p.h"
+#include <unistd.h>
+
+QT_BEGIN_NAMESPACE
+
+QLlcpSocketPrivate::QLlcpSocketPrivate(QLlcpSocket *q)
+ : q_ptr(q), m_state(QLlcpSocket::UnconnectedState), m_server(false)
+{
+}
+
+QLlcpSocketPrivate::~QLlcpSocketPrivate()
+{
+ disconnectFromService();
+}
+
+void QLlcpSocketPrivate::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_UNUSED(target)
+ Q_UNUSED(serviceUri)
+ /*if (m_state != QLlcpSocket::UnconnectedState) {
+ qWarning() << Q_FUNC_INFO << "socket is already connected";
+ return;
+ }
+
+ m_state = QLlcpSocket::ConnectingState;
+ if (nfc_llcp_register_connection_listener(NFC_LLCP_CLIENT, 0, serviceUri.toLocal8Bit().constData(),
+ &m_conListener) != NFC_RESULT_SUCCESS) {
+ qWarning() << Q_FUNC_INFO << "could not register for connection listener";
+ return;
+ }
+
+ QNXNFCManager::instance()->registerLLCPConnection(m_conListener, this);
+
+ qQNXNFCDebug() << "Connecting client socket" << serviceUri << m_conListener;
+ connect(QNXNFCManager::instance(), SIGNAL(llcpDisconnected()), this, SLOT(disconnectFromService()));*/
+}
+
+void QLlcpSocketPrivate::disconnectFromService()
+{
+ /*Q_Q(QLlcpSocket);
+ QNXNFCManager::instance()->unregisterTargetLost(this);
+ qQNXNFCDebug() << "Shutting down LLCP socket";
+ if (!m_server && nfc_llcp_unregister_connection_listener(m_conListener) != NFC_RESULT_SUCCESS) {
+ qWarning() << Q_FUNC_INFO << "Error when trying to close LLCP socket";
+ }
+ QNXNFCManager::instance()->unregisterLLCPConnection(m_conListener);
+ disconnect(QNXNFCManager::instance(), SIGNAL(llcpDisconnected()), this, SLOT(disconnectFromService()));
+
+ q->disconnected();
+ m_conListener = 0;
+ m_state = QLlcpSocket::UnconnectedState;*/
+}
+
+bool QLlcpSocketPrivate::bind(quint8 port)
+{
+ Q_UNUSED(port);
+
+ /*m_state = QLlcpSocket::ConnectedState;
+ m_server = true;
+ connect(QNXNFCManager::instance(), SIGNAL(llcpDisconnected()), this, SLOT(disconnectFromService()));
+ connected(QNXNFCManager::instance()->getLastTarget());*/
+
+ return true;
+}
+
+bool QLlcpSocketPrivate::hasPendingDatagrams() const
+{
+ return !m_receivedDatagrams.isEmpty();
+}
+
+qint64 QLlcpSocketPrivate::pendingDatagramSize() const
+{
+ if (m_receivedDatagrams.isEmpty())
+ return -1;
+
+ return m_receivedDatagrams.first().length();
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size)
+{
+ if (m_state == QLlcpSocket::ConnectedState)
+ return writeData(data, size);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
+{
+ return writeDatagram(datagram.constData(), datagram.size());
+}
+
+qint64 QLlcpSocketPrivate::readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ if (m_state == QLlcpSocket::ConnectedState)
+ return readData(data, maxSize);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return writeDatagram(data, size);
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(datagram);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return writeDatagram(datagram.constData(), datagram.size()-1);
+}
+
+QLlcpSocket::SocketError QLlcpSocketPrivate::error() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
+
+QLlcpSocket::SocketState QLlcpSocketPrivate::state() const
+{
+ return m_state;
+}
+
+qint64 QLlcpSocketPrivate::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
+ if (m_receivedDatagrams.isEmpty())
+ return 0;
+
+ /*const QByteArray datagram = m_receivedDatagrams.takeFirst();
+ qint64 size = qMin(maxlen, qint64(datagram.length()));
+ memcpy(data, datagram.constData(), size);
+ return size;*/
+ return 0;
+}
+
+qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+ /*if (socketState != Idle) {
+ m_writeQueue.append(QByteArray(data, len));
+ return len;
+ } else {
+ socketState = Writing;
+ qQNXNFCDebug() << "LLCP write";
+ nfc_result_t res = nfc_llcp_write(m_target, (uchar_t*)data, (size_t)len);
+ if (res == NFC_RESULT_SUCCESS) {
+ return len;
+ } else {
+ qWarning() << Q_FUNC_INFO << "Error writing to LLCP socket. Error" << res;
+ enteringIdle();
+ return -1;
+ }
+ }*/
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::bytesAvailable() const
+{
+ /*qint64 available = 0;
+ foreach (const QByteArray &datagram, m_receivedDatagrams)
+ available += datagram.length();
+
+ return available;*/
+ return 0;
+}
+
+bool QLlcpSocketPrivate::canReadLine() const
+{
+ /*foreach (const QByteArray &datagram, m_receivedDatagrams) {
+ if (datagram.contains('\n'))
+ return true;
+ }*/
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForReadyRead(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForBytesWritten(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForConnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForDisconnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+/*void QLlcpSocketPrivate::connected(nfc_target_t *target)
+{
+ Q_Q(QLlcpSocket);
+ m_target = target;
+
+ m_state = QLlcpSocket::ConnectedState;
+ emit q->connected();
+ qQNXNFCDebug() << "Socket connected";
+
+ unsigned int targetId;
+ nfc_get_target_connection_id(target, &targetId);
+ QNXNFCManager::instance()->requestTargetLost(this, targetId);
+ enteringIdle();
+}*/
+
+void QLlcpSocketPrivate::targetLost()
+{
+ disconnectFromService();
+ //qQNXNFCDebug() << "LLCP target lost...socket disconnected";
+}
+
+void QLlcpSocketPrivate::dataRead(QByteArray& data)
+{
+ Q_UNUSED(data);
+ /*Q_Q(QLlcpSocket);
+ if (!data.isEmpty()) {
+ m_receivedDatagrams.append(data);
+ emit q->readyRead();
+ }
+ socketState = Idle;
+ enteringIdle();*/
+}
+
+void QLlcpSocketPrivate::dataWritten()
+{
+ //enteringIdle();
+}
+
+void QLlcpSocketPrivate::read()
+{
+ /*if (socketState != Idle) {
+ qQNXNFCDebug() << "Trying to read but socket state not in idle..abort";
+ return;
+ }
+ socketState = Reading;
+ qQNXNFCDebug() << "LLCP read";
+ if (nfc_llcp_read(m_target, 128) != NFC_RESULT_SUCCESS) {
+ qWarning() << Q_FUNC_INFO << "Could not register for reading";
+ socketState = Idle;
+ }*/
+}
+
+void QLlcpSocketPrivate::enteringIdle()
+{
+ /*qQNXNFCDebug() << "entering idle; Socket state:" << socketState;
+ socketState = Idle;
+ if (m_state == QLlcpSocket::ConnectedState) {
+ if (m_writeQueue.isEmpty()) {
+ qQNXNFCDebug() << "Write queue empty, reading in 50ms";
+ QTimer::singleShot(50, this, SLOT(read()));
+ } else {
+ qQNXNFCDebug() << "Write first package in queue";
+ writeDatagram(m_writeQueue.takeFirst());
+ }
+ }*/
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/nfc/qllcpsocket_android_p.h b/src/nfc/qllcpsocket_android_p.h
new file mode 100644
index 00000000..afbc573e
--- /dev/null
+++ b/src/nfc/qllcpsocket_android_p.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_ANDROID_P_H
+#define QLLCPSOCKET_ANDROID_P_H
+
+#include "qllcpsocket_p.h"
+
+//#include "qnearfieldtarget_ANDROID_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLlcpSocketPrivate : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PUBLIC(QLlcpSocket)
+
+public:
+ QLlcpSocketPrivate(QLlcpSocket *q);
+
+ ~QLlcpSocketPrivate();
+
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ QLlcpSocket::SocketError error() const;
+ QLlcpSocket::SocketState state() const;
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs);
+ bool waitForBytesWritten(int msecs);
+ bool waitForConnected(int msecs);
+ bool waitForDisconnected(int msecs);
+
+ //Q_INVOKABLE void connected(nfc_target_t *);
+ Q_INVOKABLE void targetLost();
+
+ void dataRead(QByteArray&);
+ void dataWritten();
+
+public Q_SLOTS:
+ void disconnectFromService();
+
+private:
+ QLlcpSocket *q_ptr;
+ unsigned int m_sap;
+ //nfc_llcp_connection_listener_t m_conListener;
+ //NearFieldTarget *m_target;
+ //nfc_target_t *m_target;
+
+ QLlcpSocket::SocketState m_state;
+
+ QList<QByteArray> m_receivedDatagrams;
+ QList<QByteArray> m_writeQueue;
+
+ bool m_server;
+
+ enum llcpState {
+ Idle, Reading, Writing
+ } socketState;
+
+private Q_SLOTS:
+ void read();
+ void enteringIdle();
+};
+
+QT_END_NAMESPACE
+
+#endif // QLLCPSOCKET_ANDROID_P_H
diff --git a/src/nfc/qnearfieldmanager.cpp b/src/nfc/qnearfieldmanager.cpp
index 7aaf0878..50bee6b1 100644
--- a/src/nfc/qnearfieldmanager.cpp
+++ b/src/nfc/qnearfieldmanager.cpp
@@ -40,6 +40,8 @@
#include "qnearfieldmanager_qnx_p.h"
#elif defined(NEARD_NFC)
#include "qnearfieldmanager_neard_p.h"
+#elif defined(ANDROID_NFC)
+#include "qnearfieldmanager_android_p.h"
#else
#include "qnearfieldmanagerimpl_p.h"
#endif
diff --git a/src/nfc/qnearfieldmanager_android.cpp b/src/nfc/qnearfieldmanager_android.cpp
new file mode 100644
index 00000000..bcc90ecf
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_android.cpp
@@ -0,0 +1,299 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager_android_p.h"
+#include "qnearfieldtarget_android_p.h"
+
+#include "qndeffilter.h"
+#include "qndefmessage.h"
+#include "qndefrecord.h"
+#include "qbytearray.h"
+#include "qcoreapplication.h"
+#include "qdebug.h"
+#include "qlist.h"
+
+#include <QtCore/QMetaType>
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_NAMESPACE
+
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl() :
+ m_detecting(false), m_handlerID(0)
+{
+ qRegisterMetaType<jobject>("jobject");
+ qRegisterMetaType<QNdefMessage>("QNdefMessage");
+ connect(this, SIGNAL(targetDetected(QNearFieldTarget*)), this, SLOT(handlerTargetDetected(QNearFieldTarget*)));
+ connect(this, SIGNAL(targetLost(QNearFieldTarget*)), this, SLOT(handlerTargetLost(QNearFieldTarget*)));
+}
+
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+}
+
+void QNearFieldManagerPrivateImpl::handlerTargetDetected(QNearFieldTarget *target)
+{
+ if (ndefMessageHandlers.count() == 0 && ndefFilterHandlers.count() == 0) // if no handler is registered
+ return;
+ if (target->hasNdefMessage()) {
+ connect(target, SIGNAL(ndefMessageRead(const QNdefMessage &, const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerNdefMessageRead(const QNdefMessage &, const QNearFieldTarget::RequestId &)));
+ connect(target, SIGNAL(requestCompleted(const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerRequestCompleted(const QNearFieldTarget::RequestId &)));
+ connect(target, SIGNAL(error(QNearFieldTarget::Error, const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerError(QNearFieldTarget::Error, const QNearFieldTarget::RequestId &)));
+
+ QNearFieldTarget::RequestId id = target->readNdefMessages();
+ m_idToTarget.insert(id, target);
+ }
+}
+
+void QNearFieldManagerPrivateImpl::handlerTargetLost(QNearFieldTarget *target)
+{
+ disconnect(target, SIGNAL(ndefMessageRead(const QNdefMessage &, const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerNdefMessageRead(const QNdefMessage &, const QNearFieldTarget::RequestId &)));
+ disconnect(target, SIGNAL(requestCompleted(const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerRequestCompleted(const QNearFieldTarget::RequestId &)));
+ disconnect(target, SIGNAL(error(QNearFieldTarget::Error, const QNearFieldTarget::RequestId &)),
+ this, SLOT(handlerError(QNearFieldTarget::Error, const QNearFieldTarget::RequestId &)));
+ m_idToTarget.remove(m_idToTarget.key(target));
+}
+
+void QNearFieldManagerPrivateImpl::handlerNdefMessageRead(const QNdefMessage &message, const QNearFieldTarget::RequestId &id)
+{
+ QNearFieldTarget *target = m_idToTarget.value(id);
+ //For message handlers without filters
+ for (int i = 0; i < ndefMessageHandlers.count(); i++) {
+ ndefMessageHandlers.at(i).second.invoke(ndefMessageHandlers.at(i).first.second, Q_ARG(QNdefMessage, message), Q_ARG(QNearFieldTarget*, target));
+ }
+
+ //For message handlers that specified a filter
+ for (int i = 0; i < ndefFilterHandlers.count(); ++i) {
+ QNdefFilter filter = ndefFilterHandlers.at(i).second.first;
+ if (filter.recordCount() > message.count())
+ continue;
+
+ int j;
+ for (j = 0; j < filter.recordCount();) {
+ if (message.at(j).typeNameFormat() != filter.recordAt(j).typeNameFormat
+ || message.at(j).type() != filter.recordAt(j).type ) {
+ break;
+ }
+ ++j;
+ }
+ if (j == filter.recordCount())
+ ndefFilterHandlers.at(i).second.second.invoke(ndefFilterHandlers.at(i).first.second, Q_ARG(QNdefMessage, message), Q_ARG(QNearFieldTarget*, target));
+ }
+}
+
+void QNearFieldManagerPrivateImpl::handlerRequestCompleted(const QNearFieldTarget::RequestId &id)
+{
+ m_idToTarget.remove(id);
+}
+
+void QNearFieldManagerPrivateImpl::handlerError(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id)
+{
+ Q_UNUSED(error);
+ m_idToTarget.remove(id);
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ return AndroidNfc::isAvailable();
+}
+
+bool QNearFieldManagerPrivateImpl::startTargetDetection()
+{
+ if (m_detecting)
+ return false; // Already detecting targets
+
+ m_detecting = true;
+ updateReceiveState();
+ return true;
+}
+
+void QNearFieldManagerPrivateImpl::stopTargetDetection()
+{
+ m_detecting = false;
+ updateReceiveState();
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(QObject *object, const QMetaMethod &method)
+{
+ ndefMessageHandlers.append(QPair<QPair<int, QObject *>, QMetaMethod>(QPair<int, QObject *>(m_handlerID, object), method));
+ updateReceiveState();
+ //Returns the handler ID and increments it afterwards
+ return m_handlerID++;
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const QMetaMethod &method)
+{
+ //If no record is set in the filter, we ignore the filter
+ if (filter.recordCount()==0)
+ return registerNdefMessageHandler(object, method);
+
+ ndefFilterHandlers.append(QPair<QPair<int, QObject*>, QPair<QNdefFilter, QMetaMethod> >
+ (QPair<int, QObject*>(m_handlerID, object), QPair<QNdefFilter, QMetaMethod>(filter, method)));
+
+ updateReceiveState();
+
+ return m_handlerID++;
+}
+
+bool QNearFieldManagerPrivateImpl::unregisterNdefMessageHandler(int handlerId)
+{
+ for (int i=0; i<ndefMessageHandlers.count(); ++i) {
+ if (ndefMessageHandlers.at(i).first.first == handlerId) {
+ ndefMessageHandlers.removeAt(i);
+ updateReceiveState();
+ return true;
+ }
+ }
+ for (int i=0; i<ndefFilterHandlers.count(); ++i) {
+ if (ndefFilterHandlers.at(i).first.first == handlerId) {
+ ndefFilterHandlers.removeAt(i);
+ updateReceiveState();
+ return true;
+ }
+ }
+ return false;
+}
+
+void QNearFieldManagerPrivateImpl::requestAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ Q_UNUSED(accessModes);
+ //Do nothing, because we dont have access modes for the target
+}
+
+void QNearFieldManagerPrivateImpl::releaseAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ Q_UNUSED(accessModes);
+ //Do nothing, because we dont have access modes for the target
+}
+
+void QNearFieldManagerPrivateImpl::newIntent(jobject intent)
+{
+ // This function is called from different thread and is used to move intent to main thread.
+ QMetaObject::invokeMethod(this, "onTargetDiscovered", Qt::QueuedConnection, Q_ARG(jobject, intent));
+}
+
+QByteArray QNearFieldManagerPrivateImpl::getUid(jobject intent)
+{
+ if (intent == 0)
+ return QByteArray();
+
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ jobject tag = AndroidNfc::getTag(env, intent);
+
+ jclass tagClass = env->GetObjectClass(tag);
+ Q_ASSERT_X(tagClass != 0, "getUid", "could not get Tag class");
+
+ jmethodID getIdMID = env->GetMethodID(tagClass, "getId", "()[B");
+ Q_ASSERT_X(getIdMID != 0, "getUid", "could not get method ID for getId()");
+
+ jbyteArray tagId = reinterpret_cast<jbyteArray>(env->CallObjectMethod(tag, getIdMID));
+ Q_ASSERT_X(tagId != 0, "getUid", "getId() returned null object");
+
+ QByteArray uid;
+ jsize len = env->GetArrayLength(tagId);
+ uid.resize(len);
+ env->GetByteArrayRegion(tagId, 0, len, reinterpret_cast<jbyte*>(uid.data()));
+
+ return uid;
+}
+
+void QNearFieldManagerPrivateImpl::onTargetDiscovered(jobject intent)
+{
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ Q_ASSERT_X(env != 0, "onTargetDiscovered", "env pointer is null");
+
+ // Getting tag object and UID
+ jobject tag = AndroidNfc::getTag(env, intent);
+ QByteArray uid = getUid(env, tag);
+
+ // Accepting all targest but only sending signal of requested types.
+ NearFieldTarget *&target = m_detectedTargets[uid];
+ if (target) {
+ target->setIntent(intent); // Updating existing target
+ } else {
+ target = new NearFieldTarget(intent, uid, this);
+ connect(target, SIGNAL(targetDestroyed(QByteArray)), this, SLOT(onTargetDestroyed(QByteArray)));
+ connect(target, SIGNAL(targetLost(QNearFieldTarget*)), this, SIGNAL(targetLost(QNearFieldTarget*)));
+ }
+ emit targetDetected(target);
+}
+
+void QNearFieldManagerPrivateImpl::onTargetDestroyed(const QByteArray &uid)
+{
+ m_detectedTargets.remove(uid);
+}
+
+QByteArray QNearFieldManagerPrivateImpl::getUid(JNIEnv *env, jobject tag)
+{
+ jclass tagClass = env->GetObjectClass(tag);
+ jmethodID getIdMID = env->GetMethodID(tagClass, "getId", "()[B");
+ jbyteArray tagId = reinterpret_cast<jbyteArray>(env->CallObjectMethod(tag, getIdMID));
+ QByteArray uid;
+ jsize len = env->GetArrayLength(tagId);
+ uid.resize(len);
+ env->GetByteArrayRegion(tagId, 0, len, reinterpret_cast<jbyte*>(uid.data()));
+ return uid;
+}
+
+void QNearFieldManagerPrivateImpl::updateReceiveState()
+{
+ if (m_detecting) {
+ AndroidNfc::registerListener(this);
+ AndroidNfc::startDiscovery();
+ } else {
+ if (ndefMessageHandlers.count() || ndefFilterHandlers.count()) {
+ AndroidNfc::registerListener(this);
+ AndroidNfc::startDiscovery();
+ } else {
+ AndroidNfc::stopDiscovery();
+ AndroidNfc::unregisterListener(this);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/nfc/qnearfieldmanager_android_p.h b/src/nfc/qnearfieldmanager_android_p.h
new file mode 100644
index 00000000..1e1e218a
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_android_p.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_ANDROID_P_H
+#define QNEARFIELDMANAGER_ANDROID_P_H
+
+#include "qnearfieldmanager_p.h"
+#include "qnearfieldmanager.h"
+#include "qnearfieldtarget.h"
+#include "android/androidjninfc_p.h"
+
+#include <QHash>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QNdefMessage> QNdefMessageList;
+
+class NearFieldTarget;
+class QByteArray;
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate, public AndroidNfc::AndroidNfcListenerInterface
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+
+ virtual bool isAvailable() const;
+ virtual bool startTargetDetection();
+ virtual void stopTargetDetection();
+ virtual int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ virtual int registerNdefMessageHandler(const QNdefFilter &filter, QObject *object, const QMetaMethod &method);
+ virtual bool unregisterNdefMessageHandler(int handlerId);
+ virtual void requestAccess(QNearFieldManager::TargetAccessModes accessModes);
+ virtual void releaseAccess(QNearFieldManager::TargetAccessModes accessModes);
+ virtual void newIntent(jobject intent);
+ QByteArray getUid(jobject intent);
+
+public slots:
+ void onTargetDiscovered(jobject intent);
+ void onTargetDestroyed(const QByteArray &uid);
+ void handlerTargetDetected(QNearFieldTarget *target);
+ void handlerTargetLost(QNearFieldTarget *target);
+ void handlerNdefMessageRead(const QNdefMessage &message, const QNearFieldTarget::RequestId &id);
+ void handlerRequestCompleted(const QNearFieldTarget::RequestId &id);
+ void handlerError(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id);
+
+protected:
+ static QByteArray getUid(JNIEnv *env, jobject tag);
+ void updateReceiveState();
+
+private:
+ bool m_detecting;
+ QHash<QByteArray, NearFieldTarget*> m_detectedTargets;
+ QMap<QNearFieldTarget::RequestId, QNearFieldTarget*> m_idToTarget;
+
+ int m_handlerID;
+ QList< QPair<QPair<int, QObject *>, QMetaMethod> > ndefMessageHandlers;
+ QList< QPair<QPair<int, QObject *>, QPair<QNdefFilter, QMetaMethod> > > ndefFilterHandlers;
+};
+
+QT_END_NAMESPACE
+
+#endif // QNEARFIELDMANAGER_ANDROID_P_H
diff --git a/src/nfc/qnearfieldtarget_android.cpp b/src/nfc/qnearfieldtarget_android.cpp
new file mode 100644
index 00000000..0fd0e665
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_android.cpp
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtarget_android_p.h"
+#include "android/androidjninfc_p.h"
+#include "qdebug.h"
+
+const QString NearFieldTarget::NdefTechology = QString::fromUtf8("android.nfc.tech.Ndef");
+const QString NearFieldTarget::NdefFormatableTechnology = QString::fromUtf8("android.nfc.tech.NdefFormatable");
+const QString NearFieldTarget::NfcATechnology = QString::fromUtf8("android.nfc.tech.NfcA");
+const QString NearFieldTarget::NfcBTechnology = QString::fromUtf8("android.nfc.tech.NfcB");
+const QString NearFieldTarget::NfcFTechnology = QString::fromUtf8("android.nfc.tech.NfcF");
+const QString NearFieldTarget::NfcVTechnology = QString::fromUtf8("android.nfc.tech.NfcV");
+const QString NearFieldTarget::MifareClassicTechnology = QString::fromUtf8("android.nfc.tech.MifareClassic");
+const QString NearFieldTarget::MifareUltralightTechnology = QString::fromUtf8("android.nfc.tech.MifareUltralight");
+
+
+NearFieldTarget::NearFieldTarget(jobject intent, const QByteArray uid, QObject *parent) :
+ QNearFieldTarget(parent),
+ m_intent(intent),
+ m_uid(uid)
+{
+ updateTechList();
+ updateType();
+ setupTargetCheckTimer();
+}
+
+NearFieldTarget::~NearFieldTarget()
+{
+ releaseIntent();
+ emit targetDestroyed(m_uid);
+}
+
+QByteArray NearFieldTarget::uid() const
+{
+ return m_uid;
+}
+
+QNearFieldTarget::Type NearFieldTarget::type() const
+{
+ return m_type;
+}
+
+QNearFieldTarget::AccessMethods NearFieldTarget::accessMethods() const
+{
+ AccessMethods result = NdefAccess;
+ return result;
+}
+
+bool NearFieldTarget::hasNdefMessage()
+{
+ return m_techList.contains(NdefTechology);
+}
+
+QNearFieldTarget::RequestId NearFieldTarget::readNdefMessages()
+{
+ // Making sure that target has NDEF messages
+ if (!hasNdefMessage())
+ return QNearFieldTarget::RequestId();
+
+ // Making sure that target is still in range
+ QNearFieldTarget::RequestId requestId(new QNearFieldTarget::RequestIdPrivate);
+ if (m_intent == 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::TargetOutOfRangeError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Getting Ndef technology object
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ Q_ASSERT_X(env != 0, "readNdefMessages", "env pointer is null");
+ jobject ndef = getTagTechnology(NdefTechology, env);
+ if (ndef == 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::UnsupportedError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Connect
+ jclass ndefClass = env->GetObjectClass(ndef);
+ jmethodID connectMID = env->GetMethodID(ndefClass, "connect", "()V");
+ env->CallVoidMethod(ndef, connectMID);
+ if (catchJavaExceptions(env)) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::TargetOutOfRangeError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Get NdefMessage object
+ jmethodID getNdefMessageMID = env->GetMethodID(ndefClass, "getNdefMessage", "()Landroid/nfc/NdefMessage;");
+ jobject ndefMessage = env->CallObjectMethod(ndef, getNdefMessageMID);
+ if (catchJavaExceptions(env))
+ ndefMessage = 0;
+ if (ndefMessage == 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::NdefReadError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Convert to byte array
+ jclass ndefMessageClass = env->GetObjectClass(ndefMessage);
+ jmethodID toByteArrayMID = env->GetMethodID(ndefMessageClass, "toByteArray", "()[B");
+ jbyteArray ndefMessageBA = reinterpret_cast<jbyteArray>(env->CallObjectMethod(ndefMessage, toByteArrayMID));
+ QByteArray ndefMessageQBA = jbyteArrayToQByteArray(ndefMessageBA, env);
+
+ // Closing connection
+ jmethodID closeMID = env->GetMethodID(ndefClass, "close", "()V");
+ env->CallVoidMethod(ndef, closeMID);
+ catchJavaExceptions(env); // IOException at this point does not matter anymore.
+
+ // Sending QNdefMessage, requestCompleted and exit.
+ QNdefMessage qNdefMessage = QNdefMessage::fromByteArray(ndefMessageQBA);
+ QMetaObject::invokeMethod(this, "ndefMessageRead", Qt::QueuedConnection,
+ Q_ARG(const QNdefMessage&, qNdefMessage));
+ QMetaObject::invokeMethod(this, "requestCompleted", Qt::QueuedConnection,
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ QMetaObject::invokeMethod(this, "ndefMessageRead", Qt::QueuedConnection,
+ Q_ARG(const QNdefMessage&, qNdefMessage),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+}
+
+
+QNearFieldTarget::RequestId NearFieldTarget::sendCommand(const QByteArray &command)
+{
+ Q_UNUSED(command);
+ Q_EMIT QNearFieldTarget::error(QNearFieldTarget::UnsupportedError, QNearFieldTarget::RequestId());
+ return QNearFieldTarget::RequestId();
+
+ //Not supported for now
+ /*if (command.size() == 0) {
+ Q_EMIT QNearFieldTarget::error(QNearFieldTarget::InvalidParametersError, QNearFieldTarget::RequestId());
+ return QNearFieldTarget::RequestId();
+ }
+
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+
+ jobject tagTech;
+ if (m_techList.contains(NfcATechnology)) {
+ tagTech = getTagTechnology(NfcATechnology);
+ } else if (m_techList.contains(NfcBTechnology)) {
+ tagTech = getTagTechnology(NfcBTechnology);
+ } else if (m_techList.contains(NfcFTechnology)) {
+ tagTech = getTagTechnology(NfcFTechnology);
+ } else if (m_techList.contains(NfcVTechnology)) {
+ tagTech = getTagTechnology(NfcVTechnology);
+ } else {
+ Q_EMIT QNearFieldTarget::error(QNearFieldTarget::UnsupportedError, QNearFieldTarget::RequestId());
+ return QNearFieldTarget::RequestId();
+ }
+
+ QByteArray ba(ba);
+
+ jclass techClass = env->GetObjectClass(tagTech);
+ jmethodID tranceiveMID = env->GetMethodID(techClass, "tranceive", "([B)[B");
+ Q_ASSERT_X(tranceiveMID != 0, "sendCommand", "could not find tranceive method");
+
+ jbyteArray jba = env->NewByteArray(ba.size());
+ env->SetByteArrayRegion(jba, 0, ba.size(), reinterpret_cast<jbyte*>(ba.data()));
+
+ jbyteArray rsp = reinterpret_cast<jbyteArray>(env->CallObjectMethod(tagTech, tranceiveMID, jba));
+
+ jsize len = env->GetArrayLength(rsp);
+ QByteArray rspQBA;
+ rspQBA.resize(len);
+
+ env->GetByteArrayRegion(rsp, 0, len, reinterpret_cast<jbyte*>(rspQBA.data()));
+
+ qDebug() << "Send command returned QBA size: " << rspQBA.size();
+
+
+ env->DeleteLocalRef(jba);
+
+
+ return QNearFieldTarget::RequestId();*/
+}
+
+QNearFieldTarget::RequestId NearFieldTarget::sendCommands(const QList<QByteArray> &commands)
+{
+ QNearFieldTarget::RequestId requestId;
+ for (int i=0; i < commands.size(); i++){
+ requestId = sendCommand(commands.at(i));
+ }
+ return requestId;
+}
+
+QNearFieldTarget::RequestId NearFieldTarget::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ if (messages.size() == 0)
+ return QNearFieldTarget::RequestId();
+
+ if (messages.size() > 1)
+ qWarning("QNearFieldTarget::writeNdefMessages: Android supports writing only one NDEF message per tag.");
+
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ jmethodID writeMethod;
+ jobject tagTechnology;
+ jclass tagClass;
+
+ // Getting write method
+ if (m_techList.contains(NdefFormatableTechnology)) {
+ tagTechnology = getTagTechnology(NdefFormatableTechnology, env);
+ tagClass = env->GetObjectClass(tagTechnology);
+ writeMethod = env->GetMethodID(tagClass, "format", "(Landroid/nfc/NdefMessage;)V");
+ } else if (m_techList.contains(NdefTechology)) {
+ tagTechnology = getTagTechnology(NdefTechology, env);
+ tagClass = env->GetObjectClass(tagTechnology);
+ writeMethod = env->GetMethodID(tagClass, "writeNdefMessage", "(Landroid/nfc/NdefMessage;)V");
+ } else {
+ // An invalid request id will be returned if the target does not support writing NDEF messages.
+ return QNearFieldTarget::RequestId();
+ }
+
+ // Connecting
+ QNearFieldTarget::RequestId requestId = QNearFieldTarget::RequestId(new QNearFieldTarget::RequestIdPrivate());
+ jclass ndefMessageClass = env->FindClass("android/nfc/NdefMessage");
+ jmethodID connectMethodID = env->GetMethodID(tagClass, "connect", "()V");
+ env->CallVoidMethod(tagTechnology, connectMethodID);
+ if (catchJavaExceptions(env)) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::TargetOutOfRangeError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Making NdefMessage object
+ jmethodID ndefMessageInitMID = env->GetMethodID(ndefMessageClass, "<init>", "([B)V");
+ const QNdefMessage &message = messages.first();
+ QByteArray ba = message.toByteArray();
+ jbyteArray jba = env->NewByteArray(ba.size());
+ env->SetByteArrayRegion(jba, 0, ba.size(), reinterpret_cast<jbyte*>(ba.data()));
+ jobject jmessage = env->NewObject(ndefMessageClass, ndefMessageInitMID, jba);
+ if (catchJavaExceptions(env)) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::UnknownError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Writing
+ env->CallVoidMethod(tagTechnology, writeMethod, jmessage);
+ bool gotException = catchJavaExceptions(env);
+ env->DeleteLocalRef(jba);
+ env->DeleteLocalRef(jmessage);
+ if (gotException) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::NdefWriteError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+
+ // Closing connection, sending signal and exit
+ jmethodID closeMID = env->GetMethodID(tagClass, "close", "()V");
+ env->CallVoidMethod(tagTechnology, closeMID);
+ catchJavaExceptions(env); // IOException at this point does not matter anymore.
+ QMetaObject::invokeMethod(this, "ndefMessagesWritten", Qt::QueuedConnection);
+ return requestId;
+}
+
+void NearFieldTarget::setIntent(jobject intent)
+{
+ if (m_intent == intent)
+ return;
+
+ releaseIntent();
+ m_intent = intent;
+ if (m_intent) {
+ // Updating tech list and type in case of there is another tag with same UID as one before.
+ updateTechList();
+ updateType();
+ m_targetCheckTimer->start();
+ }
+}
+
+void NearFieldTarget::checkIsTargetLost()
+{
+ if (m_intent == 0 || m_techList.isEmpty()) {
+ handleTargetLost();
+ return;
+ }
+
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+
+ // Using first available technology to check connection
+ QString techStr = m_techList.first();
+ jobject tagTechObj = getTagTechnology(techStr, env);
+ jclass tagTechClass = env->GetObjectClass(tagTechObj);
+ jmethodID connectMID = env->GetMethodID(tagTechClass, "connect","()V");
+ jmethodID closeMID = env->GetMethodID(tagTechClass, "close","()V");
+
+ env->CallObjectMethod(tagTechObj, connectMID);
+ if (catchJavaExceptions(env)) {
+ handleTargetLost();
+ return;
+ }
+ env->CallObjectMethod(tagTechObj, closeMID);
+ if (catchJavaExceptions(env))
+ handleTargetLost();
+}
+
+void NearFieldTarget::releaseIntent()
+{
+ m_targetCheckTimer->stop();
+
+ if (m_intent == 0)
+ return;
+
+ AndroidNfc::AttachedJNIEnv aenv;
+ Q_ASSERT_X(aenv.jniEnv != 0, "releaseIntent", "aenv.jniEnv pointer is null");
+ aenv.jniEnv->DeleteGlobalRef(m_intent);
+ m_intent = 0;
+}
+
+void NearFieldTarget::updateTechList()
+{
+ if (m_intent == 0)
+ return;
+
+ // Getting tech list
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ jobject tag = AndroidNfc::getTag(env, m_intent);
+ jclass tagClass = env->GetObjectClass(tag);
+ jmethodID techListMID = env->GetMethodID(tagClass, "getTechList", "()[Ljava/lang/String;");
+ jobjectArray techListArray = reinterpret_cast<jobjectArray>(env->CallObjectMethod(tag, techListMID));
+ if (techListArray == 0) {
+ handleTargetLost();
+ return;
+ }
+
+ // Converting tech list array to QStringList.
+ m_techList.clear();
+ jsize techCount = env->GetArrayLength(techListArray);
+ for (jsize i = 0; i < techCount; ++i) {
+ jstring tech = reinterpret_cast<jstring>(env->GetObjectArrayElement(techListArray, i));
+ const char *techStr = env->GetStringUTFChars(tech, JNI_FALSE);
+ m_techList.append(QString::fromUtf8(techStr));
+ env->ReleaseStringUTFChars(tech, techStr);
+ }
+}
+
+void NearFieldTarget::updateType()
+{
+ m_type = getTagType();
+}
+
+QNearFieldTarget::Type NearFieldTarget::getTagType() const
+{
+ AndroidNfc::AttachedJNIEnv aenv;
+ JNIEnv *env = aenv.jniEnv;
+ Q_ASSERT_X(env != 0, "type", "env pointer is null");
+
+ if (m_techList.contains(NdefTechology)) {
+ jobject ndef = getTagTechnology(NdefTechology, env);
+ jclass ndefClass = env->GetObjectClass(ndef);
+
+ jmethodID typeMethodID = env->GetMethodID(ndefClass, "getType", "()Ljava/lang/String;");
+ jstring jtype = reinterpret_cast<jstring>(env->CallObjectMethod(ndef, typeMethodID));
+ const char *type_data = env->GetStringUTFChars(jtype, JNI_FALSE);
+ QString qtype = QString::fromUtf8(type_data);
+ env->ReleaseStringUTFChars(jtype, type_data);
+
+ QHash<QString, Type> types;
+ types.insert(QString::fromUtf8("com.nxp.ndef.mifareclassic"), MifareTag);
+ types.insert(QString::fromUtf8("org.nfcforum.ndef.type1"), NfcTagType1);
+ types.insert(QString::fromUtf8("org.nfcforum.ndef.type2"), NfcTagType2);
+ types.insert(QString::fromUtf8("org.nfcforum.ndef.type3"), NfcTagType3);
+ types.insert(QString::fromUtf8("org.nfcforum.ndef.type4"), NfcTagType4);
+ if (!types.contains(qtype))
+ return ProprietaryTag;
+ return types[qtype];
+ } else if (m_techList.contains(NfcATechnology)) {
+ if (m_techList.contains(MifareClassicTechnology))
+ return MifareTag;
+
+ // Checking ATQA/SENS_RES
+ // xxx0 0000 xxxx xxxx: Identifies tag Type 1 platform
+ jobject nfca = getTagTechnology(NfcATechnology, env);
+ jclass nfcaClass = env->GetObjectClass(nfca);
+ jmethodID atqaMethodID = env->GetMethodID(nfcaClass, "getAtqa", "()[B");
+ jbyteArray atqaBA = reinterpret_cast<jbyteArray>(env->CallObjectMethod(nfca, atqaMethodID));
+ QByteArray atqaQBA = jbyteArrayToQByteArray(atqaBA, env);
+ if (atqaQBA.isEmpty())
+ return ProprietaryTag;
+ if ((atqaQBA[0] & 0x1F) == 0x00)
+ return NfcTagType1;
+
+ // Checking SAK/SEL_RES
+ // xxxx xxxx x00x x0xx: Identifies tag Type 2 platform
+ // xxxx xxxx x01x x0xx: Identifies tag Type 4 platform
+ jmethodID sakMethodID = env->GetMethodID(nfcaClass, "getSak", "()S");
+ jshort sakS = env->CallShortMethod(nfca, sakMethodID);
+ if ((sakS & 0x0064) == 0x0000)
+ return NfcTagType2;
+ else if ((sakS & 0x0064) == 0x0020)
+ return NfcTagType4;
+ return ProprietaryTag;
+ } else if (m_techList.contains(NfcBTechnology)) {
+ return NfcTagType4;
+ } else if (m_techList.contains(NfcFTechnology)) {
+ return NfcTagType3;
+ }
+
+ return ProprietaryTag;
+}
+
+void NearFieldTarget::setupTargetCheckTimer()
+{
+ m_targetCheckTimer = new QTimer(this);
+ m_targetCheckTimer->setInterval(1000);
+ connect(m_targetCheckTimer, SIGNAL(timeout()), this, SLOT(checkIsTargetLost()));
+ m_targetCheckTimer->start();
+}
+
+void NearFieldTarget::handleTargetLost()
+{
+ releaseIntent();
+ emit targetLost(this);
+}
+
+jobject NearFieldTarget::getTagTechnology(const QString &tech, JNIEnv *env) const
+{
+ QString techClass(tech);
+ techClass.replace(QLatin1Char('.'), QLatin1Char('/'));
+
+ // Getting requested technology
+ jobject tag = AndroidNfc::getTag(env, m_intent);
+ jclass tagClass = env->FindClass(techClass.toUtf8().constData());
+ const QString sig = QString::fromUtf8("(Landroid/nfc/Tag;)L%1;");
+ jmethodID getTagMethodID = env->GetStaticMethodID(tagClass, "get", sig.arg(techClass).toUtf8().constData());
+ jobject tagtech = env->CallStaticObjectMethod(tagClass, getTagMethodID, tag);
+ return tagtech;
+}
+
+QByteArray NearFieldTarget::jbyteArrayToQByteArray(const jbyteArray &byteArray, JNIEnv *env) const
+{
+ QByteArray resultArray;
+ jsize len = env->GetArrayLength(byteArray);
+ resultArray.resize(len);
+ env->GetByteArrayRegion(byteArray, 0, len, reinterpret_cast<jbyte*>(resultArray.data()));
+ return resultArray;
+}
+
+bool NearFieldTarget::catchJavaExceptions(JNIEnv *env) const
+{
+ jthrowable exc = env->ExceptionOccurred();
+ if (exc) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ return true;
+ }
+ return false;
+}
diff --git a/src/nfc/qnearfieldtarget_android_p.h b/src/nfc/qnearfieldtarget_android_p.h
new file mode 100644
index 00000000..ab52f58b
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_android_p.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTARGET_ANDROID_P_H
+#define QNEARFIELDTARGET_ANDROID_P_H
+
+#include "android/androidjninfc_p.h"
+#include "qnearfieldtarget.h"
+#include "qnearfieldtarget_p.h"
+#include "qndefmessage.h"
+#include "qlist.h"
+#include "qstringlist.h"
+#include <QTimer>
+
+
+QT_BEGIN_NAMESPACE
+
+class NearFieldTarget : public QNearFieldTarget
+{
+ Q_OBJECT
+public:
+ NearFieldTarget(jobject intent,
+ const QByteArray uid,
+ QObject *parent = 0);
+ virtual ~NearFieldTarget();
+ virtual QByteArray uid() const;
+ virtual Type type() const;
+ virtual AccessMethods accessMethods() const;
+ virtual bool hasNdefMessage();
+ virtual RequestId readNdefMessages();
+ virtual RequestId sendCommand(const QByteArray &command);
+ virtual RequestId sendCommands(const QList<QByteArray> &commands);
+ virtual RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+ void setIntent(jobject intent);
+
+signals:
+ void targetDestroyed(const QByteArray &tagId);
+ void targetLost(QNearFieldTarget *target);
+ void ndefMessageRead(const QNdefMessage &message, const QNearFieldTarget::RequestId &id);
+
+protected slots:
+ void checkIsTargetLost();
+
+protected:
+ void releaseIntent();
+ void updateTechList();
+ void updateType();
+ Type getTagType() const;
+ void setupTargetCheckTimer();
+ void handleTargetLost();
+ jobject getTagTechnology(const QString &tech, JNIEnv *env) const;
+ QByteArray jbyteArrayToQByteArray(const jbyteArray &byteArray, JNIEnv *env) const;
+ bool catchJavaExceptions(JNIEnv *env) const;
+
+protected:
+ jobject m_intent;
+ QByteArray m_uid;
+ QStringList m_techList;
+ Type m_type;
+ static const QString NdefTechology;
+ static const QString NdefFormatableTechnology;
+ static const QString NfcATechnology;
+ static const QString NfcBTechnology;
+ static const QString NfcFTechnology;
+ static const QString NfcVTechnology;
+ static const QString MifareClassicTechnology;
+ static const QString MifareUltralightTechnology;
+ QTimer *m_targetCheckTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QNEARFIELDTARGET_ANDROID_P_H