Android LocationClient.getLastLocation() 返回带有新时间戳的旧且不准确的位置

Posted

技术标签:

【中文标题】Android LocationClient.getLastLocation() 返回带有新时间戳的旧且不准确的位置【英文标题】:Android LocationClient.getLastLocation() returns old and inaccurate location with a new timestamp 【发布时间】:2013-07-10 07:46:36 【问题描述】:

自从融合位置提供程序发布以来,我一直在使用它,我对它非常满意(比旧系统好得多)。但是在将地理围栏与 LocationClient.lastKnownLocation() 结合使用时,我遇到了一个特殊的问题。设置如下:

我在一些家庭位置周围放置了几个地理围栏(范围越来越大)。当我得到跨越栅栏的意图时,我从 LocationClient 检索最后一个已知位置并使用它。除此之外,我还使用更新模式 PRIORITY_BALANCED_POWER_ACCURACY 注册了定期位置更新。

在大多数情况下这工作得很好,但有时会发生这种情况:

时间 000 s - (Lat,Lon,Accuracy) = (48.127316,11.5855167,683.0)

时间 120 s - (Lat,Lon,Accuracy) = (48.1260497,11.5731745,31.823)

时间 300 s - (Lat,Lon,Accuracy) = (48.1217455,11.5641666,143.81)

时间 420 s - (Lat,Lon,Accuracy) = (48.1189942,11.559061,36.0)

时间 600s - (Lat,Lon,Accuracy) = (48.127316,11.5855167,683.0)

请注意,所有这些位置都由getLastKnownLocation() 检索。这里看起来可疑的是第一个和最后一个位置是相同的(即使在其他属性中),更具体地说:

* intent at time 0: *

component: ComponentInfopackage.Class
key [location]: Location[mProvider=fused,mTime=1373524391934,mLatitude=48.127316,mLongitude=11.5855167,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=683.0,mExtras=Bundle[mParcelledData.dataSize=352]]

* intent at time 600: *

component: ComponentInfopackage.Class
key [location]: Location[mProvider=fused,mTime=1373524994871,mLatitude=48.127316,mLongitude=11.5855167,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=683.0,mExtras=Bundle[mParcelledData.dataSize=352]]

* note the ~600 s difference in the timestamp * 

我不明白这是怎么发生的,因为在这两者之间有一些位置更新且更准确。旧位置上的新时间戳也让我很好奇......使用old API时显然发生了类似的事情,但这个新的位置提供者只是称为fused,所以我无法将GPS与WPS与传感器区分开来。 .. 如果是手机信号塔切换问题(在有关旧 API 的链接问题中有概述),那么如果手机看到更近的信号塔,为什么还要连接到“远处”信号塔?

为什么会这样?

【问题讨论】:

【参考方案1】:

第一个和最后一个点是使用单元三角剖分获得的。错误/准确性是典型的基于单元格的位置,看起来 Google 省电逻辑决定切换到单元格是可以的,即使您说它最近的历史记录包含更接近的点。

【讨论】:

这可能是对的......但对于用户我想过滤这些虚假修复(我在上周观察到更多极端的例子)。但我看不到一种方法来识别“旧”的修复,除了将旧位置保​​存在内存中并手动检查它们,我不想这样做..【参考方案2】:

哎呀,糟了!我今天也得到了这个……我搬到新的 Google Play 服务位置正是为了避免这种情况……直到现在我也得到它时,我一直很激动。您可能知道也可能不知道旧版本有这些问题,这很痛苦。

有很多关于这个的线程,包括我自己的一个:(

Why is locationmanager returning old location fixes with new gettime-timestamp?

我想唯一要做的就是避免使用缓存位置...

【讨论】:

我在使用位置之前添加了几个过滤器和健全性检查,这极大地提高了我的应用程序的性能。我遇到的最多的是 API 会给我旧的手机信号塔位置(精度 > 500),这会扰乱我的跟踪。为了避免这种情况,我开始对蜂窝塔位置进行聚类并过滤位于这些集群中的新蜂窝塔(用于创建集群的位置会定期删除)。也许这有帮助 哇,所以你在手机信号塔ID上保存了一个数据库?对于真正应该工作的东西来说,这是一个很多的麻烦...... :( 我不使用数据库,因为移动上下文非常短暂,超过 1 小时的位置会被遗忘。但你是对的,如果它像我希望的那样工作,我会更开心 我最终做的只是从不询问最后缓存的位置。我们的应用程序总是只想要一个真正新鲜的位置,但由于那个位置似乎不稳定,我们总是启动并连接客户端并开始主动轮询,直到我们有一个,然后再次关闭。到目前为止,我们只在通过 latestknownlocation 询问时看到了那些陈旧的位置。用户体验会受到影响,但是该怎么办......【参考方案3】:

可以使用这种订阅机制来解决一个或多个不准确的来源,而不是轮询。

LocationListener locListener = new LocationListener() 
    @Override
    public void onLocationChanged(Location location) 
        if (location == null)
            return;
        // process these:
        // location.getLatitude();
        // location.getLongitude();
        // location.getAccuracy();
        ...
    
    ... 


((LocationManager) getSystemService(Context.LOCATION_SERVICE)
        .requestLocationUpdates(LocationManager.GPS_PROVIDER,
                minTimeMilliSec,
                minDistanceMeters,
                locListener));

【讨论】:

以上是关于Android LocationClient.getLastLocation() 返回带有新时间戳的旧且不准确的位置的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)

【Android笔记】android Toast

图解Android - Android核心机制

Android游戏开发大全的目录