Show the user's location
Draw the user’s location as a dot on the map and center the camera on each location update:
val locationState = rememberLocationState( provider = rememberDefaultLocationProvider(), headingProvider = rememberDefaultHeadingProvider(), )
val mapState = rememberMapState { LocationIndicatorLayer(id = "user", locationState = locationState)}
LocationTrackingEffect(locationState = locationState) { if (previousLocation == null) { // First location: zoom in on the user. mapState.animateCamera(CameraUpdate(center = currentLocation.position, zoom = 15.0)) } else { updateCamera(mapState) }}
MaplibreMap(state = mapState)The dot requires location access. Request location permission when the user chooses to display their location.
The example uses these APIs:
- A
LocationProviderreads the device’s location.rememberDefaultLocationProviderreturns the provider for the current platform. rememberLocationStatecollects location updates from the provider while the screen is visible and stores the latest one inLocationState.lastLocation.LocationIndicatorLayerdraws a dot at that location, with a circle that shows its accuracy. It draws nothing until the provider reports a location.LocationTrackingEffectruns its block each time the location or its direction changes. The example sets the zoom for the first location, then usesupdateCamerato center the camera on each update. By default,updateCameraalso rotates the map to the user’s movement direction or the device’s heading, when available. PassupdateBearing = BearingUpdate.Ignoreto preserve the camera’s bearing.
An optional heading provider supplies the device’s compass direction, which
the dot displays when available.
rememberDefaultHeadingProvider reads the compass on Android and
iOS, and supplies no heading on other platforms.
Pass enabled = false to LocationTrackingEffect to stop moving the camera.
Use camera gesture events
to disable tracking when the user pans the map.
Configure location updates
Section titled “Configure location updates”By default, rememberLocationState requests high accuracy and at most one
location update per second. To reduce battery use, configure lower accuracy or
less frequent updates with LocationRequest.
HeadingRequest configures heading updates:
val locationState = rememberLocationState( provider = provider, request = LocationRequest { accuracy = LocationAccuracy.Balanced minimumInterval = 5.seconds }, headingProvider = headingProvider, headingRequest = HeadingRequest { minimumInterval = 2.seconds }, )Omitted parameters use their default values.
Request location permission
Section titled “Request location permission”The library does not request location permission automatically. Call
LocationState.requestPermission in response to a user action,
such as pressing a button to display their location:
if (locationState.permission !is LocationPermission.Granted) { Button(onClick = locationState::requestPermission) { Text("Show my location") }}The platform shows its permission dialog.
If the user denies access, use the properties of
LocationPermission.NotGranted to determine whether to request
permission again or open system settings:
shouldShowRationaleistrue: explain why your app needs the location, then request permission again. Only Android sets this property.canRequestistrueornull: you can request permission again.canRequestisfalse: only the system settings can change the permission.rememberSystemSettingsLauncheropens them on the platforms that support this action.
val settings = rememberSystemSettingsLauncher()val permission = locationState.permissionif (permission is LocationPermission.NotGranted) { when { permission.shouldShowRationale -> { Text("Your location helps you find places nearby.") Button(onClick = locationState::requestPermission) { Text("Continue") } } permission.canRequest != false -> Button(onClick = locationState::requestPermission) { Text("Show my location") } settings.canOpenApplicationSettings -> Button(onClick = { settings.openApplicationSettings() }) { Text("Open settings") } }}Handle location errors
Section titled “Handle location errors”Use LocationState.availability to check for missing or
misconfigured location support. LocationState.status reports interruptions to
location updates, such as disabled location services. Display a message and
call LocationState.retry when the user chooses to retry:
val settings = rememberSystemSettingsLauncher()if (locationState.availability != LocationBackendAvailability.Available) { Text("Location is not available on this device.")}val status = locationState.statusif (status is LocationTrackingStatus.Unavailable) { if (status.reason == LocationUnavailableReason.ServicesDisabled) { Text("Turn on location services to see your position.") if (settings.canOpenLocationServicesSettings) { Button(onClick = { settings.openLocationServicesSettings() }) { Text("Open settings") } } } else { Text("Your location is not available right now.") } Button(onClick = locationState::retry) { Text("Try again") }}When availability is LocationBackendAvailability.Misconfigured,
its cause describes the configuration error.
Platform requirements
Section titled “Platform requirements”The JVM desktop runtimes in Platform setup include location support for their operating system.
Android
Section titled “Android”Declare the location permissions in your app’s manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />The default providers use Android’s built-in location service. To use Google’s fused location and heading instead, add the optional Google Play services runtime:
androidMain.dependencies { implementation("org.maplibre.compose:location-runtime-gms:0.20.0")}On devices without Google Play services, the default providers still use the built-in service.
For Huawei devices, location-runtime-hms provides fused location through
Huawei Mobile Services. It needs Huawei’s Maven repository,
https://developer.huawei.com/repo/, and the
HMS Core setup.
Add a location usage description to your app’s Info.plist. iOS shows this text
in the permission dialog:
<key>NSLocationWhenInUseUsageDescription</key><string>Shows your position on the map.</string>Browsers provide location only on pages served over HTTPS or from localhost.
See secure contexts.
For both JVM and native macOS apps, add a location usage description to the
app bundle’s Info.plist:
<key>NSLocationUsageDescription</key><string>Shows your position on the map.</string>Apps using App Sandbox or Hardened Runtime also need the location entitlement.
For JVM apps packaged with Compose Desktop, set the usage description in
nativeDistributions { macOS { infoPlist { extraKeysRawXml = ... } } }.
Configure entitlementsFile and runtimeEntitlementsFile if the location
entitlement is required.
Location uses the
XDG Location portal.
Without the portal, availability is Unsupported.