如何设置Android模拟GPS位置?

时间:2016-07-07 17:28:31

标签: java android android-studio gps

描述

我在尝试使用Android模拟位置时遇到问题,我的主要目标是将Android GPS设置为认为我们处于不同的位置,AKA假GPS。

当前尝试次数

我目前尝试过两种不同的类似解决方案,可以在这两个网站上找到:

这两个教程都是从2012年开始的,我不知道它们是否已经过时,或者我很难实现这些教程。

编码开发

首先我确保我有权限:

  1. ACCESS_COARSE_LOCATION
  2. ACCESS_FINE_LOCATION
  3. ACCESS_MOCK_LOCATION *
  4. 注意:同时检查1和2,如果它们不可用,我会使用 requestPermissions 函数请求权限。第三个是不可用的,实际上它只能通过 AndroidManifest.xml 在调试模式下添加。

    我还确保在设置>中选择了我的APP开发人员选项>允许MOCK位置

    毕竟,我已经完成了这个功能,我尝试通过OnCreate方法或OnClick按钮调用:

    public void mockLocation(){
        LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAccuracy( Criteria.ACCURACY_FINE );
        String mocLocationProvider = lm.getBestProvider( criteria, true );
        if ( mocLocationProvider == null ) {
            Toast.makeText(getApplicationContext(), "No location provider found!", Toast.LENGTH_SHORT).show();
            return;
        }
        lm.addTestProvider(mocLocationProvider, false, false,
                false, false, true, true, true, 0, 5);
        lm.setTestProviderEnabled(mocLocationProvider, true);
    
        Location loc = new Location(mocLocationProvider);
        Location mockLocation = new Location(mocLocationProvider); // a string
        mockLocation.setLatitude(-26.902038);  // double
        mockLocation.setLongitude(-48.671337);
        mockLocation.setAltitude(loc.getAltitude());
        mockLocation.setTime(System.currentTimeMillis());
        lm.setTestProviderLocation( mocLocationProvider, mockLocation);
        Toast.makeText(getApplicationContext(), "Working", Toast.LENGTH_SHORT).show();
    }
    

    如果我以这种方式编译和测试,我将收到 Toast:"找不到位置提供商!" 。但是,如果我将mocLocationProvider更改为:

    String mocLocationProvider = LocationManager.NETWORK_PROVIDER;
    

    我遇到了APP崩溃,在LogCat中它表示在此行中崩溃了:

    lm.setTestProviderLocation(mocLocationProvider, mockLocation);
    

    所以我目前没有选择,也不知道如何前进。

3 个答案:

答案 0 :(得分:4)

你必须设置 第一:

  

在设置中允许模拟位置

第二集权限:

  

ACCESS_COARSE_LOCATION       ACCESS_FINE_LOCATION       ACCESS_MOCK_LOCATION

第三种使用这种方法:

setMock(some_lat,some_lon,some accuracy);

private void setMock(double latitude, double longitude, float accuracy) {
 locMgr.addTestProvider (LocationManager.GPS_PROVIDER,
            "requiresNetwork" == "",
            "requiresSatellite" == "",
            "requiresCell" == "",
            "hasMonetaryCost" == "",
            "supportsAltitude" == "",
            "supportsSpeed" == "",
            "supportsBearing" == "",
            android.location.Criteria.POWER_LOW,
            android.location.Criteria.ACCURACY_FINE);

    Location newLocation = new Location(LocationManager.GPS_PROVIDER);

    newLocation.setLatitude(latitude);
    newLocation.setLongitude(longitude);
    newLocation.setAccuracy(accuracy);
    newLocation.setAltitude(0);
    newLocation.setAccuracy(500);
    newLocation.setTime(System.currentTimeMillis());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        newLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }
    locMgr.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);

    locMgr.setTestProviderStatus(LocationManager.GPS_PROVIDER,
            LocationProvider.AVAILABLE,
            null,System.currentTimeMillis());

    locMgr.setTestProviderLocation(LocationManager.GPS_PROVIDER, newLocation);}

答案 1 :(得分:2)

您必须设置准确度和ElapsedRealtimeNanos值

colB.Binding = new Binding("B")

否则会抛出IllegalArgumentException。

  

如果位置不完整,则@throws IllegalArgumentException

<强>更新

如果您模拟网络提供商

location.setAccuracy(...);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}

然后您将通过网络提供商

收到模拟位置
String mocLocationProvider = LocationManager.NETWORK_PROVIDER;

每当你调用setTestProviderLocation方法时,都会触发onLocationChanged回调!

答案 2 :(得分:1)

来自@ Blackkara的回答和评论这是最终的代码: 不要忘记将位置模式设置为仅设备(GPS)

    LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy( Criteria.ACCURACY_FINE );

    String mocLocationProvider = LocationManager.GPS_PROVIDER;//lm.getBestProvider( criteria, true );

    if ( mocLocationProvider == null ) {
        Toast.makeText(getApplicationContext(), "No location provider found!", Toast.LENGTH_SHORT).show();
        return;
    }
    lm.addTestProvider(mocLocationProvider, false, false,
            false, false, true, true, true, 0, 5);
    lm.setTestProviderEnabled(mocLocationProvider, true);

    Location loc = new Location(mocLocationProvider);
    Location mockLocation = new Location(mocLocationProvider); // a string
    mockLocation.setLatitude(-26.902038);  // double
    mockLocation.setLongitude(-48.671337);
    mockLocation.setAltitude(loc.getAltitude());
    mockLocation.setTime(System.currentTimeMillis());
    mockLocation.setAccuracy(1);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }
    lm.setTestProviderLocation( mocLocationProvider, mockLocation);
    Toast.makeText(getApplicationContext(), "Working", Toast.LENGTH_SHORT).show();