在 Jetpack Compose 应用程序上,有没有办法使用 LocationServices.getFusedLocationProviderClient 查询一次位置值

问题描述 投票:0回答:2

我试图了解如何在使用 Jetpack Compose 开发的 Android 应用程序中使用位置服务。经过一些教程后,我遇到了;我编写了以下代码组件来了解如何实现这一目标。

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") }
        }
    }
}

据我了解,这种方法订阅 lambda 函数来捕获位置更新并使用更新后的值更新文本可组合项。因此,位置更新一旦开始就会继续。

我试图了解如何查询一次位置而不是注册侦听器。这可能吗?或者,如果我使用相同的方法,有没有办法在获得有效读数后取消注册回调?

我尝试查看 fusedLocationProviderClient.lastLocation 提供的其他方法,希望看到一个可以删除 OnSuccessListner 的函数。我找不到方法来做到这一点。

我还尝试看看是否可以使用协同例程来等待()获取位置结果。我没有成功地让这种方法发挥作用。

android android-location android-fusedlocation jetpack
2个回答
0
投票

您可以浏览此存储库,因为它可能会对您有所帮助。

回购:https://github.com/philipplackner/WeatherApp


0
投票

您可以使用类似的方法仅获取一次位置:

    internal object LocationService {
        suspend fun getCurrentLocation(context: Context): Location {
            val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
            when {
                !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> throw LocationServiceException.LocationDisabledException()
                !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> throw LocationServiceException.NoNetworkEnabledException()
                else -> {
                    val locationProvider = LocationServices.getFusedLocationProviderClient(context)
                    val request = CurrentLocationRequest.Builder()
                        .setPriority(Priority.PRIORITY_BALANCED_POWER_ACCURACY)
                        .build()
    
                    runCatching {
                        val location = if (ActivityCompat.checkSelfPermission(
                                context,
                                Manifest.permission.ACCESS_FINE_LOCATION
                            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                                context,
                                Manifest.permission.ACCESS_COARSE_LOCATION
                            ) != PackageManager.PERMISSION_GRANTED
                        ) {
                            throw LocationServiceException.MissingPermissionException()
                        } else {
                            locationProvider.getCurrentLocation(request, null).await()
                        }
                        return location
                    }.getOrElse {
                        throw LocationServiceException.UnknownException(stace = it.stackTraceToString())
                    }
                }
            }
        }
        sealed class LocationServiceException : Exception() {
            class MissingPermissionException : LocationServiceException()
            class LocationDisabledException : LocationServiceException()
            class NoNetworkEnabledException : LocationServiceException()
            class UnknownException(val stace: String) :LocationServiceException()
    }

}

您可以简单地调用该对象来获取位置。

© www.soinside.com 2019 - 2024. All rights reserved.