我正在尝试在 Compose 中获取用户位置。
我找到了这个链接并尝试了米奇解决方案。但它有一个无限循环,并且不显示小吃栏。从其他链接我读到它需要连接到脚手架,但似乎 M3 不再有效。
我将无限循环更改为:
LaunchedEffect(true) {
while (true) {
isGPSEnabled = isGPSEnabled(context)
delay(2.seconds)
}
}
致:
LaunchedEffect(true) {
while (!isGPSEnabled) { //while (true) {
isGPSEnabled = isGPSEnabled(context)
delay(2.seconds)
}
}
但我不知道如何让小吃栏显示:
DisposableEffect(
isGPSEnabled,
permissions.shouldShowRationale,
permissions.allPermissionsGranted,
) {
if (!permissions.allPermissionsGranted || permissions.shouldShowRationale) {
scope.launch {
val result = snackbarHostState.showSnackbar(
"Missing required permissions",
"Grant",
withDismissAction = true,
duration = SnackbarDuration.Indefinite,
)
when (result) {
SnackbarResult.Dismissed -> {
}
SnackbarResult.ActionPerformed -> {
permissions.launchMultiplePermissionRequest()
}
}
}
return@DisposableEffect SimulatedDisposableEffectResult
}
我知道代码 [val result = SnackbarHostState.showSnackbar(...) ] 被执行,因为我在调试中有一个断点到达它。它停留在那里,永远不会到达 [when(result)],因为它有 [duration = SnackbarDuration.Indefinite]
在我的屏幕上,我有以下调用该函数的内容:
Image(painter = painterResource(R.drawable.baseline_my_location_24),
contentDescription = "Get Coordinates",
modifier = Modifier
.clickable {
doGet = true
}
.size(40.dp)
)
if (doGet) {
ExampleForegroundLocationTrackerScreen()
}
这是出于测试目的,但我真的想接收值(纬度,经度)以将它们显示在屏幕上,然后保存在数据库中。
许多天或几周后,我最终使用了 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
startLocationUpdates()
} else {
launchMultiplePermissions.launch(permissions)
}
=
}) {
Text(text = "Get your location")
}
}
}
}
}
也许您可以阅读这篇post以获得更好的解释。那里的示例是针对图片而不是 GPS 位置。