Retrieving a location
When you have chosen a positioning method that suits your app, you can request the location (or fix) of a device in your app. When you have found a fix, you can use the QGeoPositionInfo class to extract location information. There are two ways that you can request location information:
- Single fixes, in which you find the location of a device at a single point of time each time that you make a request.
- Multiple fixes, in which you find the location of a device and get updates at regular intervals.
Retrieving a single fix
If your app needs a single location fix at a certain point in time, you can just request a single fix. For example, if your social networking app is updating a status with the user's current location, you can request a single fix. Here's how to get a single fix for a device in your app:
//Set up the position info source.
QGeoPositionInfoSource *src = QGeoPositionInfoSource::createDefaultSource(this);
// Connect the positionUpdated() signal to a
// slot that handles position updates.
bool positionUpdatedConnected = connect(src,
SIGNAL(positionUpdated(const QGeoPositionInfo &)),
this,
SLOT(positionUpdated(const QGeoPositionInfo &)));
if (positionUpdatedConnected) {
// Signal was successfully connected.
// Request a single fix and wait for the
// positionUpdated() signal to be emitted.
src->requestUpdate();
} else {
// Failed to connect to signal.
}
Specifying a timeout period
You can specify a time limit to retrieve the location of a device. If the location isn't found within the specified timeout period, the updateTimeout() signal is emitted. If you requested a single fix, using requestUpdate(120000), the updateTimeout() signal is emitted when the location can't be found within the timeout period (in this case, 2 minutes or 120 seconds). To use the timeout, you must connect a slot that handles the timeout to the updateTimeout() signal. Here's a code sample:
//Set up the position info source.
QGeoPositionInfoSource *src = QGeoPositionInfoSource::createDefaultSource(this);
// Connect the positionUpdated() signal to a
// slot that handles position updates.
bool positionUpdatedConnected = connect(src,
SIGNAL(positionUpdated(const QGeoPositionInfo &)),
this,
SLOT(positionUpdated(const QGeoPositionInfo &)));
if (positionUpdatedConnected) {
// positionUpdated() SIGNAL connected.
// Get the position of the device
src->requestUpdate(120000);
} else {
// positionUpdated() SIGNAL failed to connect.
}
// Connect the updateTimeout() signal to a
// slot that handles timeouts.
bool updateTimeoutConnected = connect(src,
SIGNAL(updateTimeout()),
this,
SLOT(positionUpdateTimeout()));
if (updateTimeoutConnected) {
// updateTimeout() SIGNAL connected.
} else {
// updateTimeout() SIGNAL failed to connect.
}
You need a slot to handle the positionUpdated() and positionTimeout() signals. Here's how you can define this in your .hpp and .cpp files:
void MyPositionEngine::positionUpdated
(const QGeoPositionInfo & pos)
{
// Use the position information to update your UI.
}
void MyPositionEngine::positionUpdateTimeout()
{
// A timeout occurred, no position update available.
}
Retrieving the last known location
The last known location is a special case of a single fix. The last known location of a device can be found using the lastKnownPosition() function. You can restrict this to only retrieve the last known location received from a satellite positioning method by setting fromSatellitePositioningMethodsOnly to true. This returns the last location fix received by any location-based app on the device. This could be the location fix found by another app running location services, not necessarily your app. The lastKnownPosition() function returns the value immediately.
QGeoPositionInfo lastPosition = src->lastKnownPosition(true);
Retrieving multiple fixes
If your app needs to get continuous or multiple location fixes at certain intervals, you can get fixes at regular intervals by using startUpdates(). Every time a location fix is found, the positionUpdated() signal is emitted. Here's how you can do this:
//Set up the position info source.
QGeoPositionInfoSource *src = QGeoPositionInfoSource::createDefaultSource(this);
// Connect the updateTimeout() signal to a
// slot that handles timeouts.
bool updateTimeoutConnected = connect(src,
SIGNAL(updateTimeout()),
this,
SLOT(positionUpdateTimeout()));
if (updateTimeoutConnected) {
// updateTimeout() SIGNAL connected.
} else {
// updateTimeout() SIGNAL failed to connect.
}
// Connect the positionUpdated() signal to a
// slot that handles position updates.
bool positionUpdatedConnected = connect(src,
SIGNAL(positionUpdated(const QGeoPositionInfo &)),
this,
SLOT(positionUpdated(const QGeoPositionInfo &)));
if (positionUpdatedConnected) {
// Signal and slot connected.
// Start receiving updates to the position of the device.
src->startUpdates();
} else {
// Failed to connect signal.
}
You need a slot to handle the positionUpdated() and positionTimeout() signals. Here's an example of something that you could define in your .hpp and .cpp files:
void MyPositionEngine::positionUpdated
(const QGeoPositionInfo & pos)
{
// Use the position information to update your UI.
}
void MyPositionEngine::positionUpdateTimeout()
{
// A timeout occurred, no position update available.
}
Specifying intervals for multiple fixes
In most cases, you need to set an interval between requests to find the location of a device. The interval is set in milliseconds using the setUpdateInterval() function. For example, the following code sample specifies that location fixes should be provided every second.
// Emit updates every second if available
QGeoPositionInfoSource *src = QGeoPositionInfoSource::createDefaultSource(this);
if (src)
src->setUpdateInterval(1000);
If you don't specify an interval, updates are provided every 5 seconds.
You can change the interval between updates in your app at any time using setUpdateInterval(). You don't need to stop requesting updates to change the interval between updates.
Starting and stopping updates
You can start and stop regular updates using startUpdates() and stopUpdates().
src->startUpdates();
When startUpdates() is called, each update will be delivered using a positionUpdated() signal.
src->stopUpdates();
Getting updates in the background
If you want your app to continue to get location fixes while your app is in the background or minimized, you must set the canRunInBackground property to true. For example, this could be used by a fleet tracking application that needs to update the dispatch office with the current location of the vehicle while the app is minimized.
src->setProperty(“canRunInBackground", true);
Handling errors with updateTimeout()
The updateTimeout() signal is emitted when the positioning source determines that it's temporarily unable to provide a fix. It continues to try to find a position, so your code doesn't need to handle retrying to find a location fix. However, your app can give the user a hint that positioning is temporarily unavailable. For example, a navigational app could give the user a "Lost satellite signal" alert or toast when it receives an updateTimeout() signal.
Your app will only get one updateTimeout() signal to indicate that it can't provide a location fix at this time. Any subsequent errors from an implicit retry won't be reported to the app.
Eventually, your app will get a positionUpdated() signal, and it will reset the timer to 0 and send another updateTimeout() signal if it determines that it can't get a location update within the timeout period.
If you want to specify an absolute timeout period for the first fix, you can use:
src->setProperty("responseTime", "15000");
This forces the location manager to return the first fix within 15 seconds. All subsequent fixes are returned at intervals defined by setUpdateInterval().
Last modified: 2013-03-21