I want to get user's location when user entered to AddComplaintFragment
I'm using LocationManager for this but it lasts about at least 4 or 5 seconds to get the location but I need to add this location information to my Complaint
model when the user clicks to makeComplaint
button. But since I don't know when the LocationManager exactly gets location it may return null at the mean time ( while user push the makeComplaint
button ). How can I prevent this ?
Thanks in advance.
Function to get location:
private fun requestLocationPermission() {
when {
ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED -> {
locationManager!!.requestSingleUpdate(
LocationManager.GPS_PROVIDER,
object : LocationListener {
override fun onLocationChanged(location: Location) {
val geocoder = Geocoder(requireContext(), Locale.getDefault())
val addresses =
geocoder.
getFromLocation(location!!.latitude, location.longitude, 1)
val address = addresses[0]
addressString = address.locality
latLongMap = hashMapOf()
val latitude = address.latitude
val longitude = address.longitude
latLongMap["latitude"] = latitude
latLongMap["longitude"] = longitude
println(addressString)
}
override fun onStatusChanged(
provider: String?,
status: Int,
extras: Bundle?
) {
}
override fun onProviderEnabled(provider: String) {
println("gps enabled")
}
override fun onProviderDisabled(provider: String) {
println("gps disabled")
}
},
Looper.getMainLooper()
)
}
else -> {
locationPermissionRequest.launch(
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}
}
}
Adding complaint to the model in the fragment's onViewCreated method. I'm storing lat and long in a global map variable:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_make_complaint.setOnClickListener {
val givenAddress = et_complaint_location.text.toString()
val complaintContent = et_complaint.text.toString()
val complaintLocation: String? = addressString
val complaint = Complaint(
userName = GlobalValues.userName.value.toString(),
content = complaintContent,
location = complaintLocation ?: givenAddress,
status = "Solving",
urgency = "Not urgent",
latitude = latLongMap["latitude"],
longitude = latLongMap["longitude"],
)
viewModel.saveImageToStorage(selectedPicture!!, complaint)
}
}
Here is a sample code of how I get Location using coroutines:
Here MyLocationProvider is a class which implements the whole flow of getting location and finally triggers MyLocationProvider.OnMyLocationUpdate on result. I am using suspendCoroutine but you can do the same thing using await method.