Comprehensive Guide: Get User Location on Android with Jetpack Compose
In this article, we are going to learn about Google’s fused location provider client for accessing user location on Android, compare it with Android’s native LocationManager API, permission handling for location, build a real-world compose app and more. Let’s begin.
What is Fused Location Provider ?
Fused location provider is a location API from Google Play Services. It combines several additional services from Android to get the location, like Wi-Fi and GPS based on their availability for battery efficiency.
Why Fused Location Provider API ??
To access the device’s geographical location, Android natively has a LocationManager api. Why do we need this API? Well, Android has this LocationManager API to access all the location updates. But when we have a requirement to combine different services, as I mentioned above based on availability. We need to write a lot of boilerplate code to achieve the same thing in the fused provider client. It offers a simple API to work with considering power efficiency.
Key Components when requesting Location
Before we implementing requesting location on a android, We must know what are the type of location service available for us. here it follows
- Foreground Location
- last known location
- location updates
- Background Location
Note: In this article we are going to only focus on foreground location access, especially (2. location updates in detail). Not all apps have a requirement for accessing locations in the background. Special use cases only have this requirement, like for Geo-fencing.
- last known location:
Using the fused location provider, we are able to get the last known location of the device using the getLastLocation()
function. It returns the cached location object from the past currently available. It may return null if there are no cached values available.
fusedLocationClient.lastLocation
.addOnSuccessListener { location : Location? ->
// last known location. this can be null.
}
For use cases like map, driving, walking, apps the location updates would be more appropriate.
2. location updates
For current continued location update at a specific intervals location updates will be used. it return the updates based on the currently-available location service such as Wi-Fi and GPS.
Request the location permissions.
To access system location, we need to request two permissions at runtime, ACCESS_FINE_LOCATION
and ACCESS_COARSE_LOCATION
, because on Android 12 (API level 31) or higher, users have a choice to provide a coarse location (approx. location) only, even if we declare fine permissions on the manifest. Read more about it here.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Handling permission request
Here, the below code implementation uses google Accompanist Permissions library to make things easier for this demo, If you like to handle the permissions yourself in a jetpack compose, I recommend using rememberLauncherForActivityResult()
API.
In this implementation, we have a better way to request location permissions as per our need for both ACCESS_FINE_LOCATION
and ACCESS_COARSE_LOCATION
, and we also handle the permission rejection by showing a rational alert dialog to the user if they deny the permission we have requested.
Start location request
Before we going to receive the location update, we need to request the location that specifies the required level of accuracy/power consumption and desired update interval, and the device automatically makes the appropriate changes to system settings. These settings are defined by the LocationRequest
data object.
The LocationRequest object has multiple parameters to configure. Here are some important parameters as follows:
Sets the setPriority(int priority) of the location request.
The default value is Priority.PRIORITY_BALANCED_POWER_ACCURACY
— Use this setting to request location precision to within a city block, which is an accuracy of approximately 100 meters.
Priority.PRIORITY_HIGH_ACCURACY
— Use this setting to request the most precise location possible.
setInterval(long intervalMillis) — Sets the desired interval of location updates.
Create the location request and set the parameters as shown in this code sample:
fun createLocationRequest() {
val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 2000)
.build()
}
- The priority of
PRIORITY_HIGH_ACCURACY
is ideal for map apps, the requires current real time locations.
Once the location request is in place, we can start the regular location updates by calling requestLocationUpdates()
Note: requestLocationUpdates() has two function overloads. One parameter is (LocationRequest request, LocationCallback callback, Looper looper) and the second one is (LocationRequest with a Pending Intent.) If you receive location updates in the background, pending intent overload will be used. For foreground use cases, prefer to listen for location updates via a listener or callback instead of a pending intent.
Here, we receive updates in the foreground, so let’s use theLocationCallback
approach. Call requestLocationUpdates()
, passing it your instance of the LocationRequest
object, and a LocationCallback
.
Note: Here we use DisposableEffect for receiving and removing listing updates for location, based on application lifecycle. Receive when the application is in the foreground using our requestLocationUpdates and stop when the application is in the background using
removeLocationUpdates(locationCallback).
Finally, receive updates using location update callback
With our LocationCallback.onLocationResult()
callback method we get the LocationResult. Using this we get a Location
objects containing location’s latitude and longitude. The following snippet shows how you can do that.
// Only register the location updates effect when we have a locationRequest
if (locationRequest != null) {
LocationUpdatesEffect(locationRequest!!) { locationResult ->
for (currentLocation in locationResult.locations) {
// Update UI with location data as per your needs.
}
}
}
Here is the full implementation of this code by building a LocateU jetpack compose location demo app:
Conclusion
In this article, I explained what is fused location provider API is, and how to implement it in our Android project and more. I hope you like this article and learn its use-cases. If yes, please consider supporting me 👏. To stay motivated to creating high-quality free articles, I will see you on my next interesting topic with an interesting article.
Signing off, Mubarak Native