如何设置Android Mock GPS位置?
描述
我在尝试使用android模拟位置时遇到了问题,我的主要目标是将android GPS设置为认为我们处于不同的位置,AKA假GPS。
目前的尝试
我目前尝试了两种不同的类似解决方案,可以在这两个网站上找到:
- 编程丛林
- Mobiarch
这两个教程都是从2012年开始的,我不知道它们是否已经过时,或者我很难实现它们。
编码开发
首先,我确保我有权限:
- ACCESS_COARSE_LOCATION
- ACCESS_FINE_LOCATION
- 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);}