diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-10-29 13:04:49 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@digia.com> | 2014-11-04 09:47:24 +0100 |
commit | 7c12e73031c7dde3d422f9a2d0baeaa25b75fabb (patch) | |
tree | fcc6a333174cb741bc459855778ae0917e8f2cdc /src/bluetooth/android | |
parent | cb3054e2373dec8e800c1b5208555936ef3ae63b (diff) |
Android: Add ability to (dis)connect to BTLE devices on Android
and keep tracking the connection state
Change-Id: If4d05fa18c78802ae06096884fba78eed123e77f
Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com>
Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/bluetooth/android')
-rw-r--r-- | src/bluetooth/android/android.pri | 6 | ||||
-rw-r--r-- | src/bluetooth/android/jni_android.cpp | 3 | ||||
-rw-r--r-- | src/bluetooth/android/lowenergynotificationhub.cpp | 110 | ||||
-rw-r--r-- | src/bluetooth/android/lowenergynotificationhub_p.h | 80 |
4 files changed, 197 insertions, 2 deletions
diff --git a/src/bluetooth/android/android.pri b/src/bluetooth/android/android.pri index 0507894f..c50a919a 100644 --- a/src/bluetooth/android/android.pri +++ b/src/bluetooth/android/android.pri @@ -5,7 +5,8 @@ PRIVATE_HEADERS += \ android/androidbroadcastreceiver_p.h \ android/localdevicebroadcastreceiver_p.h \ android/serveracceptancethread_p.h \ - android/jni_android_p.h + android/jni_android_p.h \ + android/lowenergynotificationhub_p.h SOURCES += \ @@ -15,4 +16,5 @@ SOURCES += \ android/jni_android.cpp \ android/androidbroadcastreceiver.cpp \ android/localdevicebroadcastreceiver.cpp \ - android/serveracceptancethread.cpp + android/serveracceptancethread.cpp \ + android/lowenergynotificationhub.cpp diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index 061d6ce2..6fffc018 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -40,6 +40,7 @@ #include "android/androidbroadcastreceiver_p.h" #include "android/serveracceptancethread_p.h" #include "android/inputstreamthread_p.h" +#include "android/lowenergynotificationhub_p.h" Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) @@ -198,6 +199,8 @@ static JNINativeMethod methods[] = { static JNINativeMethod methods_le[] = { {"leScanResult", "(JLandroid/bluetooth/BluetoothDevice;I)V", (void *) QtBluetoothLE_leScanResult}, + {"leConnectionStateChange", "(JII)V", + (void *) LowEnergyNotificationHub::lowEnergy_connectionChange}, }; static JNINativeMethod methods_server[] = { diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp new file mode 100644 index 00000000..d662cd5b --- /dev/null +++ b/src/bluetooth/android/lowenergynotificationhub.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "lowenergynotificationhub_p.h" + +#include <QtCore/QHash> +#include <QtCore/QLoggingCategory> +#include <QtCore/QTime> +#include <QtAndroidExtras/QAndroidJniEnvironment> + +QT_BEGIN_NAMESPACE + +typedef QHash<long, LowEnergyNotificationHub*> HubMapType; +Q_GLOBAL_STATIC(HubMapType, hubMap) + +QReadWriteLock LowEnergyNotificationHub::lock; + +Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) + +LowEnergyNotificationHub::LowEnergyNotificationHub( + const QBluetoothAddress &remote, QObject *parent) + : QObject(parent), javaToCtoken(0) +{ + QAndroidJniEnvironment env; + const QAndroidJniObject address = + QAndroidJniObject::fromString(remote.toString()); + jBluetoothLe = QAndroidJniObject("org/qtproject/qt5/android/bluetooth/QtBluetoothLE", + "(Ljava/lang/String;Landroid/app/Activity;)V", + address.object<jstring>(), + QtAndroidPrivate::activity()); + + + if (env->ExceptionCheck() || !jBluetoothLe.isValid()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + jBluetoothLe = QAndroidJniObject(); + return; + } + + // register C++ class pointer in Java + qsrand(QTime::currentTime().msec()); + lock.lockForWrite(); + + while (true) { + javaToCtoken = qrand(); + if (!hubMap()->contains(javaToCtoken)) + break; + } + + hubMap()->insert(javaToCtoken, this); + lock.unlock(); + + jBluetoothLe.setField<jlong>("qtObject", javaToCtoken); +} + +LowEnergyNotificationHub::~LowEnergyNotificationHub() +{ + lock.lockForWrite(); + hubMap()->remove(javaToCtoken); + lock.unlock(); +} + +// runs in Java thread +void LowEnergyNotificationHub::lowEnergy_connectionChange( + JNIEnv *, jobject, jlong qtObject, jint errorCode, jint newState) +{ + lock.lockForRead(); + LowEnergyNotificationHub *hub = hubMap()->value(qtObject); + lock.unlock(); + if (!hub) + return; + + QMetaObject::invokeMethod(hub, "connectionUpdated", Qt::QueuedConnection, + Q_ARG(QLowEnergyController::ControllerState, + (QLowEnergyController::ControllerState)newState), + Q_ARG(QLowEnergyController::Error, + (QLowEnergyController::Error)errorCode)); +} + +QT_END_NAMESPACE diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h new file mode 100644 index 00000000..68999a3e --- /dev/null +++ b/src/bluetooth/android/lowenergynotificationhub_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LOWENERGYNOTIFICATIONHUB_H +#define LOWENERGYNOTIFICATIONHUB_H + +#include <QtCore/QObject> +#include <QtCore/QReadWriteLock> +#include <QtCore/private/qjnihelpers_p.h> +#include <QtAndroidExtras/QAndroidJniObject> +#include <QtBluetooth/QBluetoothAddress> +#include <jni.h> + +#include "qlowenergycontroller_p.h" + +QT_BEGIN_NAMESPACE + +class LowEnergyNotificationHub : public QObject +{ + Q_OBJECT +public: + explicit LowEnergyNotificationHub(const QBluetoothAddress &remote, + QObject *parent = 0); + ~LowEnergyNotificationHub(); + + static void lowEnergy_connectionChange(JNIEnv*, jobject, jlong qtObject, + jint errorCode, jint newState); + + QAndroidJniObject javaObject() + { + return jBluetoothLe; + } + +signals: + void connectionUpdated(QLowEnergyController::ControllerState newState, + QLowEnergyController::Error errorCode); + +public slots: +private: + static QReadWriteLock lock; + + QAndroidJniObject jBluetoothLe; + long javaToCtoken; + +}; + +QT_END_NAMESPACE + +#endif // LOWENERGYNOTIFICATIONHUB_H + |