Location services¶
A sensor that can capture the geographical location of the device.
Usage¶
The location services of a device can be accessed using the
toga.App.location
attribute. This attribute exposes an API that allows you
to check if you have have permission to access location services; if permission
exists, you can capture the current location of the device, and/or set a handler to be
notified when position changes occur.
The Location API is asynchronous. This means the methods that have long-running
behavior (such as requesting permissions and requesting a location) must be
await
-ed, rather than being invoked directly. This means they must be invoked from
inside an asynchronous handler:
import toga
class MyApp(toga.App):
...
async def determine_location(self, widget, **kwargs):
location = await self.location.current_location()
All platforms require some form of permission to access the location service. To
confirm if you have permission to use the location service while the app is running,
you can call Location.has_permission
; you can request permission using
Location.request_permission()
.
If you wish to track the location of the user while the app is in the background, you
must make a separate request for background location permissions using
Location.request_background_permission()
. This request must be made after
foreground permissions have been requested and confirmed. To confirm if you have
permission to use location while the app is in the background, you can call
Location.has_background_permission
.
Toga will confirm whether the app has been granted permission to use Location
services before invoking any location API. If permission has not yet been granted, or
if permission has been denied by the user, a PermissionError
will be raised.
To continuously track location, add an on_change
handler to the location service,
then call Location.start_tracking()
. The handler will be invoked whenever a new
location is obtained:
class MyApp(toga.App):
...
async def location_update(self, location, altitude, **kwargs):
print(f"You are now at {location}, with altitude {altitude} meters")
def start_location(self):
# Install a location handler
self.location.on_change = self.location_update
# Start location updates. This assumes permissions have already been
# requested and granted.
try:
self.location.start_tracking()
except PermissionError:
print("User has not permitted location tracking.")
If you no longer wish to receive location updates, call Location.stop_tracking()
.
Notes¶
Apps that use location services must be configured to provide permissions to access those services. The permissions required are platform specific:
iOS:
NSLocationWhenInUseUsageDescription
must be defined in the app’sInfo.plist
file. If you want to track location while the app is in the background, you must also defineNSLocationAlwaysAndWhenInUseUsageDescription
, and add thelocation
andprocessing
values toUIBackgroundModes
.macOS: The
com.apple.security.personal-information.location
entitlement must be enabled, andNSLocationUsageDescription
must be defined in the app’sInfo.plist
file.Android: At least one of the permissions
android.permission.ACCESS_FINE_LOCATION
orandroid.permission.ACCESS_COARSE_LOCATION
must be declared; if only one is declared, this will impact on the precision available in location results. If you want to track location while the app is in the background, you must also define the permissionandroid.permission.ACCESS_BACKGROUND_LOCATION
.
On macOS, there is no distinction between “background” permissions and “while-running” permissions.
On iOS, if the user has provided “allow once” permission for foreground location tracking, requests for background location permission will be rejected.
On Android prior to API 34, altitude is reported as the distance above the WGS84 ellipsoid datum, rather than Mean Sea Level altitude.
Reference¶
- class toga.hardware.location.Location(app)¶
- Parameters:
app (App)
- current_location()¶
Obtain the user’s current location using the location service.
If the app hasn’t requested and received permission to use location services, a
PermissionError
will be raised.This is an asynchronous method. If you call this method in a synchronous context, it will start the process of requesting the user’s location, but will return immediately. The return value can be awaited in an asynchronous context, but cannot be used directly.
If location tracking is enabled, and an
on_change
handler is installed, requesting the current location may also cause that handler to be invoked.- Returns:
An asynchronous result; when awaited, returns the current
toga.LatLng
of the device.- Raises:
PermissionError – If the app has not requested and received permission to use location services.
- Return type:
LocationResult
- property has_background_permission: bool¶
Does the app have permission to use location services in the background?
If the platform requires the user to explicitly confirm permission, and the user has not yet given permission, this will return
False
.
- property has_permission: bool¶
Does the app have permission to use location services?
If the platform requires the user to explicitly confirm permission, and the user has not yet given permission, this will return
False
.
- property on_change: OnLocationChangeHandler¶
The handler to invoke when an update to the user’s location is available.
- request_background_permission()¶
Request sufficient permissions to capture the user’s location in the background.
If permission has already been granted, this will return without prompting the user.
Before requesting background permission, you must first request and receive foreground location permission using
Location.request_permission
. If you ask for background permission before receiving foreground location permission, aPermissionError
will be raised.This is an asynchronous method. If you invoke this method in synchronous context, it will start the process of requesting permissions, but will return immediately. The return value can be awaited in an asynchronous context, but cannot be used directly.
- Returns:
An asynchronous result; when awaited, returns True if the app has permission to capture the user’s location while running in the background; False otherwise.
- Raises:
PermissionError – If the app has not already requested and received permission to use location services.
- Return type:
PermissionResult
- request_permission()¶
Request sufficient permissions to capture the user’s location.
If permission has already been granted, this will return without prompting the user.
This method will only grant permission to access location services while the app is in the foreground. If you want your application to have permission to track location while the app is in the background, you must call this method, then make an additional permission request for background permissions using
Location.request_background_permission()
.This is an asynchronous method. If you invoke this method in synchronous context, it will start the process of requesting permissions, but will return immediately. The return value can be awaited in an asynchronous context, but cannot be used directly.
- Returns:
An asynchronous result; when awaited, returns True if the app has permission to capture the user’s location; False otherwise.
- Return type:
PermissionResult
- start_tracking()¶
Start monitoring the user’s location for changes.
An
on_change
callback will be generated when the user’s location changes.- Raises:
PermissionError – If the app has not requested and received permission to use location services.
- Return type:
None
- stop_tracking()¶
Stop monitoring the user’s location.
- Raises:
PermissionError – If the app has not requested and received permission to use location services.
- Return type:
None
- protocol toga.hardware.location.OnLocationChangeHandler¶
-
Classes that implement this protocol must have the following methods / attributes:
- __call__(*, service, location, altitude, **kwargs)¶
A handler that will be invoked when the user’s location changes.
- Parameters:
service (Location) – the location service that generated the update.
location (LatLng) – The user’s location as (latitude, longitude).
altitude (float | None) – The user’s altitude in meters above mean sea level. Returns None if the altitude could not be determined.
kwargs (Any) – Ensures compatibility with arguments added in future versions.
- Return type: