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

Android应用静止时速度波动过大,GPS Test显示0的技术问题

解决Android应用静止状态下速度值异常波动问题

问题背景

我的Android应用在设备静止时,速度值波动极大,甚至会跳到70km/h,此前从未出现该问题。我猜测这与GPS信号差有关,但另一款应用「GPS Test」却显示速度为0,推测对方可能做了异常数据过滤或采用了不同的定位方式。以下是我在前台服务中使用的代码:

override fun onCreate() {
    super.onCreate()
    mHandlerThread.start()
    mBroadcastManager = LocalBroadcastManager.getInstance(this)
    createNotificationChanel()
    requestLocationUpdates()
}
@SuppressLint("MissingPermission")
@Synchronized private fun requestLocationUpdates() {
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    createLocationRequest()
    val locationCallback: LocationCallback?
    locationCallback = object : LocationCallback() {
        @Synchronized override fun onLocationResult(locationResult: LocationResult) {
                val location = locationResult.lastLocation
                val speedKmph = ((location?.speed?: 0f) * 3.6).roundToInt()
                mSpeed = speedKmph
        }
    }
    mFusedLocationClient.requestLocationUpdates(
        mLocationRequest,
        locationCallback,
        mHandlerThread.looper
    )
}
@Synchronized   private fun createLocationRequest() {
 LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000)
 .setWaitForAccurateLocation(false)
 .setMinUpdateIntervalMillis(500)
 .build().also { mLocationRequest = it }
}

问题分析

FusedLocationProvider返回的speed字段可能来自GPS传感器或其他辅助定位源,当GPS信号弱(比如室内、高楼遮挡)时,定位数据会出现噪声,导致速度计算异常。而「GPS Test」这类专业应用会对原始定位数据做多层过滤,比如:

  • 忽略精度过低的定位结果
  • 对速度设置合理阈值,过滤超出静止/低速范围的异常值
  • 对连续的速度数据做平滑处理

解决方案

1. 基础异常值过滤

添加速度阈值和位置精度判断,过滤明显不合理的数据:

  • 静止状态下,速度一般不会超过5km/h,超过则视为异常值
  • 位置精度(location.accuracy)大于20米时,定位数据可信度低,忽略速度值

2. 速度平滑处理

使用滑动平均算法,取最近N个有效速度值的平均值,减少单次异常数据的影响。

3. 调整定位请求参数

开启setWaitForAccurateLocation(true),让系统等待更准确的定位结果再返回;适当调整更新间隔,避免过于频繁的更新引入噪声。

4. 基于位置变化计算速度

如果GPS原生速度不可靠,可以通过前后两次有效位置的距离和时间差计算速度,结果更稳定。

修改后的代码示例

// 用于存储最近的有效速度值,做滑动平均
private val speedHistory = mutableListOf<Int>()
private const val MAX_HISTORY_SIZE = 5
private const val MAX_STATIC_SPEED = 5 // 静止状态下最大允许速度(km/h)
private const val MAX_ALLOWED_ACCURACY = 20f // 最大允许的位置精度(米)

override fun onCreate() {
    super.onCreate()
    mHandlerThread.start()
    mBroadcastManager = LocalBroadcastManager.getInstance(this)
    createNotificationChanel()
    requestLocationUpdates()
}

@SuppressLint("MissingPermission")
@Synchronized private fun requestLocationUpdates() {
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    createLocationRequest()
    val locationCallback: LocationCallback?
    locationCallback = object : LocationCallback() {
        @Synchronized override fun onLocationResult(locationResult: LocationResult) {
            val location = locationResult.lastLocation ?: return
            
            // 过滤精度过低的定位结果
            if (location.accuracy > MAX_ALLOWED_ACCURACY) {
                mSpeed = 0
                return
            }
            
            // 计算原始速度(km/h)
            val rawSpeedKmph = ((location.speed ?: 0f) * 3.6).roundToInt()
            
            // 过滤异常高速值
            val validSpeed = if (rawSpeedKmph > MAX_STATIC_SPEED) 0 else rawSpeedKmph
            
            // 滑动平均处理
            speedHistory.add(validSpeed)
            if (speedHistory.size > MAX_HISTORY_SIZE) {
                speedHistory.removeAt(0)
            }
            mSpeed = speedHistory.average().roundToInt()
        }
    }
    mFusedLocationClient.requestLocationUpdates(
        mLocationRequest,
        locationCallback,
        mHandlerThread.looper
    )
}

@Synchronized private fun createLocationRequest() {
    LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000)
        .setWaitForAccurateLocation(true) // 等待准确位置
        .setMinUpdateIntervalMillis(1000) // 调整最小更新间隔
        .build().also { mLocationRequest = it }
}

内容的提问来源于stack exchange,提问作者ronenfe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 12:51:07