【问题标题】:Android - Reliably getting the current locationAndroid - 可靠地获取当前位置
【发布时间】:2010-06-25 17:57:03
【问题描述】:

我的应用会在特定时间检查用户是否在给定位置。我使用警报管理器来启动进行此调用的服务:

locationManager.requestLocationUpdates(bestProvider, 0, 0, listener);

并且还检查:

 locationManager.getLastKnownLocation(bestProvider);

但我在真实设备上运行时遇到问题。一方面,getLastKnownLocation 很可能是 GPS 的最后一个位置,它可能在任何地方(即,它可能距离用户当前位置数英里)。所以我会等待requestLocationUpdates 回调,如果他们在两分钟内不存在,请移除侦听器并放弃,对吗?

错了,因为如果用户的位置已经稳定(即他们最近使用了 GPS 并且没有移动),那么我的监听器将永远不会被调用,因为位置不会改变。但是 GPS 会一直运行,直到我的监听器被移除,耗尽电池...

在不将旧位置误认为当前位置的情况下,获取当前位置的正确方法是什么?我不介意等几分钟。

编辑:我可能错了没有调用听众,这可能比我想象的要长一点......很难说。我仍然希望得到一个明确的答案。

【问题讨论】:

    标签: android geolocation gps


    【解决方案1】:

    代码可能是这样的:

    public class MyLocation {
        Timer timer1;
        LocationManager lm;
    
        public boolean getLocation(Context context)
        {
            lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
            timer1=new Timer();
            timer1.schedule(new GetLastLocation(), 20000);
            return true;
        }
    
        LocationListener locationListenerGps = new LocationListener() {
            public void onLocationChanged(Location location) {
                timer1.cancel();
                lm.removeUpdates(this);
                //use location as it is the latest value
            }
            public void onProviderDisabled(String provider) {}
            public void onProviderEnabled(String provider) {}
            public void onStatusChanged(String provider, int status, Bundle extras) {}
        };
    
        class GetLastLocation extends TimerTask {
            @Override
            public void run() {
                 lm.removeUpdates(locationListenerGps);
                 Location location=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                 //use location as we have not received the new value from listener
            }
        }
    }
    

    我们启动监听器并等待更新一段时间(在我的示例中为 20 秒)。如果我们在此期间收到更新,我们会使用它。如果在此期间我们没有收到更新,我们会使用 getLastKnownLocation 值并停止监听器。

    你可以在这里看到我的完整代码What is the simplest and most robust way to get the user's current location on Android?

    编辑(由提问者):这是大部分答案,但我的最终解决方案使用 Handler 而不是计时器。

    【讨论】:

    • 你能提供一些示例代码吗?例如,如果不调用位置侦听器,您将如何等待 2 分钟或类似的时间?
    【解决方案2】:

    如果用户的位置已经稳定,那么getLastKnownLocation会返回当前位置。我会先打电话给getLastKnownLocation,查看时间戳(比较Location.getElapsedRealTimeNanos()SystemClock.elapsedRealTimeNanos()),如果修复太旧,请注册一个监听器。

    【讨论】:

    • 谢谢,我不知道 getTime()。问题是,位置提供者认为它太旧之前的时间必须是多少?如果我不使用该位置,如何保证我的听众会被调用?
    • 位置提供者不认为它太旧,它从不丢弃它(据我所知)。您必须决定何时认为修复程序太旧并在必要时请求更新。如果在给定时间内没有更新,您仍然可以使用旧位置。
    • 这里有个小问题:API没有定义Location.getTime()返回的时间戳的来源。对于 GPS,它似乎是卫星时间。对于网络提供商来说,它似乎是本地设备时间。这使得可靠地确定位置的年龄变得有些困难 - 考虑到用户时钟可能不准确或时区配置错误的可能性。
    • 您可以使用 location.getElapsedRealTimeNanos() 而不是 location.getTime(),然后将其与 SystemClock.elapsedRealTimeNanos 进行比较,以获得更准确的位置修复时间。
    • 是的,但请记住,location.getElapsedRealTimeNanos() 仅在 API 级别 17 中添加。
    猜你喜欢
    • 2011-07-15
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2018-12-21
    • 2012-01-22
    • 2016-07-30
    相关资源
    最近更新 更多