LocationComponent
This guide will demonstrate how to utilize the LocationComponent to represent the user's current location.
When implementing the LocationComponent, the application should request location permissions. Declare the need for foreground location in the AndroidManifest.xml
file. For more information, please refer to the Android Developer Documentation.
<manifest ... >
<!-- Always include this permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Include only if your app benefits from precise location access. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
Create a new activity named BasicLocationPulsingCircleActivity
:
- This Activity should implement the
OnMapReadyCallback
interface. TheonMapReady()
method is triggered when the map is ready to be used. - Add a variable
permissionsManager
to manage permissions. - Add a variable
locationComponent
to manage user location. - At the end of the
onCreate()
method, callcheckPermissions()
to ensure that the application can access the user's location.
/**
* This activity shows a basic usage of the LocationComponent's pulsing circle. There's no
* customization of the pulsing circle's color, radius, speed, etc.
*/
class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallback {
private var lastLocation: Location? = null
private lateinit var mapView: MapView
private var permissionsManager: PermissionsManager? = null
private var locationComponent: LocationComponent? = null
private lateinit var maplibreMap: MapLibreMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location_layer_basic_pulsing_circle)
mapView = findViewById(R.id.mapView)
if (savedInstanceState != null) {
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION, Location::class.java)
}
mapView.onCreate(savedInstanceState)
checkPermissions()
}
In the checkPermissions()
method, the PermissionManager is used to request location permissions at runtime and handle the callbacks for permission granting or rejection.Additionally, you should pass the results of Activity.onRequestPermissionResult()
to it. If the permissions are granted, call mapView.getMapAsync(this)
to register the activity as a listener for onMapReady event.
private fun checkPermissions() {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
mapView.getMapAsync(this)
} else {
permissionsManager = PermissionsManager(object : PermissionsListener {
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
Toast.makeText(
this@BasicLocationPulsingCircleActivity,
"You need to accept location permissions.",
Toast.LENGTH_SHORT
).show()
}
override fun onPermissionResult(granted: Boolean) {
if (granted) {
mapView.getMapAsync(this@BasicLocationPulsingCircleActivity)
} else {
finish()
}
}
})
permissionsManager!!.requestLocationPermissions(this)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
In the onMapReady()
method, first set the style and then handle the user's location using the LocationComponent.
To configure the LocationComponent, developers should use LocationComponentOptions.
In this demonstration, we create an instance of this class.
In this method:
- Use the annotation
@SuppressLint("MissingPermission")
to suppress warnings related to missing location access permissions. - In
setStyle(),
you can utilize other public and token-free styles like demotiles instead of the predefined styles. - For the builder of LocationComponentOptions, use
pulseEnabled(true)
to enable the pulse animation, which enhances awareness of the user's location. - Use method
buildLocationComponentActivationOptions()
to set LocationComponentActivationOptions, then activatelocatinoComponent
with it. - To apply options, make sure you call
activateLocationComponent()
oflocationComponent
. You can also setlocationComponent
's various properties likeisLocationComponentEnabled
,cameraMode
, etc... CameraMode.TRACKING
1 means that when the user's location is updated, the camera will reposition accordingly.locationComponent!!.forceLocationUpdate(lastLocation)
updates the the user's last known location.
@SuppressLint("MissingPermission")
override fun onMapReady(maplibreMap: MapLibreMap) {
this.maplibreMap = maplibreMap
maplibreMap.setStyle(TestStyles.getPredefinedStyleWithFallback("Streets")) { style: Style ->
locationComponent = maplibreMap.locationComponent
val locationComponentOptions =
LocationComponentOptions.builder(this@BasicLocationPulsingCircleActivity)
.pulseEnabled(true)
.build()
val locationComponentActivationOptions =
buildLocationComponentActivationOptions(style, locationComponentOptions)
locationComponent!!.activateLocationComponent(locationComponentActivationOptions)
locationComponent!!.isLocationComponentEnabled = true
locationComponent!!.cameraMode = CameraMode.TRACKING
locationComponent!!.forceLocationUpdate(lastLocation)
}
}
LocationComponentActivationOptions is used to hold the style, LocationComponentOptions and other locating behaviors.
- It can also be used to configure how to obtain the current location, such as LocationEngine and intervals.
- In this demonstration, it sets 750ms as the fastest interval for location updates, providing high accuracy location results (but with higher power consumption).
- For more information, please visit the documentation page.
private fun buildLocationComponentActivationOptions(
style: Style,
locationComponentOptions: LocationComponentOptions
): LocationComponentActivationOptions {
return LocationComponentActivationOptions
.builder(this, style)
.locationComponentOptions(locationComponentOptions)
.useDefaultLocationEngine(true)
.locationEngineRequest(
LocationEngineRequest.Builder(750)
.setFastestInterval(750)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.build()
)
.build()
}
For further customization, you can also utilize the foregroundTintColor()
and pulseColor()
methods on the LocationComponentOptions builder:
val locationComponentOptions =
LocationComponentOptions.builder(this@BasicLocationPulsingCircleActivity)
.pulseEnabled(true)
.pulseColor(Color.RED) // Set color of pulse
.foregroundTintColor(Color.BLACK) // Set color of user location
.build()
Here is the final results with different color configurations. For the complete content of this demo, please refer to the source code of the Test App.
-
A variety of camera modes determine how the camera will track the user location.
They provide the right context to your users at the correct time. ↩