Iam retrieving the users location (longitude and lattitude). I made a class LocationLiveData, this is working fine. What i want is to show the longitude in a TextField, so when the location of the user changes it has to update the TextField. At this moment the textfield is only updating the longitude when i trigger a recompose of the composable.
It seems like there is going something wrong in the observeAsState()
The composable:
@Composable
fun HomeScreen(application:Application) {
//connect to viewModel
val viewModelLocations: ApplicationViewModel = ApplicationViewModel(application = application)
//observe the data in viewModel
val location by viewModelLocations.getLocationLiveData().observeAsState()
Column() {
OutlinedTextField(value = location.longitude, onValueChange = { location.longitude = it})
Text("The textfield has this text: " + location.longitude)
}
}
The ViewModel:
class ApplicationViewModel(application: Application): AndroidViewModel(application) {
private val locationLiveData = LocationLiveData(context = application)
fun getLocationLiveData(): LocationLiveData {
var data = locationLiveData
return data
}
//start the location updates
fun startLocationUpdates() {
locationLiveData.startLocationUpdates()
}
}
Class LocationLiveData (here iam retrieving the users location) Note: if i print the .value its printing the userslocation longitude and lattitude
class LocationLiveData(var context: Context): MutableLiveData<LocationDetails>() {
private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
override fun onActive() {
super.onActive()
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
return
}
fusedLocationClient.lastLocation.addOnSuccessListener {
location -> location.also {
setLocationData(it)
}
}
}
fun startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
return
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}
private fun setLocationData(location: Location?) {
//location.let (maak een functie, deze wordt alleen uitgvoerd indien locatie niet null is)
location?.let { it ->
//value is observed in LiveData
value = LocationDetails(
longitude = it.longitude.toString(),
lattitude = it.latitude.toString()
)
println("value $value")
}
}
//onInactive als de LiveData niet meer geobserveerd wordt
//we willen unsubscriben van de location updates (moet dus stoppen met updaten)
override fun onInactive() {
super.onInactive()
fusedLocationClient.removeLocationUpdates(locationCallback)
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
println("we have a new location result")
locationResult ?: return //als er een result is dan prima, zo niet dan just return (elvis operator)
for (location in locationResult.locations) {
setLocationData(location = location)
}
}
}
companion object {
val ONE_MINUTE: Long = 1000
@RequiresApi(Build.VERSION_CODES.S)
val locationRequest : com.google.android.gms.location.LocationRequest = com.google.android.gms.location.LocationRequest.create().apply {
interval = ONE_MINUTE
fastestInterval = ONE_MINUTE/4
priority = LocationRequest.QUALITY_HIGH_ACCURACY
}
}
}