After many days or weeks I end up using a BottomSheetScaffold.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LocationScreen(
startLocationUpdates: ()->Unit,
context: Context,
currentLocation: LatLng
) {
////// This permissions are use down bellow at a Button Click event that
////// actually calls for the GPS location. The Button is part of the BottomSheet content.
val permissions = arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
)
////// startActivityForResult function is deprecated and in Jetpack Compose the solution is
////// to use "rememberLauncherForActivityResult" with "ActivityResultContracts"
val launchMultiplePermissions = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissionMaps ->
val areGranted = permissionMaps.values.reduce { acc, next -> acc && next }
if (areGranted) {
locationRequired = true
startLocationUpdates()
Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()
}
}
var readable by remember { mutableStateOf("") }
//val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
BottomSheetScaffold(
//modifier = Modifier.heightIn(min=0.dp, max=400.dp),
scaffoldState = scaffoldState,
sheetPeekHeight = 590.dp,
sheetSwipeEnabled = false,
sheetContent = {
Column(
Modifier
.fillMaxWidth()
.padding(6.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (currentLocation.latitude != 0.toDouble() && currentLocation.longitude != 0.toDouble() && readable != "") {
WebViewScreen(location = currentLocation) //, address = readable)
showdialog.value = false
} else {Text(text = "Please click [Get your location]")}
}
}) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Your location: ${currentLocation.latitude}/${currentLocation.longitude}")
if (currentLocation.latitude != 0.toDouble() && currentLocation.longitude != 0.toDouble()) {
Text(
text = "Readable location: $currentLocation"
)
location = ""
readable = getReadableLocation(currentLocation.latitude, currentLocation.longitude, context)
glocation = currentLocation
}
//////Here is where the permissions are used to call for the system permissions pop up.
Button(onClick = {
if (permissions.all {
ContextCompat.checkSelfPermission(
context,
it
) == PackageManager.PERMISSION_GRANTED
}) {
//Get Locations
////// Here once the permissions are granted I call my function that actually gets the GPS Location
startLocationUpdates()
} else {
launchMultiplePermissions.launch(permissions)
}
=
}) {
Text(text = "Get your location")
}
}
}
}
}
Maybe you can read this post for better explanation. In there the example is directed toward Pictures instead of GPS location.
The GPS Location function is the following:
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationCallback: LocationCallback
override fun onResume() {
super.onResume()
if (locationRequired)
startLocationUpdates()
}
override fun onPause() {
super.onPause()
if (this::locationCallback.isInitialized) {
locationCallback?.let {
fusedLocationClient?.removeLocationUpdates(it)
}
}
}
@SuppressLint("MissingPermission")
private fun startLocationUpdates() {
locationCallback?.let {
val locationRequest = LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY, 100
)
.setWaitForAccurateLocation(false)
.setMinUpdateIntervalMillis(3000)
.setMaxUpdateDelayMillis(100)
.build()
fusedLocationClient?.requestLocationUpdates(
locationRequest,
it,
Looper.getMainLooper()
)
}
}
This code is written in the MainActivity before the onCreate and is pass to the Screen as a Lambda function along the currentLocation:LatLng which is calculated/retrieved by the "startLocationUpdates" function already detail above.
Then inside the onCreate the following code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
setContent {
var currentLocation by remember {
mutableStateOf(LatLng(0.toDouble(), 0.toDouble()))
}
locationCallback = object : LocationCallback() {
override fun onLocationResult(p0: LocationResult) {
super.onLocationResult(p0)
for (location in p0.locations) {
currentLocation = LatLng(location.latitude, location.longitude)
}
}
}
MainTheme { ...
NavHost(navController = navController, startDestination = "MainScreen") {
composable("LocationScreen") {
LocationScreen(
{ startLocationUpdates() },
this@MainActivity,
currentLocation
)
}
...