summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@digia.com>2014-08-08 18:31:20 +0200
committerPaul Olav Tvete <paul.tvete@digia.com>2014-08-12 09:24:51 +0200
commitea7af7f00886f77941b81262e597c3b7f3477f48 (patch)
tree535e61590542e9f6e464b93de16202ce239b7e3b
parent825ae95d8984a3daa49ad81a91e85483918799af (diff)
downloadqtsensors-ea7af7f00886f77941b81262e597c3b7f3477f48.tar.gz
qtsensors-ea7af7f00886f77941b81262e597c3b7f3477f48.tar.bz2
qtsensors-ea7af7f00886f77941b81262e597c3b7f3477f48.zip
Compass sensor implementation for Android
Change-Id: Ic13d2d1e400a92b2f0c3c83e279c58b799f9d06b Reviewed-by: Lorn Potter <lorn.potter@jollamobile.com>
-rw-r--r--src/plugins/sensors/android/jar/src/org/qtproject/qt5/android/sensors/QtSensors.java19
-rw-r--r--src/plugins/sensors/android/src/androidcompass.cpp173
-rw-r--r--src/plugins/sensors/android/src/androidcompass.h76
-rw-r--r--src/plugins/sensors/android/src/androidjnisensors.cpp16
-rw-r--r--src/plugins/sensors/android/src/androidjnisensors.h1
-rw-r--r--src/plugins/sensors/android/src/main.cpp11
-rw-r--r--src/plugins/sensors/android/src/src.pro2
7 files changed, 298 insertions, 0 deletions
diff --git a/src/plugins/sensors/android/jar/src/org/qtproject/qt5/android/sensors/QtSensors.java b/src/plugins/sensors/android/jar/src/org/qtproject/qt5/android/sensors/QtSensors.java
index efd1ff6..e7e309e 100644
--- a/src/plugins/sensors/android/jar/src/org/qtproject/qt5/android/sensors/QtSensors.java
+++ b/src/plugins/sensors/android/jar/src/org/qtproject/qt5/android/sensors/QtSensors.java
@@ -153,6 +153,25 @@ public class QtSensors implements SensorEventListener
return angles;
}
+ private static float[] mRotation = new float[9];
+ private static float[] mOrientation = new float[3];
+ private static float[] mAcc = new float[3];
+ private static float[] mMag = new float[3];
+
+ private static float getCompassAzimuth(float a0, float a1, float a2, float m0, float m1, float m2)
+ {
+ mAcc[0] = a0;
+ mAcc[1] = a1;
+ mAcc[2] = a2;
+ mMag[0] = m0;
+ mMag[1] = m1;
+ mMag[2] = m2;
+
+ SensorManager.getRotationMatrix(mRotation, null, mAcc, mMag);
+ SensorManager.getOrientation(mRotation, mOrientation);
+ return mOrientation[0];
+ }
+
public static native void accuracyChanged(int sensorType, int accuracy);
public static native void sensorChanged(int sensorType, long timestamp, float[] values);
diff --git a/src/plugins/sensors/android/src/androidcompass.cpp b/src/plugins/sensors/android/src/androidcompass.cpp
new file mode 100644
index 0000000..f2b4bd2
--- /dev/null
+++ b/src/plugins/sensors/android/src/androidcompass.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSensors 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 "androidcompass.h"
+
+#include <QDebug>
+#include <qmath.h>
+#include "androidjnisensors.h"
+
+
+class AndroidAccelerometerListener : public AndroidSensors::AndroidSensorsListenerInterface
+{
+public:
+
+ AndroidAccelerometerListener(AndroidCompass *parent)
+ : m_compass(parent)
+ {
+ }
+
+ void start(int dataRate)
+ {
+ AndroidSensors::registerListener(AndroidSensors::TYPE_ACCELEROMETER, this, dataRate);
+ }
+
+ void stop()
+ {
+ AndroidSensors::unregisterListener(AndroidSensors::TYPE_ACCELEROMETER, this);
+ }
+
+ void onAccuracyChanged(jint accuracy) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(accuracy);
+ }
+
+ void onSensorChanged(jlong /*timestamp*/, const jfloat *values, uint size) Q_DECL_OVERRIDE
+ {
+ if (size < 3)
+ return;
+ reading[0] = values[0];
+ reading[1] = values[1];
+ reading[2] = values[2];
+ m_compass->testStuff();
+ }
+
+ jfloat reading[3];
+
+private:
+ AndroidCompass *m_compass;
+};
+
+class AndroidMagnetometerListener : public AndroidSensors::AndroidSensorsListenerInterface
+{
+public:
+ AndroidMagnetometerListener(AndroidCompass *parent)
+ :m_compass(parent)
+ {
+
+ }
+
+ void start(int dataRate)
+ {
+ AndroidSensors::registerListener(AndroidSensors::TYPE_MAGNETIC_FIELD, this, dataRate);
+ }
+
+ void stop()
+ {
+ AndroidSensors::unregisterListener(AndroidSensors::TYPE_MAGNETIC_FIELD, this);
+ }
+
+ void onAccuracyChanged(jint accuracy) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(accuracy);
+ }
+
+ void onSensorChanged(jlong /*timestamp*/, const jfloat *values, uint size) Q_DECL_OVERRIDE
+ {
+ if (size < 3)
+ return;
+ reading[0] = values[0];
+ reading[1] = values[1];
+ reading[2] = values[2];
+ m_compass->testStuff();
+ }
+
+ jfloat reading[3];
+private:
+ AndroidCompass *m_compass;
+};
+
+char const * const AndroidCompass::id("android.synthetic.compass");
+
+AndroidCompass::AndroidCompass(QSensor *sensor)
+ : QSensorBackend(sensor), m_accelerometerListener(0), m_magnetometerListener(0), m_isStarted(false)
+{
+ setReading<QCompassReading>(&m_reading);
+ m_isStarted = false;
+}
+
+AndroidCompass::~AndroidCompass()
+{
+ if (m_isStarted)
+ stop();
+ delete m_accelerometerListener;
+ delete m_magnetometerListener;
+}
+
+void AndroidCompass::start()
+{
+ if (!m_accelerometerListener)
+ m_accelerometerListener = new AndroidAccelerometerListener(this);
+ m_accelerometerListener->start(sensor()->dataRate());
+ if (!m_magnetometerListener)
+ m_magnetometerListener = new AndroidMagnetometerListener(this);
+ m_magnetometerListener->start(sensor()->dataRate());
+
+ m_isStarted = true;
+}
+
+void AndroidCompass::stop()
+{
+ if (m_isStarted) {
+ m_isStarted = false;
+ m_accelerometerListener->stop();
+ m_magnetometerListener->stop();
+ }
+}
+
+void AndroidCompass::testStuff()
+{
+ qreal azimuth = AndroidSensors::getCompassAzimuth(m_accelerometerListener->reading, m_magnetometerListener->reading);
+
+ azimuth = azimuth * 180.0 / M_PI;
+ m_reading.setAzimuth(azimuth);
+ newReadingAvailable();
+}
diff --git a/src/plugins/sensors/android/src/androidcompass.h b/src/plugins/sensors/android/src/androidcompass.h
new file mode 100644
index 0000000..897dd46
--- /dev/null
+++ b/src/plugins/sensors/android/src/androidcompass.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtSensors 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 ANDROIDCOMPASS_H
+#define ANDROIDCOMPASS_H
+#include <qcompass.h>
+
+#include "androidcommonsensor.h"
+
+class AndroidAccelerometerListener;
+class AndroidMagnetometerListener;
+
+class AndroidCompass : public QSensorBackend
+{
+ Q_OBJECT
+
+public:
+ static char const * const id;
+
+ AndroidCompass(QSensor *sensor);
+ ~AndroidCompass();
+
+ void start() Q_DECL_OVERRIDE;
+ void stop() Q_DECL_OVERRIDE;
+
+private:
+ AndroidAccelerometerListener *m_accelerometerListener;
+ AndroidMagnetometerListener *m_magnetometerListener;
+
+ QCompassReading m_reading;
+ bool m_isStarted;
+
+public Q_SLOTS:
+ void testStuff();
+
+};
+
+#endif // ANDROIDCOMPASS_H
diff --git a/src/plugins/sensors/android/src/androidjnisensors.cpp b/src/plugins/sensors/android/src/androidjnisensors.cpp
index 87889a8..9a7b671 100644
--- a/src/plugins/sensors/android/src/androidjnisensors.cpp
+++ b/src/plugins/sensors/android/src/androidjnisensors.cpp
@@ -54,6 +54,7 @@ static jmethodID registerSensorMethodId;
static jmethodID unregisterSensorMethodId;
static jmethodID getSensorDescriptionMethodId;
static jmethodID getSensorMaximumRangeMethodId;
+static jmethodID getCompassAzimuthId;
static QHash<int, QList<AndroidSensors::AndroidSensorsListenerInterface *> > listenersHash;
QReadWriteLock listenersLocker;
@@ -166,6 +167,20 @@ namespace AndroidSensors
}
return true;
}
+
+ qreal getCompassAzimuth(jfloat *accelerometerReading, jfloat *magnetometerReading)
+ {
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return 0.0;
+ return aenv.jniEnv->CallStaticFloatMethod(sensorsClass, getCompassAzimuthId,
+ accelerometerReading[0],
+ accelerometerReading[1],
+ accelerometerReading[2],
+ magnetometerReading[0],
+ magnetometerReading[1],
+ magnetometerReading[2]);
+ }
}
static const char logTag[] = "Qt";
@@ -227,6 +242,7 @@ static bool registerNatives(JNIEnv *env)
GET_AND_CHECK_STATIC_METHOD(unregisterSensorMethodId, sensorsClass, "unregisterSensor", "(I)Z");
GET_AND_CHECK_STATIC_METHOD(getSensorDescriptionMethodId, sensorsClass, "getSensorDescription", "(I)Ljava/lang/String;");
GET_AND_CHECK_STATIC_METHOD(getSensorMaximumRangeMethodId, sensorsClass, "getSensorMaximumRange", "(I)F");
+ GET_AND_CHECK_STATIC_METHOD(getCompassAzimuthId, sensorsClass, "getCompassAzimuth", "(FFFFFF)F");
return true;
}
diff --git a/src/plugins/sensors/android/src/androidjnisensors.h b/src/plugins/sensors/android/src/androidjnisensors.h
index 30aab6c..9d2ccf5 100644
--- a/src/plugins/sensors/android/src/androidjnisensors.h
+++ b/src/plugins/sensors/android/src/androidjnisensors.h
@@ -83,6 +83,7 @@ namespace AndroidSensors
qreal sensorMaximumRange(AndroidSensorType sensor);
bool registerListener(AndroidSensorType sensor, AndroidSensorsListenerInterface *listener, int dataRate = 0);
bool unregisterListener(AndroidSensorType sensor, AndroidSensorsListenerInterface *listener);
+ qreal getCompassAzimuth(jfloat *accelerometerReading, jfloat *magnetometerReading);
}
#endif // ANDROIDJNISENSORS_H
diff --git a/src/plugins/sensors/android/src/main.cpp b/src/plugins/sensors/android/src/main.cpp
index 3d8604f..b8d1496 100644
--- a/src/plugins/sensors/android/src/main.cpp
+++ b/src/plugins/sensors/android/src/main.cpp
@@ -44,7 +44,9 @@
#include <qsensorbackend.h>
#include <qsensormanager.h>
#include <qaccelerometer.h>
+#include <qcompass.h>
#include "androidaccelerometer.h"
+#include "androidcompass.h"
#include "androidgyroscope.h"
#include "androidlight.h"
#include "androidmagnetometer.h"
@@ -63,10 +65,13 @@ class AndroidSensorPlugin : public QObject, public QSensorPluginInterface, publi
public:
void registerSensors()
{
+ bool accelerometer = false;
+ bool magnetometer = false;
foreach (AndroidSensorType sensor, availableSensors()) {
switch (sensor) {
case TYPE_ACCELEROMETER:
QSensorManager::registerBackend(QAccelerometer::type, QByteArray::number(sensor), this);
+ accelerometer = true;
break;
case TYPE_AMBIENT_TEMPERATURE:
case TYPE_TEMPERATURE:
@@ -84,6 +89,7 @@ public:
break; // add the linear acceleration sensor backend
case TYPE_MAGNETIC_FIELD:
QSensorManager::registerBackend(QMagnetometer::type, QByteArray::number(sensor), this);
+ magnetometer = true;
break;
case TYPE_ORIENTATION:
break; // add the orientation sensor backend
@@ -106,10 +112,15 @@ public:
break; // add backends for API level 18 sensors
}
}
+ if (accelerometer && magnetometer)
+ QSensorManager::registerBackend(QCompass::type, AndroidCompass::id, this);
}
QSensorBackend *createBackend(QSensor *sensor)
{
+ if (sensor->identifier() == AndroidCompass::id)
+ return new AndroidCompass(sensor);
+
AndroidSensorType type = static_cast<AndroidSensorType>(sensor->identifier().toInt());
switch (type) {
case TYPE_ACCELEROMETER: {
diff --git a/src/plugins/sensors/android/src/src.pro b/src/plugins/sensors/android/src/src.pro
index 21423ef..23a6bea 100644
--- a/src/plugins/sensors/android/src/src.pro
+++ b/src/plugins/sensors/android/src/src.pro
@@ -12,6 +12,7 @@ DEFINES += QT_STATICPLUGIN
HEADERS = \
androidjnisensors.h \
androidaccelerometer.h \
+ androidcompass.h \
androidcommonsensor.h \
androidgyroscope.h \
androidmagnetometer.h \
@@ -25,6 +26,7 @@ SOURCES = \
main.cpp \
androidjnisensors.cpp \
androidaccelerometer.cpp \
+ androidcompass.cpp \
androidgyroscope.cpp \
androidmagnetometer.cpp \
androidpressure.cpp \