如何设置Android Mock GPS位置?

描述

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

目前的尝试

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

  • 编程丛林
  • Mobiarch

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

编码开发

首先,我确保我有权限:

  1. ACCESS_COARSE_LOCATION
  2. ACCESS_FINE_LOCATION
  3. ACCESS_MOCK_LOCATION *

注意 :1和2都被检查,如果它们不可用我请求使用requestPermissions函数的权限。 第三个是不可用的,事实上它只能通过AndroidManifest.xml在调试模式下添加。

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

毕竟,我已经完成了这个function,我尝试通过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); 

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

您必须设置准确度和ElapsedRealtimeNanos值

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

否则会抛出IllegalArgumentException。

@throws IllegalArgumentException如果位置不完整

UPDATE

如果您模拟网络提供商

 String mocLocationProvider = LocationManager.NETWORK_PROVIDER; 

然后你将通过网络提供商收到模拟位置,

 LocationListener listener = new LocationListener(){ ... void onLocationChanged(Location location){ } }; locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, ..., listener); 

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

来自@ 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(); 

你必须先设置:

允许在设置中模拟位置

第二集权限:

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);}