6#include <QGeoPositionInfo>
9using namespace Qt::StringLiterals;
18 QGeoPositionInfoSource(parent)
20 androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(
this);
21 androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(
this);
23 parseParameters(parameters);
26 setPreferredPositioningMethods(AllPositioningMethods);
28 m_requestTimer.setSingleShot(
true);
29 connect(&m_requestTimer, &QTimer::timeout,
this,
30 &QGeoPositionInfoSourceAndroid::requestTimeout);
32 m_regularUpdatesTimer.setSingleShot(
false);
33 connect(&m_regularUpdatesTimer, &QTimer::timeout,
this,
34 &QGeoPositionInfoSourceAndroid::regularUpdatesTimeout);
41 if (m_requestTimer.isActive()) {
42 m_requestTimer.stop();
52 int previousInterval = updateInterval();
55 if (msec == previousInterval)
58 QGeoPositionInfoSource::setUpdateInterval(msec);
61 reconfigureRunningSystem();
66 return AndroidPositioning::lastKnownPosition(fromSatellitePositioningMethodsOnly,
72 return AndroidPositioning::availableProviders();
77 PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
78 QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
79 if (previousPreferredPositioningMethods == preferredPositioningMethods())
83 reconfigureRunningSystem();
98 return m_useAltitudeConverter;
104 if (error != QGeoPositionInfoSource::NoError)
105 emit QGeoPositionInfoSource::errorOccurred(m_error);
110 m_useAltitudeConverter = parameters.value(kUseAltitudeConverter,
false).toBool();
118 m_error = QGeoPositionInfoSource::NoError;
120 if (preferredPositioningMethods() == 0) {
121 setError(UnknownSourceError);
125 updatesRunning =
true;
127 m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
128 m_regularUpdatesErrorRaised =
false;
129 QGeoPositionInfoSource::Error error = AndroidPositioning::startUpdates(androidClassKeyForUpdate);
130 if (error != QGeoPositionInfoSource::NoError) {
131 updatesRunning =
false;
134 m_regularUpdatesTimer.start(kRegularUpdatesTimerInterval);
143 updatesRunning =
false;
144 m_regularUpdatesTimer.stop();
150 if (m_requestTimer.isActive())
153 m_error = QGeoPositionInfoSource::NoError;
156 setError(QGeoPositionInfoSource::UpdateTimeoutError);
163 m_requestTimer.start(timeout);
168 if (updatesRunning && updateInterval() <= timeout)
171 const QGeoPositionInfoSource::Error error =
172 AndroidPositioning::requestUpdate(androidClassKeyForSingleRequest, timeout);
173 if (error != QGeoPositionInfoSource::NoError) {
174 m_requestTimer.stop();
182 if (m_requestTimer.isActive())
183 m_requestTimer.stop();
185 m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
186 m_regularUpdatesErrorRaised =
false;
188 emit positionUpdated(pInfo);
195 if (!m_requestTimer.isActive())
198 queuedSingleUpdates.append(pInfo);
202 const qsizetype maxPossibleUpdates =
203 (preferredPositioningMethods() == QGeoPositionInfoSource::AllPositioningMethods)
206 if (queuedSingleUpdates.size() == maxPossibleUpdates) {
207 m_requestTimer.stop();
214 if (updatesRunning && !m_regularUpdatesErrorRaised) {
215 m_regularUpdatesErrorRaised =
true;
216 setError(QGeoPositionInfoSource::UpdateTimeoutError);
219 setError(QGeoPositionInfoSource::ClosedError);
224 emit supportedPositioningMethodsChanged();
232 if (queuedSingleUpdates.isEmpty()) {
233 setError(QGeoPositionInfoSource::UpdateTimeoutError);
237 auto byAccuracy = [](
const QGeoPositionInfo &info,
const QGeoPositionInfo &best) {
239 const qint64 timeDelta = best.timestamp().secsTo(info.timestamp());
240 if (abs(timeDelta) > 20)
241 return timeDelta > 0;
244 if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) &&
245 best.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
247 return info.attribute(QGeoPositionInfo::HorizontalAccuracy) <
248 best.attribute(QGeoPositionInfo::HorizontalAccuracy);
252 if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
258 QGeoPositionInfo best = *std::min_element(queuedSingleUpdates.begin(),
259 queuedSingleUpdates.end(), byAccuracy);
260 queuedSingleUpdates.clear();
261 emit positionUpdated(best);
266 if (!m_regularUpdatesErrorRaised) {
267 const auto now = QDateTime::currentMSecsSinceEpoch();
268 if ((now - m_lastUpdateTime) > (updateInterval() + kUpdateFromColdStart)) {
269 m_regularUpdatesErrorRaised =
true;
270 setError(QGeoPositionInfoSource::UpdateTimeoutError);
276
277
278
bool useAltitudeConverter() const
virtual void stopUpdates() override
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly=false) const override
Returns an update containing the last known position, or a null update if none is available.
void processSinglePositionUpdate(const QGeoPositionInfo &pInfo)
void locationProvidersChanged()
~QGeoPositionInfoSourceAndroid()
virtual void requestUpdate(int timeout=0) override
void processPositionUpdate(const QGeoPositionInfo &pInfo)
void setPreferredPositioningMethods(PositioningMethods methods) override
void setUpdateInterval(int msec) override
int minimumUpdateInterval() const override
Error error() const override
Returns the type of error that last occurred.
PositioningMethods supportedPositioningMethods() const override
Returns the positioning methods available to this source.
void locationProviderDisabled()
void stopUpdates(int androidClassKey)
static constexpr auto kUseAltitudeConverter
static constexpr int kRegularUpdatesTimerInterval
static constexpr int kUpdateFromColdStart