如何在 Android 上强制更新位置

How to force a location update on Android

是否有替代此调用的方法强制从硬件获取新坐标?

locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

我遇到的具体问题是他们使用假 GPS 来模拟位置。他们在启动我的应用程序之前将其关闭,但是当我的应用程序启动并进行上述调用时,它仍然获得最后给定的模拟位置。

注意:我们已将其作为模拟 GPS 提供程序从开发人员选项中删除,并强制退出。我们甚至卸载了它。所以我确定 Android 本身仍在缓存先前的模拟值并将其提供给我的应用程序,因为 phone 没有移动。

此外,由于开发人员选项中没有模拟提供程序,Android LocationManager 将缓存的虚假位置报告为未模拟。明显是个大bug。

我想做的是调用强制 phone 打开 GPS 并获取新坐标。不幸的是,我看不到任何方法...

最简单的解决方案是从 Android 的 gps 工具中抽象出来。 只需将所有与 gps 相关的功能提取到单独的接口中,并在不使用任何 Android 相关服务的情况下实现它以进行测试。通过这样做,您甚至不需要模拟您的位置(假设您的最终 Android 实现将正常工作)。您可以以任何方式模拟此测试实现,例如,打开 Json 文件,其中包含来自资产的位置,并定期将其提供给您的界面。请参阅这篇文章:http://martinfowler.com/articles/dipInTheWild.html

简而言之,您必须为上述提供商提出位置请求。供应商需要一个新的位置。

长答案是;

The specific problem I'm having is they are using Fake GPS to mock a location. They turn it off before launching my app, but when my app launches and makes the above call it's still getting the last-given mock location.

在正常情况下 getLastKnownLocation 方法 returns 给定提供程序的缓存位置。因此,在您的情况下,预计会获得模拟位置,因为您的设备尚未收到新位置

Note: We've removed it from the Developer Options as the mock gps provider and done a force quit on it. We even uninstalled it. So I'm certain that Android itself is still caching the prior mock value and just feeding that to my app because the phone hasn't moved.

没错,因为 mocker 应用程序先前设置的位置已针对给定提供程序进行缓存。它会影响整个系统。这也是卸载mocker app后没有清除的原因。您必须向提供商发出位置请求或重新启动您的设备。

In addition, because there's no mock provider in Developer Options, Android LocationManager is reporting the cached fake location as NOT mocked. Clearly a huge bug.

你是怎么测试的?当您测试时,所有设备的行为都像这样吗?也许 mocker 应用程序是作为系统应用程序安装的,所以它会向 LocationManager 报告位置并伪装你?


要强制 GPS 获取位置,您可以轻松使用以下代码。 onLocationChanged 方法将由 GPS 硬件触发。

但请确保模拟位置应用此时无法运行。否则,onLocationChanged 方法将被 mocker app 触发!

private void requestLocation(){
    locationManager.requestLocationUpdates(
    LocationManager.GPS_PROVIDER, 0, 0, mListener);
}

private LocationListener mListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        // Previously mock location is cleared.
        // getLastKnownLocation(LocationManager.GPS_PROVIDER); will not return mock location. 
    }

    ...
};

这是 Marshmallow 报告的一个问题。 https://code.google.com/p/android/issues/detail?id=227873