Skip to main content

Showing device location

A newer version of the Maps SDK is available
This page uses v9.7.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.3.1, in the Maps SDK documentation.

Showing the user's current location as a map annotation is a popular and often critical feature of location-based apps. The Maps SDK's LocationComponent makes use of the Maps SDK's runtime styling capabilities to display the device location icon within the map itself rather than on top as an Android view. Mapbox map layers and layer styling give you precise control over how you show a device's location on the map.

Note
This LocationComponent has replaced the now-deprecated Location Layer Plugin. The LocationComponent is integrated into the Maps SDK for Android so that you don't need to add any additional dependencies. It brings the same set of functionality that you were used to with the plugin.

Requesting location permissions

You'll need to request the Android-system location permission before using the LocationComponent. If you build your Android project targeting API level 23 or higher your application will need to request permissions during runtime. Handling this directly in your activity produces boilerplate code and can often be hard to manage. Read more about using the Mapbox Core Library for Android's PermissionsManager class.

Customization

The LocationComponent can be customized in many different ways. You can set the image drawables, opacities, colors, and more. See a full list of XML attributes for styling the LocationComponent via XML. The LocationComponentOptions class can be used if you prefer to customize the LocationComponent programmatically. Create a LocationComponentOptions object and then use whichever LocationComponentOptions.builder()'s various methods you'd like. Then use the built LocationComponentOptions object as parameter in LocationComponentActivationOptions#locationComponentOptions() or by passing it through as a parameter of the LocationComponent#applyStyle() method at a later time.

val locationComponentOptions = LocationComponentOptions.builder(this)
.layerBelow(layerId)
.foregroundDrawable(R.drawable.drawable_name)
.bearingTintColor(int color)
.accuracyAlpha(float)
.build()

val locationComponentActivationOptions = LocationComponentActivationOptions
.builder(this, style)
.locationComponentOptions(locationComponentOptions)
.build()

locationComponent = mapboxMap.locationComponent
locationComponent.activateLocationComponent(locationComponentActivationOptions)
example
Customizing device location

Use LocationComponent options to style the device location icon.

chevron-right

Active styling options

XML OptionExplanation
mapbox_foregroundDrawableDrawable image that would replace the blue circle.
mapbox_foregroundTintColorThe blue circle's color.
mapbox_backgroundDrawableDrawable image that would replace the white circle.
mapbox_backgroundTintColorThe white circle.
mapbox_bearingDrawableDrawable image that would replace the blue triangle.
mapbox_bearingTintColorThe blue triangle.
mapbox_navigationDrawableDrawable image used for the navigation state icon.
mapbox_accuracyAlphaThe larger light blue circle surrounding the device location icon.
mapbox_accuracyColorColor of the larger light blue circle surrounding the device location icon.
mapbox_elevationThe amount of space between the map and the device location icon. The elevation will adjust the size of the shadow as seen underneath the white circle. Passing 0f as the method parameter will remove the shadow effect.
mapbox_compassAnimationEnabledEnable or disable smooth animation of compass values for the blue triangle.
mapbox_accuracyAnimationEnabledEnable or disable smooth animation of the larger light blue accuracy circle surrounding the device location icon.
mapbox_pulsingLocationCircleEnabledEnable or disable the pulsing circle.
mapbox_pulsingLocationCircleFadeEnabledEnable or disable fading of the pulsing circle. If it fades, the circle's opacity decreases as its radius increases.
mapbox_pulsingLocationCircleColorSets the color of the pulsing circle.
mapbox_pulsingLocationCircleDurationSets the number of milliseconds it takes for a single pulse of the pulsing circle.
mapbox_pulsingLocationCircleRadiusThe maximum radius that a single pulse should expand the pulsing circle to.
mapbox_pulsingLocationCircleAlphaSets the opacity of the pulsing circle. The expected range is 0 to 1. An opacity of 1 makes the layer fully opaque.
mapbox_pulsingLocationCircleInterpolatorSets the pulsing circle's interpolation animation.
Note
mapbox_compassAnimationEnabled and mapbox_accuracyAnimationEnabled options are available because smooth animation of the LocationComponent can have a significant impact on a device's battery level. Disabling smooth compass and accuracy animations during scenarios where it'd be the only animation running on the device can decrease CPU usage by a significant amount.

Adding a pulsing circle to the LocationComponent is another styling option. The pulsing circle expands its radius over a certain amount of time to make the LocationComponent look as if it's a beacon that is emitting energy. This UI can give the LocationComponent and your map an even more engaging and energetic feel as the device stays still or moves around the map.

The pulsing circle is disabled by default. To show the default pulsing UI, pass true through the LocationComponentOptions.builder()'s pulseEnabled() method to enable the pulsing. The LocationComponentOptions.builder() has several methods (seen listed above) to customize the pulsing UI.

val locationComponentOptions = LocationComponentOptions.builder(this)
.pulseEnabled(true)
.pulseColor(Color.GREEN)
.pulseAlpha(.4f)
.pulseInterpolator(BounceInterpolator())
.build()

val locationComponentActivationOptions = LocationComponentActivationOptions
.builder(this, style)
.locationComponentOptions(locationComponentOptions)
.build()

locationComponent = mapboxMap.locationComponent
locationComponent.activateLocationComponent(locationComponentActivationOptions)

Stale styling options

XML OptionExplanation
mapbox_foregroundDrawableStaleDrawable image that would replace the gray circle's location.
mapbox_foregroundStaleTintColorThe gray circle's color.
mapbox_backgroundDrawableStaleDrawable image that would replace the white circle's location.
mapbox_backgroundStaleTintColorThe white circle's color.

