I am trying to understand how to use Location services in an Android App developed using Jetpack Compose. Following some tutorials I came across; I have written the following code component to understand how to achieve this.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
GetLocationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
LocationDisplay()
}
}
}
}
}
@OptIn(ExperimentalPermissionsApi::class)
@SuppressLint("MissingPermission")
@Composable
private fun LocationDisplay() {
var locationText by remember { mutableStateOf("")}
val locationPermissionsState = rememberMultiplePermissionsState(
listOf(
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION,
)
)
if (locationPermissionsState.allPermissionsGranted) {
Column {
Text(locationText)
Button(onClick = { /*TODO*/ }) {
Text("Stop")
}
}
val appContext = LocalContext.current.applicationContext
val fusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(appContext)
fusedLocationProviderClient.lastLocation
.addOnSuccessListener {location ->
location?.let {locationText = "Location ${it.latitude}, ${it.longitude}"}
Log.d("TAG", locationText)
}
}
else {
Column {
Button(
onClick = { locationPermissionsState.launchMultiplePermissionRequest() }
) { Text("Request permissions") }
}
}
}
As I understood this approach subscribes a lambda function to capture location updates and update a Text composable with the updated value. Therefore, the location updates continue once started.
I am trying to understand how I can query the location once instead of registering a listener. Is this possible? Alternatively, if I use the same approach, is there a way to de-register the callback once a valid reading is obtained?
I have tried to look at other methods provided by fusedLocationProviderClient.lastLocation hoping to see a function that would removeOnSuccessListner. I could not find out a way to do this.
I also tried to see if I can use a co-routine to await() for a location result. I did not succeed in getting this approach to work.
You can use something like this to get the location only once:
You can simply call this object to get the location.