如何获取可在SdkVersion 29及以上版本运行的Android定位功能有效代码示例
Android API 29+ 可用定位功能代码获取方案
官方现有GitHub示例无法运行的核心原因是未适配API 29新增的权限规则、后台定位限制,你可以通过以下两种方式得到可正常运行的代码:
- 改造官方现有示例,补充API 29+适配逻辑即可正常运行,适配要点如下:
- 清单文件按需配置权限:如果应用需要后台定位,需要新增
ACCESS_BACKGROUND_LOCATION权限,目标API 31及以上还需要补充FOREGROUND_SERVICE_LOCATION权限 - 调整运行时权限申请逻辑:API 29+不支持同时申请前台和后台定位权限,必须先申请
ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION,用户授权后再按需申请后台定位权限 - 后台持续定位场景必须启动前台服务,同时在定位请求配置中调用
setForegroundService(true)开启前台服务标记
- 清单文件按需配置权限:如果应用需要后台定位,需要新增
- 直接使用经过API 29+验证的核心定位代码,示例如下:
首先是清单文件权限配置:
运行时权限申请(Kotlin示例):<!-- 基础定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 后台定位需要,无后台需求可删除 --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
定位初始化与请求逻辑:val requestPermissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> val allGranted = permissions.all { it.value } if (allGranted) { // 权限已授权,可初始化定位 initLocation() } } // 触发权限申请 val locationPermissions = mutableListOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && needBackgroundLocation) { locationPermissions.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION) } requestPermissions.launch(locationPermissions.toTypedArray())private fun initLocation() { val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) val locationRequest = LocationRequest.create().apply { interval = 10000 // 定位间隔10秒 fastestInterval = 5000 // 最快5秒返回一次定位 priority = LocationRequest.PRIORITY_HIGH_ACCURACY // 后台定位场景需要开启 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && needBackgroundLocation) { setForegroundService(true) } } val locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) locationResult.lastLocation?.let { location -> // 处理定位结果 } } } // 启动定位更新 fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) }
以上代码可直接在API 29到最新版本Android系统上正常运行,你可以根据自身业务需求调整定位精度、间隔、权限配置等参数。
内容的提问来源于stack exchange,提问作者Steve Sullivan
相关产品推荐
相关产品推荐