Activating

MapboxMap#getLocationComponent() fetches the component and LocationComponent#activateLocationComponent() activates it.

The activateLocationComponent() method requires a built LocationComponentActivationOptions class. The LocationComponentActivationOptions class offers a convenient way to set activation options such as whether to use the default LocationEngine or a built LocationComponentOptions object.

Create a LocationComponentActivationOptions class with the builder pattern that is provided to you via the Maps SDK.

val locationComponentActivationOptions = LocationComponentActivationOptions
.builder(this, style)
.locationComponentOptions(locationComponentOptions)
.useDefaultLocationEngine(true)
.build()

Retrieve and activate the LocationComponent once the user has granted location permission and the map has fully loaded.

override fun onMapReady(mapboxMap: MapboxMap) {

mapboxMap.setStyle(Style.MAPBOX_STREETS) {

style -> enableLocationComponent()

}
}

@SuppressWarnings("MissingPermission")
private fun enableLocationComponent() {

// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {

// Get an instance of the component
val locationComponent = mapboxMap?.locationComponent

// Activate with a built LocationComponentActivationOptions object
locationComponent?.activateLocationComponent(LocationComponentActivationOptions.builder(this, style).build())

// Enable to make component visible
locationComponent?.isLocationComponentEnabled = true

// Set the component's camera mode
locationComponent?.cameraMode = CameraMode.TRACKING

// Set the component's render mode
locationComponent?.renderMode = RenderMode.COMPASS

} else {

permissionsManager = PermissionsManager(this)

permissionsManager?.requestLocationPermissions(this)

}
}
example
Showing device location

Add the device's location to the map.

chevron-right

Visibility

There is a single method to either enable or disable the LocationComponent's visibility after activation. The setLocationComponentEnabled() method requires a true/false boolean parameter. When set to false, this method will hide the device location icon and stop map camera animations from occurring.

locationComponent.isLocationComponentEnabled = true

RenderMode

The RenderMode class contains preset options for the device location image.

locationComponent?.renderMode = RenderMode.NORMAL

There are three types of RenderMode options:

RenderModeDescription
NORMALThis mode shows the device location, ignoring both compass and GPS bearing (no arrow rendered).
COMPASSThis mode shows the device location, as well as an arrow that is considering the compass of the device.
GPSThis mode shows the device location with the icon bearing updated from the Location updates being provided to the LocationComponent.
Note
The actual device location icon is highly customizable with methods such as LocationComponentOptions#foregroundDrawable() and LocationComponentOptions#backgroundDrawable().

CameraMode

The method LocationComponent#setCameraMode(@CameraMode.Mode int cameraMode) allows developers to set specific camera tracking instructions as the device location changes.

locationComponent?.cameraMode = CameraMode.TRACKING

There are 7 CameraMode options available:

CameraModeDescription
NONENo camera tracking.
NONE_COMPASSCamera does not track location, but does track compass bearing.
NONE_GPSCamera does not track location, but does track GPS Location bearing.
TRACKINGCamera tracks the device location, no bearing is considered.
TRACKING_COMPASSCamera tracks the device location, tracking bearing provided by the device compass.
TRACKING_GPSCamera tracks the device location, with bearing provided by a normalized Location#getBearing().
TRACKING_GPS_NORTHCamera tracks the device location, with bearing always set to north (0).

Here are a few examples from the LocationModesActivity in the Maps SDK's test application:

CameraMode.NORMAL

CameraMode.COMPASS

CameraMode.GPS

Traditional camera transitions will be canceled when any of the camera modes, besides CameraMode#NONE, are engaged. Use LocationComponent#zoomWhileTracking and LocationComponent#tiltWhileTracking to manipulate the camera in a tracking state. Use these two in combination with traditional camera transitions and MapboxMap#CancelableCallback to schedule fluid transitions.

When instantiating the LocationComponent for the first time, the map's max/min zoom levels are determined by LocationComponentOptions#MAX_ZOOM_DEFAULT and LocationComponentOptions#MIN_ZOOM_DEFAULT respectively. Adjust the zoom range with the LocationComponentOptions#maxZoom() and LocationComponentOptions#minZoom() methods in the LocationComponentOptions class.

Gesture thresholds while camera tracking

The LocationComponent is integrated with the Mapbox Gestures for Android library. The component will adjust the camera's focal point and increase thresholds to enable camera manipulation, like zooming in and out, without breaking tracking. Enabling this feature is explicitly opt-in because it overwrites custom gestures detection implementation set with MapboxMap#setGesturesManager(AndroidGesturesManager, boolean, boolean).

To enable the feature use LocationComponentOptions#trackingGesturesManagement(boolean).

You can adjust thresholds that need to be exceeded to break the tracking for one pointer gestures (like panning the map, double-tap to zoom in) and multi-pointer gestures (like scale gesture, two-tap to zoom out):

  • LocationComponentOptions#trackingInitialMoveThreshold(float) adjusts the minimum single pointer movement in pixels required to break camera tracking.
  • LocationComponentOptions#trackingMultiFingerMoveThreshold(float) adjusts minimum multi pointer movement in pixels required to break camera tracking (for example during scale gesture).
  • If either of these thresholds are exceeded and tracking is dismissed, developers can listen to this with a OnCameraTrackingChangedListener:
val locationComponent = mapboxMap?.locationComponent

locationComponent.addOnCameraTrackingChangedListener(object : OnCameraTrackingChangedListener {
override fun onCameraTrackingDismissed() {
// Tracking has been dismissed

}

override fun onCameraTrackingChanged(currentMode: Int) {
// CameraMode has been updated

}
})