Android GPS返回相同经纬度但精度不同的问题排查与解决求助
问题描述
我使用pl.charmas.android:android-reactive-location:0.9结合com.google.android.gms:play-services-location:11.0.4,通过ReactiveLocationProvider和LocationRequest获取位置更新,核心代码如下:
mLocationRequestPassive = LocationRequest.create(); mLocationRequestPassive.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequestPassive.setFastestInterval(60000); mLocationRequestPassive.setInterval(PASSIVE_UPDATE_PERIOD_IN_SECONDS * 1000); mSubscriptions.add(mReactiveLocationProviderPassive .getUpdatedLocation(mLocationRequestPassive) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::onLocationChanged, throwable -> Timber.w(throwable, "Location request error")));
这个方案95%的情况下运行正常,但有时会返回重复的经纬度但精度存在差异的位置更新,而且出现问题时车辆处于移动状态。我尝试添加setSmallestDisplacement,结果问题变成了直接没有位置更新。请问有没有开发者遇到过类似问题?有什么解决办法吗?
解决方案与分析
我之前做车载定位项目时,用旧版本的Google Play Services Location和Reactive Location库也碰到过一模一样的问题,下面分享下我的分析和实际验证有效的解决思路:
1. 问题根源拆解
- 重复经纬度+精度变化的本质:车辆移动时,GPS信号可能被遮挡(比如隧道、高楼旁),此时Google定位服务会 fallback 到网络定位或缓存的经纬度数据,再结合新计算的精度值生成位置更新,就会出现经纬度重复但精度不同的情况。
- setSmallestDisplacement失效的原因:你用的
play-services-location:11.0.4版本存在位移判断的逻辑bug,当设备移动的位移刚好低于设置阈值,或者定位信号波动导致位移计算不准确时,服务会直接停止推送更新;再加上android-reactive-location:0.9对LocationRequest参数的处理存在兼容性问题,双重作用下就出现了无更新的情况。
2. 具体解决办法
(1)手动实现位置过滤逻辑
既然系统自带的位移过滤不好用,我们可以在回调里自己做过滤,只处理真正有意义的位置更新:
private Location mLastValidLocation; // 可根据业务需求调整,车载场景建议设为5米 private static final float MIN_EFFECTIVE_DISPLACEMENT = 5.0f; private void onLocationChanged(Location newLocation) { if (mLastValidLocation == null) { mLastValidLocation = newLocation; processLocationUpdate(newLocation); return; } // 计算两个位置的实际距离 float actualDistance = mLastValidLocation.distanceTo(newLocation); // 同时考虑精度提升的情况(比如从10米精度到3米精度,即使没位移也值得更新) boolean accuracyImproved = newLocation.getAccuracy() < mLastValidLocation.getAccuracy() && Math.abs(newLocation.getAccuracy() - mLastValidLocation.getAccuracy()) > 2.0f; // 只有当位移超过阈值,或者精度明显提升时,才处理这个位置 if (actualDistance > MIN_EFFECTIVE_DISPLACEMENT || accuracyImproved) { mLastValidLocation = newLocation; processLocationUpdate(newLocation); } }
(2)升级依赖库版本
你用的库版本太老旧了,很多已知bug都在新版本里修复了:
- Reactive Location库可以考虑迁移到Jetpack的
Location Runtime配合RxJava自己封装,或者升级到它的最后稳定版本1.0.3; - Google Play Services Location直接升级到
17.0.0+的稳定版本,新版本优化了定位缓存逻辑和位移判断机制,能很大程度减少这类问题。
(3)调整LocationRequest参数
- 降低
FastestInterval的取值,比如从60秒改成10秒,让定位服务更频繁地尝试获取新的位置,减少对缓存的依赖; - 如果业务允许,可以开启
setWaitForAccurateLocation(true)(需要库版本支持),让系统等待高精度定位结果再推送,不过会增加首次定位的延迟,适合对精度要求高的场景。
3. 额外注意点
- 确保已经申请了
ACCESS_FINE_LOCATION权限,低权限下只能获取网络定位,更容易出现重复经纬度的情况; - 车载场景下,可以结合传感器数据(比如加速度传感器)辅助判断设备是否真的在移动,进一步优化过滤逻辑。
内容的提问来源于stack exchange,提问作者Sudhanshu Mishra
相关产品推荐
相关产品推荐

