【问题标题】:Mocking Android's LocationProvider模拟 Android 的 LocationProvider
【发布时间】:2013-03-14 15:03:37
【问题描述】:

目前我正在通过模拟文件中的一些 GPS 数据来测试我的 android 应用程序的 LocationProvider,以便临时模拟真实设备上的运动。另外,我想即时从我的模拟数据切换到真实数据。以下代码适用于模拟从文件读取的 GPS 数据。但是,当我尝试停止模拟 GPS 数据时,我的当前位置卡在文件中最后读取的 GPS 信号上。

因为我不想更改实际 Android 应用程序的代码,所以我将模拟数据写入与名称 GPS_Provider 关联的 LocationProvider 中。基于位置的应用程序可以通过简单地调用 `requestLocationUpdates(LocationManager.GPS_Provider, , ) 来读取模拟数据。棘手的部分是重置 GPS LocationProvider 以便再次提供真实数据。在这里我卡住了,不知道如何重新设置。

    private AssetManager assetManager;
    private LocationManager locationManager;

    private String locationProviderName = LocationManager.GPS_Provider;

    private List<Location> allMockedPositions;

    private Handler handler;
    private int position;

    private Runnable runner = new Runnable() {

        @Override
        public void run() {
            if (position <= allMockedPositions.size()) {    
                Location mockedLocation = allMockedPositions.get(position++);
                locationManager.setTestProviderLocation(locationProviderName, mockedLocation);
                handler.postDelayed(runner, 500);
            }
        }
    };

    public MockLocationProvider(Context context) {
        assetManager = context.getAssets();
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    }

    public void startMockingLocation(Route route) {
        allMockedPositions = LocationData.getRouteData(assetManager, route, locationProviderName);
        startMocking();
    }

    private void startMocking() {       
        position = 0;
        handler = new Handler();
        handler.post(runner);
    }

    public void stopMockingLocation() {
        locationManager.clearTestProviderLocation(locationProviderName);
        stopMocking();
    }

    private void stopMocking() {
        handler.removeCallbacks(runner);
    }

【问题讨论】:

  • 你是在模拟器上做的吧?不在真手机上?

标签: android testing gps mocking


【解决方案1】:

您需要实现LocationManagerLocationListener 来获取手机的当前位置,然后在stopMockingLocation 方法中使用该位置。您的代码中已经有一个LocationManager,但作为参考,可以在herehere 找到有关如何设置此回调系统的文档。

基本上您将配置您的LocationManager 以从无线NETWORK_PROVIDERGPS_PROVDER 获取更新。如果在您的指定参数内有注册更改(您可以设置注册更改的时间和距离范围),这会将新的位置信息提供给LocationListener

最后,在您的LocationListener 中,您将看到onLocationChanged 的方法

private final LocationListener listener = new LocationListener() {      
    @Override     
    public void onLocationChanged(Location location) {         
    // A new location update is received.  Do something useful with it.           
    }     
};  

这是当手机的位置在您定义的时间和距离参数内发生变化时调用的。如果您只想在停止模拟后获取用户的位置,您可以简单地创建一个实例变量,从 onLocationChanged 方法中将用户位置存储到该变量中,然后从您的 stopMockingLocation 中访问该位置方法。或者,您可以从 onLocationChanged 中调用其他方法,但我无法提出建议,因为我不确定您到底要做什么。

【讨论】:

  • 我只是想编写一个应用程序,允许我开始和停止模拟 GPS 数据并在真实和模拟 GPS 数据之间切换
  • 我明白了 - 我的意思是您需要收集 GPS 数据,以便在停止模拟后可以使用它。如果您使用 locationlistener 来获取 GPS 数据,那么每当您停止模拟位置时,您都可以简单地使用 GPS 位置。没有其他方法可以使用 locationlistener/locationmanager 获取 GPS 位置 excpet
  • 在开始模拟 GPS 数据之前,我还可以使用 LocationManager 的 getLastKnownPosition ,但这不是重点。因为我在与字符串 GPS_Provider 关联的 LocationProvider 中编写了我的模拟 GPS,所以在完成模拟后我不能以常规方式使用它。每次我使用 requestLocationUpdates(...) 访问已清除的 LocationProvider 时,我都会收到最后一个模拟位置。完成模拟 GPS 数据后,我可以添加 lastKnownPosition 以从 LocationProvider 接收它,但这不允许我在模拟后跟踪实际运动。
  • 嗯。你可以使用一个单独的类吗?一个只记录这个模拟位置类之外的位置,然后以这种方式检索位置?我知道困难在于提供商内部的嘲笑。想办法解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
相关资源
最近更新 更多