Android应用位置更新不显示问题排查与修正请求
问题排查与修正方案
核心问题分析
你的应用在授予位置权限后仍弹出"Go to setting"提示,主要原因是权限检查逻辑错误:代码要求同时拥有ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION权限才能获取位置,但Android只需要其中任意一个权限即可访问位置信息。此外还有几个次要问题可能导致异常或内存泄漏。
具体修正步骤
1. 修正权限检查逻辑
修改LocationUtils中的hasLocationPermission方法,将逻辑与(&&)改为逻辑或(||):
fun hasLocationPermission(): Boolean { return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED }
2. 修正权限请求回调逻辑
在LocationDisplay的权限请求回调中,同样将权限判断改为逻辑或:
val requestPermissionLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val hasFine = permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true val hasCoarse = permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true if (hasFine || hasCoarse) { locationUtils.requestLocationUpdates(viewModel) } else { // 原有提示逻辑保留 } }
3. 适配权限对应的定位精度
避免仅授予粗略位置权限时使用高精度定位导致的安全异常,修改LocationUtils的requestLocationUpdates方法:
private var locationCallback: LocationCallback? = null @SuppressLint("MissingPermission") fun requestLocationUpdates(viewModel: locationViewModel) { // 先停止已有定位更新,避免重复回调 stopLocationUpdates() val hasFinePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED val priority = if (hasFinePermission) { Priority.PRIORITY_HIGH_ACCURACY } else { Priority.PRIORITY_BALANCED_POWER_ACCURACY } locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) locationResult.lastLocation?.let { location -> viewModel.updateLocation(LocationData(location.latitude, location.longitude)) // 获取到位置后可选择停止更新,节省资源 stopLocationUpdates() } } } val locationRequest = LocationRequest.Builder(priority, 1000) .setMinUpdateIntervalMillis(500) .build() _fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback!!, Looper.getMainLooper()) } // 添加停止定位更新的方法,防止内存泄漏 fun stopLocationUpdates() { locationCallback?.let { _fusedLocationClient.removeLocationUpdates(it) locationCallback = null } }
4. 安全获取Activity上下文
在LocationDisplay中使用LocalActivity.current替代强制类型转换,避免ClassCastException:
val activity = LocalActivity.current // 权限合理性检查部分修改为: val rationalRequired = activity?.let { ActivityCompat.shouldShowRequestPermissionRationale(it, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(it, Manifest.permission.ACCESS_COARSE_LOCATION) } ?: false
5. 清理定位资源
在LocationDisplay中添加DisposableEffect,确保页面销毁时停止定位更新:
DisposableEffect(Unit) { onDispose { locationUtils.stopLocationUpdates() } }
额外注意事项
确保AndroidManifest.xml中已声明所需权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
内容的提问来源于stack exchange,提问作者Md Nasif
相关产品推荐
相关产品推荐

