Commit a0fcccc4 authored by Vyacheslav Koscheev's avatar Vyacheslav Koscheev

GLPv3+cell support

parent ba663d28
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
Offscreen Android Views library for Qt Offscreen Android Views library for Qt
Authors: Authors:
Vyacheslav O. Koscheev <vok1980@gmail.com> Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License Distrbuted under The BSD License
...@@ -41,53 +41,30 @@ ...@@ -41,53 +41,30 @@
namespace Mobility { namespace Mobility {
CellData::CellData()
{
clear();
}
bool CellData::compare( const CellData& other, bool compareSignalStrength ) const
{
if( cellId != other.cellId ||
locationAreaCode != other.locationAreaCode ||
mobileCountryCode != other.mobileCountryCode ||
mobileNetworkCode != other.mobileNetworkCode ||
timingAdvance != other.timingAdvance )
{
return false;
}
if( compareSignalStrength &&
signalStrength != other.signalStrength )
{
return false;
}
return true;
}
bool CellData::operator==(const CellData &other) const const int32_t CellData::java_integer_max_value = std::numeric_limits<int32_t>::max();
{
return compare(other, true);
}
bool CellData::operator!=(const CellData &other) const CellData::Data::Data(int32_t cell_id)
: cell_id_(cell_id)
, location_area_code_(java_integer_max_value)
, mobile_country_code_(java_integer_max_value)
, mobile_network_code_(java_integer_max_value)
, signal_strength_(java_integer_max_value)
, timing_advance_(java_integer_max_value)
{ {
return !compare(other, true);
} }
// used as sign of validity void CellData::Data::accept(DataOperation & operation) const
bool CellData::isEmpty() const
{ {
return !(cellId && locationAreaCode && mobileCountryCode && mobileNetworkCode); operation.execute(QStringLiteral("cell_id"), cell_id_);
operation.execute(QStringLiteral("location_area_code"), location_area_code_);
operation.execute(QStringLiteral("mobile_country_code"), mobile_country_code_);
operation.execute(QStringLiteral("mobile_network_code"), mobile_network_code_);
operation.execute(QStringLiteral("signal_strength"), signal_strength_);
operation.execute(QStringLiteral("timing_advance"), timing_advance_);
operation.execute(QStringLiteral("radio_type"), radio_type_);
} }
} // namespace Mobility
void CellData::clear()
{
memset(this, 0, sizeof(*this));
}
}
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
Offscreen Android Views library for Qt Offscreen Android Views library for Qt
Authors: Authors:
Vyacheslav O. Koscheev <vok1980@gmail.com> Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License Distrbuted under The BSD License
...@@ -45,39 +45,47 @@ namespace Mobility { ...@@ -45,39 +45,47 @@ namespace Mobility {
struct CellData struct CellData
{ {
CellData(); struct DataOperation
bool compare( const CellData& other, bool compareSignalStrength ) const; {
bool operator==(const CellData& other) const; virtual void execute(const QString & key, int32_t value) = 0;
bool operator!=(const CellData& other) const; virtual void execute(const QString & key, const QString & value) = 0;
bool isEmpty() const; // used as sign of validity };
void clear();
struct Data
// fields are described in http://code.google.com/intl/ru/apis/gears/geolocation_network_protocol.html {
// Unique identifier of the cell. (CID for GSM, BID for CDMA) Data(int32_t cell_id);
int cellId; void accept(DataOperation & operation) const;
// Location Area Code (LAC for GSM, NID for CDMA) // required, int.
int locationAreaCode; // Cell ID (CID) for GSM
// Base Station ID (BID) for CDMA
// Mobile Country Code (MCC for GSM and CDMA) // UTRAN/GERAN Cell Identity (UC-Id) for WCDMA.
int mobileCountryCode; int32_t cell_id_;
// Mobile Network Code (MNC for GSM, SID for CDMA) // optional, int.
int mobileNetworkCode; // Location Area Code (LAC) for GSM and WCDMA.
// Network ID (NID) for CDMA сетей. 0 <= LAC <= 65535.
// Radio signal strength measured in dBm. int32_t location_area_code_;
/* convert GSM asu (TS 27.007 8.5) to these as follows:
<rssi>: // optional, int. 0 <= MCC < 1000
0 -113 dBm or less int32_t mobile_country_code_;
1 -111 dBm
2...30 -109... -53 dBm // optional, int. 0 <= MNC < 1000
31 -51 dBm or greater int32_t mobile_network_code_;
99 not known or not detectable
*/ // optional, int. RSSI в dBm.
int signalStrength; int32_t signal_strength_;
// Represents the distance from the cell tower. Each unit is roughly 550 meters. // optional, int
int timingAdvance; int32_t timing_advance_;
// gsm, wcdma, lte, cdma
QString radio_type_;
};
typedef QList<Data> DataColl;
DataColl data_;
static const int32_t java_integer_max_value;
}; };
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
Offscreen Android Views library for Qt Offscreen Android Views library for Qt
Authors: Authors:
Vyacheslav O. Koscheev <vok1980@gmail.com> Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License Distrbuted under The BSD License
...@@ -37,23 +37,33 @@ ...@@ -37,23 +37,33 @@
*/ */
#include "QAndroidCellDataProvider.h" #include "QAndroidCellDataProvider.h"
#include <QtCore/QtDebug>
#include <QAndroidQPAPluginGap.h> #include <QAndroidQPAPluginGap.h>
#include "TJniObjectLinker.h" #include "TJniObjectLinker.h"
namespace Mobility { namespace Mobility {
Q_DECL_EXPORT void JNICALL Java_CellListener_cellUpdate(JNIEnv *, jobject, jlong native_ptr, jint cid, jint lac, jint mcc, jint mnc, jint rssi)
Q_DECL_EXPORT void JNICALL Java_CellListener_cellUpdate(JNIEnv *, jobject, jlong native_ptr, jstring type, jint cid, jint lac, jint mcc, jint mnc, jint rssi, jint ta)
{ {
JNI_LINKER_OBJECT(Mobility::QAndroidCellDataProvider, native_ptr, proxy) JNI_LINKER_OBJECT(Mobility::QAndroidCellDataProvider, native_ptr, proxy)
proxy->cellUpdate(cid, lac, mcc, mnc, rssi); proxy->cellUpdate(type, cid, lac, mcc, mnc, rssi, ta);
}
Q_DECL_EXPORT void JNICALL Java_CellListener_onSignalChanged(JNIEnv *, jobject, jlong native_ptr)
{
JNI_LINKER_OBJECT(Mobility::QAndroidCellDataProvider, native_ptr, proxy)
proxy->onSignalChanged();
} }
static const JNINativeMethod methods[] = { static const JNINativeMethod methods[] = {
{"getContext", "()Landroid/content/Context;", reinterpret_cast<void*>(QAndroidQPAPluginGap::getCurrentContextNoThrow)}, {"getContext", "()Landroid/content/Context;", reinterpret_cast<void*>(QAndroidQPAPluginGap::getCurrentContextNoThrow)},
// private native void cellUpdate(long native_ptr, int cid, int lac, int mcc, int mnc, int rssi); {"onSignalChanged", "(J)V", reinterpret_cast<void*>(Java_CellListener_onSignalChanged)},
{"cellUpdate", "(JIIIII)V", reinterpret_cast<void*>(Java_CellListener_cellUpdate)}, {"cellUpdate", "(JLjava/lang/String;IIIIII)V", reinterpret_cast<void*>(Java_CellListener_cellUpdate)},
}; };
...@@ -74,48 +84,92 @@ QAndroidCellDataProvider::~QAndroidCellDataProvider() ...@@ -74,48 +84,92 @@ QAndroidCellDataProvider::~QAndroidCellDataProvider()
void QAndroidCellDataProvider::start() void QAndroidCellDataProvider::start()
{ {
if (isJniReady()) try
{
if (isJniReady())
{
jni()->callBool("start");
}
}
catch (const std::exception & ex)
{ {
jni()->callBool("start"); qCritical() << "JNI exception in QAndroidCellDataProvider:" << ex.what();
} }
} }
void QAndroidCellDataProvider::stop() void QAndroidCellDataProvider::stop()
{ {
if (isJniReady()) try
{
if (isJniReady())
{
jni()->callVoid("stop");
}
}
catch (const std::exception & ex)
{
qCritical() << "JNI exception in QAndroidCellDataProvider:" << ex.what();
}
}
void QAndroidCellDataProvider::onSignalChanged()
{
emit updated();
}
void QAndroidCellDataProvider::requestData()
{
current_data_ = CellDataPtr::create();
try
{ {
jni()->callVoid("stop"); if (isJniReady())
{
jni()->callVoid("requestData");
{
QWriteLocker locker(&lock_data_);
last_data_ = current_data_;
}
emit dataReady();
}
}
catch (const std::exception & ex)
{
qCritical() << "JNI exception in QAndroidCellDataProvider:" << ex.what();
} }
} }
void QAndroidCellDataProvider::cellUpdate(int cid, int lac, int mcc, int mnc, int rssi) void QAndroidCellDataProvider::cellUpdate(jstring type, jint cid, jint lac, jint mcc, jint mnc, jint rssi, jint ta)
{ {
CellDataPtr new_data(new CellData); if (current_data_ && cid > 0 && cid != CellData::java_integer_max_value)
new_data->cellId = cid;
new_data->locationAreaCode = lac;
new_data->mobileCountryCode = mcc;
new_data->mobileNetworkCode = mnc;
new_data->signalStrength = rssi;
new_data->timingAdvance = 0;
if (last_data_)
{ {
if (*new_data==*last_data_) current_data_->data_.push_back(CellData::Data(cid));
if (isJniReady())
{ {
return; QJniEnvPtr jep;
current_data_->data_.back().radio_type_ = jep.JStringToQString(type);
} }
current_data_->data_.back().location_area_code_ = lac;
current_data_->data_.back().mobile_country_code_ = mcc;
current_data_->data_.back().mobile_network_code_ = mnc;
current_data_->data_.back().signal_strength_ = rssi;
current_data_->data_.back().timing_advance_ = ta;
} }
last_data_ = new_data;
emit update();
} }
CellDataPtr QAndroidCellDataProvider::getLastData() CellDataPtr QAndroidCellDataProvider::getLastData()
{ {
QReadLocker locker(&lock_data_);
return last_data_; return last_data_;
} }
} } // namespace Mobility
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
Offscreen Android Views library for Qt Offscreen Android Views library for Qt
Authors: Authors:
Vyacheslav O. Koscheev <vok1980@gmail.com> Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License Distrbuted under The BSD License
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#pragma once #pragma once
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QReadWriteLock>
#include <QJniHelpers.h> #include <QJniHelpers.h>
#include "IJniObjectLinker.h" #include "IJniObjectLinker.h"
#include "CellData.h" #include "CellData.h"
...@@ -59,18 +60,24 @@ public: ...@@ -59,18 +60,24 @@ public:
CellDataPtr getLastData(); CellDataPtr getLastData();
private: private:
friend void JNICALL Java_CellListener_cellUpdate(JNIEnv *, jobject, jlong native_ptr, jint cid, jint lac, jint mcc, jint mnc, jint rssi); friend void JNICALL Java_CellListener_cellUpdate(JNIEnv *, jobject, jlong native_ptr, jstring type, jint cid, jint lac, jint mcc, jint mnc, jint rssi, jint ta);
void cellUpdate(int cid, int lac, int mcc, int mnc, int rssi); friend void JNICALL JNICALL Java_CellListener_onSignalChanged(JNIEnv *, jobject, jlong native_ptr);
void cellUpdate(jstring type, jint cid, jint lac, jint mcc, jint mnc, jint rssi, jint ta);
void onSignalChanged();
public slots: public slots:
void start(); void start();
void stop(); void stop();
void requestData();
signals: signals:
void update(); void updated();
void dataReady();
private: private:
CellDataPtr last_data_; CellDataPtr last_data_;
CellDataPtr current_data_;
QReadWriteLock lock_data_;
}; };
} }
...@@ -53,7 +53,6 @@ Q_DECL_EXPORT void JNICALL Java_WifiListener_scanUpdate(JNIEnv *, jobject, jlong ...@@ -53,7 +53,6 @@ Q_DECL_EXPORT void JNICALL Java_WifiListener_scanUpdate(JNIEnv *, jobject, jlong
static const JNINativeMethod methods[] = { static const JNINativeMethod methods[] = {
{"getContext", "()Landroid/content/Context;", reinterpret_cast<void*>(QAndroidQPAPluginGap::getCurrentContextNoThrow)}, {"getContext", "()Landroid/content/Context;", reinterpret_cast<void*>(QAndroidQPAPluginGap::getCurrentContextNoThrow)},
// private native void scanUpdate(long native_ptr);
{"scanUpdate", "(J)V", reinterpret_cast<void*>(Java_WifiListener_scanUpdate)}, {"scanUpdate", "(J)V", reinterpret_cast<void*>(Java_WifiListener_scanUpdate)},
}; };
......
/*
Offscreen Android Views library for Qt
Authors:
Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License
Copyright (c) 2015, DoubleGIS, LLC.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the DoubleGIS, LLC nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
package ru.dublgis.androidhelpers.mobility;
public class CellData
{
public int cellId_;
public int locationAreaCode_;
public int mobileCountryCode_;
public int mobileNetworkCode_;
public int signalStrength_;
public int timingAdvance_;
public CellData(int cellId, int locationAreaCode,
int mobileCountryCode, int mobileNetworkCode,
int signalStrength, int timingAdvance )
{
cellId_ = cellId;
locationAreaCode_ = locationAreaCode;
mobileCountryCode_ = mobileCountryCode;
mobileNetworkCode_ = mobileNetworkCode;
signalStrength_ = signalStrength;
timingAdvance_ = timingAdvance;
}
@Override
public String toString()
{
return "[cid:"+cellId_+", lac:"+locationAreaCode_+
", mcc:"+mobileCountryCode_+", mnc:"+mobileNetworkCode_+
", rssi:"+signalStrength_+", ta:"+timingAdvance_+"]";
}
}
...@@ -85,7 +85,7 @@ public class WifiListener extends BroadcastReceiver ...@@ -85,7 +85,7 @@ public class WifiListener extends BroadcastReceiver
} }
mWifiMan = (WifiManager)getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE); mWifiMan = (WifiManager)getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (mWifiMan == null) if (mWifiMan == null)
{ {
return false; return false;
......
...@@ -100,8 +100,8 @@ public class GmsLocationProvider ...@@ -100,8 +100,8 @@ public class GmsLocationProvider
private class RequestHolder { private class RequestHolder {
public long mRequestId; public long mRequestId;
public LocationRequest mRequest = null; private LocationRequest mRequest = null;
public LocationCallback mCallback = null; private LocationCallback mCallback = null;
RequestHolder(long id, LocationRequest request, LocationCallback callback) { RequestHolder(long id, LocationRequest request, LocationCallback callback) {
mRequestId = id; mRequestId = id;
...@@ -141,7 +141,7 @@ public class GmsLocationProvider ...@@ -141,7 +141,7 @@ public class GmsLocationProvider
mlocationUpdatesThread.join(300); mlocationUpdatesThread.join(300);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); Log.e(TAG, "Exception in cppDestroyed: ", e);
} }
} }
......
...@@ -126,7 +126,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver ...@@ -126,7 +126,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver
final LocationManager lm = final LocationManager lm =
(LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
ret = lm.isProviderEnabled(provider); if (lm != null) {
ret = lm.isProviderEnabled(provider);
}
} }
catch(Throwable e) catch(Throwable e)
{ {
...@@ -144,7 +146,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver ...@@ -144,7 +146,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver
final LocationManager lm = final LocationManager lm =
(LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
return lm.getAllProviders().contains(provider); if (lm != null) {
return lm.getAllProviders().contains(provider);
}
} }
catch(Throwable e) catch(Throwable e)
{ {
......
...@@ -135,7 +135,7 @@ public class PassiveLocationProvider implements LocationListener ...@@ -135,7 +135,7 @@ public class PassiveLocationProvider implements LocationListener
static public Location lastKnownPosition(boolean fromSatelliteOnly) { static public Location lastKnownPosition(boolean fromSatelliteOnly) {
Log.i(TAG, "lastKnownPosition"); Log.i(TAG, "lastKnownPosition");
try { try {
if (null != mLocationManager && isPermissionGranted(mContext)) { if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
Log.i(TAG, "lastKnownPosition, mLocationManager not null"); Log.i(TAG, "lastKnownPosition, mLocationManager not null");
return mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); return mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
} }
...@@ -164,7 +164,7 @@ public class PassiveLocationProvider implements LocationListener ...@@ -164,7 +164,7 @@ public class PassiveLocationProvider implements LocationListener
static public boolean requestSingleUpdate(PendingIntent intent) { static public boolean requestSingleUpdate(PendingIntent intent) {
try { try {
if (null != mLocationManager && isPermissionGranted(mContext)) { if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
Criteria criteria = new Criteria(); Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.POWER_HIGH); criteria.setPowerRequirement(Criteria.POWER_HIGH);
mLocationManager.requestSingleUpdate(criteria, intent); mLocationManager.requestSingleUpdate(criteria, intent);
...@@ -178,7 +178,7 @@ public class PassiveLocationProvider implements LocationListener ...@@ -178,7 +178,7 @@ public class PassiveLocationProvider implements LocationListener
public boolean startLocationUpdates(final int minTime) { public boolean startLocationUpdates(final int minTime) {
try { try {
if (null != mLocationManager && isPermissionGranted(mContext)) { if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, minTime, 0, this, mlocationUpdatesLooper); mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, minTime, 0, this, mlocationUpdatesLooper);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment