Skip to content

Instantly share code, notes, and snippets.

@RaheemJnr
Created April 11, 2023 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RaheemJnr/ef3fce9ffe2afe7991995b9b8ce1060e to your computer and use it in GitHub Desktop.
Save RaheemJnr/ef3fce9ffe2afe7991995b9b8ce1060e to your computer and use it in GitHub Desktop.
/**
* Manages all location related tasks for the app.
*/
//A callback for receiving notifications from the FusedLocationProviderClient.
lateinit var locationCallback: LocationCallback
//The main entry point for interacting with the Fused Location Provider
lateinit var locationProvider: FusedLocationProviderClient
@SuppressLint("MissingPermission")
@Composable
fun getUserLocation(context: Context): LatandLong {
// The Fused Location Provider provides access to location APIs.
locationProvider = LocationServices.getFusedLocationProviderClient(context)
var currentUserLocation by remember { mutableStateOf(LatandLong()) }
DisposableEffect(key1 = locationProvider) {
locationCallback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
/**
* Option 1
* This option returns the locations computed, ordered from oldest to newest.
* */
for (location in result.locations) {
// Update data class with location data
currentUserLocation = LatandLong(location.latitude, location.longitude)
Log.d(LOCATION_TAG, "${location.latitude},${location.longitude}")
}
/**
* Option 2
* This option returns the most recent historical location currently available.
* Will return null if no historical location is available
* */
locationProvider.lastLocation
.addOnSuccessListener { location ->
location?.let {
val lat = location.latitude
val long = location.longitude
// Update data class with location data
currentUserLocation = LatandLong(latitude = lat, longitude = long)
}
}
.addOnFailureListener {
Log.e("Location_error", "${it.message}")
}
}
}
if (hasPermissions(
context,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
) {
locationUpdate()
} else {
askPermissions(
context, REQUEST_LOCATION_PERMISSION, Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
}
onDispose {
stopLocationUpdate()
}
}
//
return currentUserLocation
}
fun stopLocationUpdate() {
try {
//Removes all location updates for the given callback.
val removeTask = locationProvider.removeLocationUpdates(locationCallback)
removeTask.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d(LOCATION_TAG, "Location Callback removed.")
} else {
Log.d(LOCATION_TAG, "Failed to remove Location Callback.")
}
}
} catch (se: SecurityException) {
Log.e(LOCATION_TAG, "Failed to remove Location Callback.. $se")
}
}
@SuppressLint("MissingPermission")
fun locationUpdate() {
locationCallback.let {
//An encapsulation of various parameters for requesting
// location through FusedLocationProviderClient.
val locationRequest: LocationRequest =
LocationRequest.create().apply {
interval = TimeUnit.SECONDS.toMillis(60)
fastestInterval = TimeUnit.SECONDS.toMillis(30)
maxWaitTime = TimeUnit.MINUTES.toMillis(2)
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
//use FusedLocationProviderClient to request location update
locationProvider.requestLocationUpdates(
locationRequest,
it,
Looper.getMainLooper()
)
}
}
data class LatandLong(
val latitude: Double = 0.0,
val longitude: Double = 0.0
)
fun getReadableLocation(latitude: Double, longitude: Double, context: Context): String {
var addressText = ""
val geocoder = Geocoder(context, Locale.getDefault())
try {
val addresses = geocoder.getFromLocation(latitude, longitude, 1)
if (addresses?.isNotEmpty() == true) {
val address = addresses[0]
addressText = "${address.getAddressLine(0)}, ${address.locality}"
// Use the addressText in your app
Log.d("geolocation", addressText)
}
} catch (e: IOException) {
Log.d("geolocation", e.message.toString())
}
return addressText
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment