Skip to main content
GuidesAPI ReferenceExamplesFAQ

Get started with positioning

|

The Positioning module provides location data for navigation, tracking, and location-based services. Use GPS data from the device or integrate custom location data from external sources.


Grant permissions

Step 1: Add application location permissions

Configure location permissions based on the platform:

Add the following permissions to android/app/main/AndroidManifest.xml within the <manifest> block:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

More information about permissions can be found in the Android Manifest documentation.

Use the permission_handler plugin to request and manage location permissions:

warning

Follow the platform specific setup for the permission_handler package to correctly configure permissions for your application.

// For Android & iOS platforms, permission_handler package is used to ask for permissions.
final locationPermissionStatus = await Permission.locationWhenInUse.request();

if (locationPermissionStatus == PermissionStatus.granted) {
// After the permission was granted, we can set the live data source (in most cases the GPS).
// The data source should be set only once, otherwise we'll get GemError.exist error.
GemError setLiveDataSourceError = PositionService.setLiveDataSource();
showSnackbar("Set live datasource with result: $setLiveDataSourceError");
}

if (locationPermissionStatus == PermissionStatus.denied) {
// The user denied the permission
showSnackbar("Location permission denied");
}

if (locationPermissionStatus == PermissionStatus.permanentlyDenied) {
// The user permanently denied the permission
// The user should go to the app settings to enable the permission
showSnackbar("Location permission permanently denied");
}

The code requests the locationWhenInUse permission. If granted, call setLiveDataSource on the PositionService instance to use real GPS positions for navigation.

When the live data source is set and permissions are granted, the position cursor appears on the map as an arrow.

Tip

For debugging, use the Android Emulator's extended controls to mock the current position. On real devices, use apps like Mock Locations to simulate location data.

On iOS (simulators and devices), mock the location from Xcode for GPX replay. See more here.

If the location permission popup doesn't appear, verify the platform-specific setup is correct. Check the permission_handler package documentation and issue tracker.


Receive location updates

Register a callback function using the addImprovedPositionListener and addPositionListener methods to receive position updates. The listener is called continuously as new position data becomes available.

Tip

Consult the Positions guide for more information about the GemPosition class and the differences between raw positions and map-matched positions.

Raw positions

Use the addPositionListener method to listen for raw position updates as they're pushed to the data source or received via sensors:

PositionService.addPositionListener((GemPosition position) {
// Process the position
});

Map-matched positions

Use the addImprovedPositionListener method to register a callback for map-matched positions:

PositionService.addImprovedPositionListener((GemImprovedPosition position) {
// Current coordinates
Coordinates coordinates = position.coordinates;
print("New position: ${coordinates}");

// Speed in m/s (-1 if not available)
double speed = position.speed;

// Speed limit in m/s on the current road (0 if not available)
double speedLimit = position.speedLimit;

// Heading angle in degrees (N=0, E=90, S=180, W=270, -1 if not available)
double course = position.course;

// Information about current road (if it is in a tunnel, bridge, ramp, one way, etc.)
Set<RoadModifier> roadModifiers = position.roadModifiers;

// Quality of the current position
PositionQuality fixQuality = position.fixQuality;

// Horizontal and vertical accuracy in meters
double accuracyHorizontal = position.accuracyH;
double accuracyVertical = position.accuracyV;
});
info

During simulation, the positions provided through the addImprovedPositionListener and addPositionListener methods correspond to the simulated locations generated as part of the navigation simulation process.


Get current location

Use the position getter from the PositionService class to retrieve the current location. This returns a GemPosition object with the latest location information or null if no position data is available. Use this to access the most recent position without registering for continuous updates:

GemPosition? position = PositionService.position;

if (position == null) {
showSnackbar("No position");
} else {
showSnackbar("Position: ${position.coordinates}");
}

A similar getter is provided for map-matched positions: improvedPosition returns GemImprovedPosition? instead of GemPosition?.