【问题标题】:FusedLocationProviderClient getLastLocation elapsedRealtimeNanos mostly current system timeFusedLocationProviderClient getLastLocation elapsedRealtimeNanos 主要是当前系统时间
【发布时间】:2018-08-08 14:57:00
【问题描述】:

更新 2

我在 Google I/O '18 上与一位 Google 工程师进行了交谈。他告诉我,我可以信任 fusedLocationProvider。如果他用新的时间戳标记最后一个已知位置,则用户可能仍在同一位置。

我想在未来用“移动”设备做一些测试来证明这个说法。


原始问题

我正在向FusedLocationProviderClientgetLastLocation() 请求最后一个已知位置,并想检查最后一个已知位置是否早于 5 分钟以开始新的位置请求。

在我的测试中,我发现elapsedRealtimeNanos 的位置有一个奇怪的行为,应该用于compare

出于测试目的,我在一个简单的 Java 线程中每秒请求最后一个已知位置。收到位置后,我检查 elapsedRealtimeNanos 并将它们与SystemClock.elapsedRealtimeNanos() 进行比较。在大多数情况下,最后一个已知位置的年龄也设置为SystemClock.elapsedRealtimeNanos(),因此差值几乎为 0。这意味着,FusedLocationProvider 告诉我最后一个已知位置的修复是现在,这会进行年龄检查不可靠。

这种行为已经够奇怪了,但越来越严重。

当我在测试期间启动并行位置请求或启动 Google 地图时,最后一个已知位置的 elapsedRealtimeNanos 将停止增长,并且仅在找到“真实”新位置时更新到较新的时间。这应该是我所期望的默认行为。

我在 HIGH_ACCURACY 和 SENSORS_ONLY 等不同的位置设置中观察到了这种行为。

这是否意味着不可能检查最后一个已知位置的年龄?谁能解释一下这种行为?

更新 1

location.getTime() 的行为相同

代码片段:

 @Override void getLastKnownLocation() {
    try {
        mLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
            @Override
            public void onComplete(@NonNull Task<Location> task) {
                try {
                    Location location = task.getResult();
                    if (location != null) {
                        location.getElapsedRealtimeNanos()
                        //Compare to SystemClock.elapsedRealtimeNanos();
            ...

而且(我知道它很乱)

      new Thread(){
        @Override public void run() {
            locationFinder.getLastKnownLocation();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            run();
        }
    }.start();

位置更新请求

public PlayServicesLocationFinder(Context context){
    mLocationClient = LocationServices.getFusedLocationProviderClient(context);
}

@Override
public void getLocationUpdates() {

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(60000); 
    locationRequest.setFastestInterval(15000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationClient.requestLocationUpdates(locationRequest, continuousUpdatesLocationListener, null);
}

【问题讨论】:

  • getTime() 的情况是否相同?
  • @TpoM6oH 不幸的是,我更新了我的问题。
  • 你如何开始你的服务?
  • @TpoM6oH PlayServicesLocationFinder 在我的应用程序的应用程序类中有一个静态属性,以启动我调用getLocationUpdates 的位置更新(请参阅更新问题)

标签: android location google-play-services android-fusedlocation fusedlocationproviderclient


【解决方案1】:

也许我可以建议您尝试其他方式来获得“新鲜”坐标,这似乎是您的代码的主要目标。 也许你可以试试:

  • 首先获取LastKnownLocation
  • 拥有 LastKnownLocation 后。您可以开始 requestLocationUpdates() 并且一旦您有了一个与 lastKnownLocation 不同的新坐标,那么该坐标就是您的“新”坐标。您甚至可以实施精度控制以获得“更准确、更新鲜”的坐标。

我使用了之前的方案,它非常适合在不验证位置 GPS 时间 (getTime()) 的情况下获取当前位置。

注意:我知道这对电池不友好,但您可以在 LocationRequest 中控制更新次数、间隔时间、最长等待时间,以将电池消耗保持在最低限度。

【讨论】:

    【解决方案2】:

    有一种方法可以解决此要求。 您将使用 updatedLocation 计算已保存位置,是否存储新位置。 有两个属性可以帮助您进行此计算。

    • 两个位置之间的距离。
    • 获取位置的时间。 (您的要求)

    首先,您必须使用

    存储位置返回
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                        mGoogleApiClient);
    

    然后将其与下一个获取的位置进行比较(这两个属性都会为您提供更好的跟踪以管理设备位置更新), 然后决定是否应该将新获取的位置替换为存储位置。 为此你已经编写了你的​​逻辑,我想我可以分享一些可以帮助你的代码。

    private boolean isTimeToUpdateLocation(Location newlocation) {
        int LOCATION_ALERT_FREQUENCY = 60000; //1 * 60000; // 1 minute
        long timeDelta = System.currentTimeMillis() - newlocation.getTime();
        return (timeDelta >= LOCATION_ALERT_FREQUENCY);
    }
    

    关于距离的位置更新有一小段代码

    int LOCATION_DEVIATION = 1000; // 1 KM
    
    public boolean shouldUpdateNewLocation(Location location) {
    
        Location prevLocation = getLastStoredLocation();
    
        boolean shouldUpdateToServer = false;
    
        if (prevLocation != null) {
            if (prevLocation.distanceTo(location) > LOCATION_DEVIATION)
                shouldUpdateToServer = true;
        }
    
        return shouldUpdateToServer;
    }
    

    希望您现在可以解决您面临的问题。

    【讨论】:

    • 谢谢,不幸的是这不能解决我的问题,因为 getLastLocation().getTime() 主要是系统时间,这是我在问题中描述的问题,我想比较另一个 getLastLocation()称呼。但是这个调用给了我另一个当前系统时间的位置,比较两者只告诉我 getLastLocation() 调用之间的时间
    • another getLastLocation() 你是否调用相同的方法来获取另一个位置,我认为如果是这种情况,它会以相同的位置响应。
    • 这也是我所期望的,但就时间戳集而言,我得到了一个“新”位置,坐标可能是相同的。
    猜你喜欢
    • 2018-12-24
    • 2011-07-02
    • 1970-01-01
    • 2017-08-03
    • 2016-12-04
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多