You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin开发Android应用如何正确请求GPS位置更新?

Kotlin实现Android高频位置更新方案

你现有代码的两个核心问题:

  1. 时间间隔参数设为了5000毫秒(5秒),不符合你要的2-3秒更新需求
  2. 最小位移阈值设为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:48:02