Kotlin开发Android应用如何正确请求GPS位置更新?
Kotlin实现Android高频位置更新方案
你现有代码的两个核心问题:
- 时间间隔参数设为了5000毫秒(5秒),不符合你要的2-3秒更新需求
- 最小位移阈值设为10米,只有用户移动超过10米才会触发回调,不符合无位移也要拿最新位置的要求
推荐实现方案(使用Fused Location Provider,兼容性和可靠性更高)
这是官方推荐的定位实现,比原生LocationManager适配性更好,不会出现不同厂商设备回调差异大的问题。
第一步:添加依赖
在模块级build.gradle的dependencies块中添加定位库依赖:
implementation 'com.google.android.gms:play-services-location:21.0.1'
第二步:核心代码实现
在需要接收定位的Activity/Fragment中添加如下代码:
import com.google.android.gms.location.* class YourActivity : AppCompatActivity() { // 定位客户端实例 private lateinit var fusedLocationClient: FusedLocationProviderClient // 定位请求配置 private val locationRequest = LocationRequest.create().apply { interval = 2500 // 常规更新间隔2.5秒,符合2-3秒的需求区间 fastestInterval = 2000 // 最快回调间隔2秒,避免其他应用请求更频繁时收到超出预期的更新 priority = LocationRequest.PRIORITY_HIGH_ACCURACY // 高精度模式,优先使用GPS smallestDisplacement = 0f // 位移阈值0米,无论是否移动都会触发回调 } // 定位结果回调 private val locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) locationResult.lastLocation?.let { latestLocation -> // 此处拿到最新位置,可存入全局变量供你后续调用 // 示例:打印定位结果 println("最新位置:纬度${latestLocation.latitude}, 经度${latestLocation.longitude}") } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_your) // 初始化定位客户端 fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) // 确认已获得定位权限后启动更新 if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { startLocationUpdates() } } @SuppressLint("MissingPermission") private fun startLocationUpdates() { fusedLocationClient.requestLocationUpdates( locationRequest, locationCallback, Looper.getMainLooper() ) } // 页面退后台时停止定位更新,避免耗电 override fun onPause() { super.onPause() fusedLocationClient.removeLocationUpdates(locationCallback) } // 回到前台时重启定位 override fun onResume() { super.onResume() if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { startLocationUpdates() } } }
如果你坚持使用原生LocationManager实现
修改你现有代码的参数即可达到需求:
val locationListener: LocationListener = this // 时间间隔改为2000毫秒,位移阈值改为0米 locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 2000, 0, locationListener )
注意:原生LocationManager的GPS_PROVIDER仅在户外开阔场景下能稳定返回结果,室内场景大概率无法获取定位,且不同厂商的系统定制会导致回调逻辑差异较大
注意事项
- 2-3秒的高频定位功耗较高,建议仅在前台使用场景保持该间隔,后台运行时拉长间隔减少耗电
- 如需后台持续定位,必须配合前台Service使用,Android 12及以上系统会严格限制后台无前台服务的定位行为
- 你已经申请了前后台定位权限,配合上述代码即可稳定拿到更新后的最新位置
内容的提问来源于stack exchange,提问作者Enrico Cortinovis
相关产品推荐
相关产品推荐

