Usage¶
The artifacts come with a LocationService
class which provides a high-level implementations for handling
location-related operations in your applications. It uses a LocationProvider
to manage the actual
location updates. On Android it defaults to AndroidLocationProvider
and on iOS it defaults to
CLLocationProvider
if not specified.
Initialization¶
To use LocationService
, you first need to initialize it. There are few ways to do this:
Using the default provider¶
This method uses the default AndroidLocationProvider
or CLLocationProvider
for iOS.
import com.addhen.klocation.LocationService
val context: Context = /* your application context */
val locationService = LocationService(context)
Using the FusedLocationProvider¶
The FusedLocationProvider
is a wrapper around the Google Play services
FusedLocationProviderClient
API. To use it:
Add the following dependencies to your Gradle build file:
dependencies {
implementation 'com.google.android.gms:play-services-location:<version>'
// Add other required dependencies
}
FusedLocationProvider
:
val context: Context = // your application context
val fusedLocationProvider = FusedLocationProvider(
context = context,
intervalMs = 1000, // Update interval in milliseconds (optional)
priority = Priority.PRIORITY_HIGH_ACCURACY // Location priority (optional)
)
You can then pass the fusedLocationProvider
to the LocationService
:
val locationService = LocationService(fusedLocationProvider)
Note: The FusedLocationProvider
is only available on Android.
Using a custom location provider¶
val customProvider: LocationProvider = // your custom location provider
val locationService = LocationService(locationProvider = customProvider)
Using the LocationService
¶
For klocation artifact¶
This guide will walk you through using the LocationService
APIs for consuming location in your
non compose-based applications.
Requesting location updates¶
To receive continuous location updates, use the requestLocationUpdates()
method:
locationService.requestLocationUpdates()
.distinctUntilChanged()
.onEach { state ->
// Handle the location state
when (state) {
is LocationState.LocationDisabled -> {
// Location is disabled
}
is LocationState.Error -> {
// Handle the error
}
LocationState.NoNetworkEnabled -> {
// No network enabled
}
LocationState.PermissionMissing -> {
// Permission missing
}
is LocationState.CurrentLocation<*> -> {
// Handle the current location
// for Android cast as `android.location.Location`
// for iOS cast as `CLLocation`
val location = state.libLocation as? Location
// Or use the extension variable `state.location` for Android and iOS `state.cllocation`
// Do something with the location
}
}
}.launchIn(viewModelScope)
Getting the last known location¶
To retrieve the last known location, use the getLastKnownLocation()
method:
viewModelScope.launch {
try {
val locationState = locationService.getLastKnownLocation()
// Handle the location state
when (locationState) {
is LocationState.LocationDisabled -> {
// Location is disabled
}
is LocationState.Error -> {
// Handle the error
}
LocationState.NoNetworkEnabled -> {
// No network enabled
}
LocationState.PermissionMissing -> {
// Permission missing
}
is LocationState.CurrentLocation<*> -> {
// Handle the current location
// for Android cast as `android.location.Location`
// for iOS cast as `CLLocation`
val location = state.libLocation as? Location
// Or use the extension variable `state.location` for Android and iOS `state.cllocation`
// Do something with the location
}
}
} catch (e: Throwable) {
ensureActive()
// Handle the error
}
}
For klocation-compose artifact¶
This guide will walk you through using the APIs provided for consuming location in your compose-based application.
Requesting location updates¶
To receive continuous location updates, use the locationUpdatesState()
function in your Composable:
import com.addhen.klocation.compose.locationUpdatesState
@Composable
fun LocationTracking(locationService: LocationService) {
val locationState by locationUpdatesState(locationService)
val info = getLocation(locationState)
Text(text = info)
}
@Composable
private fun getLocation(locationState: LocationState): String {
val locationInfo = when (locationState) {
is LocationState.LocationDisabled -> {
"Location disabled"
}
is LocationState.Error -> {
"Error: ${(locationState as LocationState.Error).message}"
}
LocationState.NoNetworkEnabled -> {
"No network enabled"
}
LocationState.PermissionMissing -> {
"Permission missing"
}
is LocationState.CurrentLocation<*> -> {
val location = locationState.location
"${location?.latitude},${location?.longitude}"
}
}
return locationInfo
}
Getting the last known location¶
To get the last known location, use the lastKnownLocationState()
function in your Composable:
import com.addhen.klocation.compose.lastKnownLocationState
@Composable
fun LastKnownLocation(locationService: LocationService) {
val locationState by lastKnownLocationState(locationService)
val info = getLocation(locationState)
Text(text = info)
}
Using recomposition keys¶
The lastKnownLocationState()
function has overloads
that accept recomposition keys. These are
useful when you want to force a refresh of the last known location based on certain conditions:
import com.addhen.klocation.compose.lastKnownLocationState
@Composable
fun RefreshableLastLocation(
locationService: LocationService,
refreshTrigger: Boolean
) {
val lastLocationState by lastKnowLocationState(
locationService,
refreshTrigger
)
// Do something with lastLocationState
}
refreshTrigger
changes.
Best practices¶
- Permission Handling: Ensure you have the necessary location permissions before using these functions.
- Error Handling: Always handle the LocationState.Error case to provide a good user experience.
- Lifecycle Awareness: These Composable functions are automatically lifecycle-aware, but ensure you're not calling them unnecessarily.
- Performance: Use lastKnownLocationState() when you don't need continuous updates, as it's less resource-intensive.
- Recomposition Keys: Use keys judiciously. Overusing them can lead to unnecessary recompositions and battery drain.