Commit a0fcccc4 authored by Vyacheslav Koscheev's avatar Vyacheslav Koscheev

GLPv3+cell support

parent ba663d28
......@@ -2,9 +2,9 @@
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
Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License
......@@ -41,53 +41,30 @@
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
{
return compare(other, true);
}
const int32_t CellData::java_integer_max_value = std::numeric_limits<int32_t>::max();
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
bool CellData::isEmpty() const
void CellData::Data::accept(DataOperation & operation) 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_);
}
void CellData::clear()
{
memset(this, 0, sizeof(*this));
}
}
} // namespace Mobility
......@@ -2,9 +2,9 @@
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
Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License
......@@ -45,39 +45,47 @@ namespace Mobility {
struct CellData
{
CellData();
bool compare( const CellData& other, bool compareSignalStrength ) const;
bool operator==(const CellData& other) const;
bool operator!=(const CellData& other) const;
bool isEmpty() const; // used as sign of validity
void clear();
// 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)
int cellId;
// Location Area Code (LAC for GSM, NID for CDMA)
int locationAreaCode;
// Mobile Country Code (MCC for GSM and CDMA)
int mobileCountryCode;
// Mobile Network Code (MNC for GSM, SID for CDMA)
int mobileNetworkCode;
// Radio signal strength measured in dBm.
/* convert GSM asu (TS 27.007 8.5) to these as follows:
<rssi>:
0 -113 dBm or less
1 -111 dBm
2...30 -109... -53 dBm
31 -51 dBm or greater
99 not known or not detectable
*/
int signalStrength;
// Represents the distance from the cell tower. Each unit is roughly 550 meters.
int timingAdvance;
struct DataOperation
{
virtual void execute(const QString & key, int32_t value) = 0;
virtual void execute(const QString & key, const QString & value) = 0;
};
struct Data
{
Data(int32_t cell_id);
void accept(DataOperation & operation) const;
// required, int.
// Cell ID (CID) for GSM
// Base Station ID (BID) for CDMA
// UTRAN/GERAN Cell Identity (UC-Id) for WCDMA.
int32_t cell_id_;
// optional, int.
// Location Area Code (LAC) for GSM and WCDMA.
// Network ID (NID) for CDMA сетей. 0 <= LAC <= 65535.
int32_t location_area_code_;
// optional, int. 0 <= MCC < 1000
int32_t mobile_country_code_;
// optional, int. 0 <= MNC < 1000
int32_t mobile_network_code_;
// optional, int. RSSI в dBm.
int32_t signal_strength_;
// optional, int
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 @@
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
Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License
......@@ -37,23 +37,33 @@
*/
#include "QAndroidCellDataProvider.h"
#include <QtCore/QtDebug>
#include <QAndroidQPAPluginGap.h>
#include "TJniObjectLinker.h"
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)
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[] = {
{"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);
{"cellUpdate", "(JIIIII)V", reinterpret_cast<void*>(Java_CellListener_cellUpdate)},
{"onSignalChanged", "(J)V", reinterpret_cast<void*>(Java_CellListener_onSignalChanged)},
{"cellUpdate", "(JLjava/lang/String;IIIIII)V", reinterpret_cast<void*>(Java_CellListener_cellUpdate)},
};
......@@ -74,48 +84,92 @@ QAndroidCellDataProvider::~QAndroidCellDataProvider()
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()
{
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);
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 (current_data_ && cid > 0 && cid != CellData::java_integer_max_value)
{
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()
{
QReadLocker locker(&lock_data_);
return last_data_;
}
}
} // namespace Mobility
......@@ -2,9 +2,9 @@
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
Vyacheslav O. Koscheev <vok1980@gmail.com>
Ivan Avdeev marflon@gmail.com
Sergey A. Galin sergey.galin@gmail.com
Distrbuted under The BSD License
......@@ -39,6 +39,7 @@
#pragma once
#include <QtCore/QObject>
#include <QtCore/QReadWriteLock>
#include <QJniHelpers.h>
#include "IJniObjectLinker.h"
#include "CellData.h"
......@@ -59,18 +60,24 @@ public:
CellDataPtr getLastData();
private:
friend void JNICALL Java_CellListener_cellUpdate(JNIEnv *, jobject, jlong native_ptr, jint cid, jint lac, jint mcc, jint mnc, jint rssi);
void cellUpdate(int cid, int lac, int mcc, int mnc, int 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);
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:
void start();
void stop();
void requestData();
signals:
void update();
void updated();
void dataReady();
private:
CellDataPtr last_data_;
CellDataPtr current_data_;
QReadWriteLock lock_data_;
};
}
......@@ -53,7 +53,6 @@ Q_DECL_EXPORT void JNICALL Java_WifiListener_scanUpdate(JNIEnv *, jobject, jlong
static const JNINativeMethod methods[] = {
{"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)},
};
......
/*
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
}
mWifiMan = (WifiManager)getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (mWifiMan == null)
{
return false;
......
......@@ -100,8 +100,8 @@ public class GmsLocationProvider
private class RequestHolder {
public long mRequestId;
public LocationRequest mRequest = null;
public LocationCallback mCallback = null;
private LocationRequest mRequest = null;
private LocationCallback mCallback = null;
RequestHolder(long id, LocationRequest request, LocationCallback callback) {
mRequestId = id;
......@@ -141,7 +141,7 @@ public class GmsLocationProvider
mlocationUpdatesThread.join(300);
}
} catch (InterruptedException e) {
e.printStackTrace();
Log.e(TAG, "Exception in cppDestroyed: ", e);
}
}
......
......@@ -126,7 +126,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver
final LocationManager lm =
(LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
ret = lm.isProviderEnabled(provider);
if (lm != null) {
ret = lm.isProviderEnabled(provider);
}
}
catch(Throwable e)
{
......@@ -144,7 +146,9 @@ public class LocationManagerProvidersListener extends BroadcastReceiver
final LocationManager lm =
(LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
return lm.getAllProviders().contains(provider);
if (lm != null) {
return lm.getAllProviders().contains(provider);
}
}
catch(Throwable e)
{
......
......@@ -135,7 +135,7 @@ public class PassiveLocationProvider implements LocationListener
static public Location lastKnownPosition(boolean fromSatelliteOnly) {
Log.i(TAG, "lastKnownPosition");
try {
if (null != mLocationManager && isPermissionGranted(mContext)) {
if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
Log.i(TAG, "lastKnownPosition, mLocationManager not null");
return mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
}
......@@ -164,7 +164,7 @@ public class PassiveLocationProvider implements LocationListener
static public boolean requestSingleUpdate(PendingIntent intent) {
try {
if (null != mLocationManager && isPermissionGranted(mContext)) {
if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.POWER_HIGH);
mLocationManager.requestSingleUpdate(criteria, intent);
......@@ -178,7 +178,7 @@ public class PassiveLocationProvider implements LocationListener
public boolean startLocationUpdates(final int minTime) {
try {
if (null != mLocationManager && isPermissionGranted(mContext)) {
if (null != mContext && null != mLocationManager && isPermissionGranted(mContext)) {
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, minTime, 0, this, mlocationUpdatesLooper);
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