如何在物理设备(Nexus One)上模拟我的位置?
我知道你可以在模拟器控制面板中使用此功能,但对于物理设备而言,这并不起作用。
如何在物理设备(Nexus One)上模拟我的位置?
我知道你可以在模拟器控制面板中使用此功能,但对于物理设备而言,这并不起作用。
似乎唯一的方法是使用模拟位置提供程序。
您需要在设置中启用模拟位置,并添加
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
将其添加到您的清单文件中。
现在您可以在代码中创建自己的模拟位置提供程序并设置该提供程序的位置。
如果您只在开发实验室中使用此手机,则有可能将GPS芯片焊接下来,并直接使用来自其他设备的NMEA序列进行串口馈送。
我希望我有我的电缆方便。我知道你可以telnet到模拟器来改变它的位置。
$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK
我记不清您是否可以 telnet 到您的设备,但我认为您可以。希望这有所帮助。
您需要使用 adb(Android 调试桥)进行此操作(CLI)。
你可以使用位置服务权限来模拟位置...
"android.permission.ACCESS_MOCK_LOCATION"
然后在你的java代码中,
// Set location by setting the latitude, longitude and may be the altitude...
String[] MockLoc = str.split(",");
Location location = new Location(mocLocationProvider);
Double lat = Double.valueOf(MockLoc[0]);
location.setLatitude(lat);
Double longi = Double.valueOf(MockLoc[1]);
location.setLongitude(longi);
Double alti = Double.valueOf(MockLoc[2]);
location.setAltitude(alti);
使用以下代码我已经取得了成功。尽管由于某些原因(即使我尝试了不同的LatLng对),它为我工作。 mLocationManager
是一个连接到 LocationListener
的 LocationManager
:
private void getMockLocation()
{
mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
mLocationManager.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 (/* TODO: Set Some Lat */);
newLocation.setLongitude(/* TODO: Set Some Lng */);
newLocation.setAccuracy(500);
mLocationManager.setTestProviderEnabled
(
LocationManager.GPS_PROVIDER,
true
);
mLocationManager.setTestProviderStatus
(
LocationManager.GPS_PROVIDER,
LocationProvider.AVAILABLE,
null,
System.currentTimeMillis()
);
mLocationManager.setTestProviderLocation
(
LocationManager.GPS_PROVIDER,
newLocation
);
}
setTestProviderStatus
用于通知/发布/调度一个事件给 LocationManager,以便 GPS 提供程序已经找到了一个修复“现在”,从而可以处理该事件。 - Dr1KumLocationManager
是一个连接到LocationListener
的LocationManager
"这句话的意思是什么?我该怎么做呢?谢谢。 - YehudaLocationManager
服务和LocationListener
检查位置更改:http://blog.doityourselfandroid.com/2010/12/25/understanding-locationlistener-android/ - Dr1KuDr1Ku发布的内容有效。今天我使用了这段代码,但需要添加更多 locs(位置)。
改进:
可选:不要使用LocationManager.GPS_PROVIDER字符串,而是定义自己的常量 PROVIDER_NAME 并使用它。在注册位置更新时,通过标准选择提供程序,而不是直接将其作为字符串指定。
首先:不要调用removeTestProvider,而是先检查是否有要删除的提供程序(以避免IllegalArgumentException异常):
if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}
其次:要发布多个位置,您必须为每个位置设置时间:
newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);
还有一个使用MockLocationProviders的Google测试:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java
另一个好的可工作示例可以在这里找到:http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/
另一篇好文章:http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358。你也可以在模拟器上找到一些对我实际有效的代码。
Android市场上有一些应用程序可以为您的设备指定“模拟GPS位置”。
我在https://market.android.com上搜索到一个名为“我的虚假位置”的应用程序适合我使用。
Paul提到的Mock GPS Provider(位于http://www.cowlumbus.nl/forum/MockGpsProvider.zip)是另一个包含源代码的示例,尽管我无法安装提供的APK(它说Failure [INSTALL_FAILED_OLDER_SDK],可能只需要重新编译)。
为了使用GPS模拟位置,您需要在设备设置中启用它。前往“设置” -> “应用程序” -> “开发”并选中“允许模拟位置”。
然后,您可以使用上述描述的应用程序之一来设置GPS坐标,Google地图和其他应用程序将使用您指定的模拟GPS位置。
private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
if (BuildConfig.USE_MOCK_LOCATION) {
LocationServices.FusedLocationApi.setMockMode(mGoogleApiClient, true);
new MockLocationMovingHandler(mGoogleApiClient).start(48.873399, 2.342911);
}
}
@Override
public void onConnectionSuspended(int i) {
}
};
The Handler class :
private static class MockLocationMovingHandler extends Handler {
private final static int SET_MOCK_LOCATION = 0x000001;
private final static double STEP_LATITUDE = -0.00005;
private final static double STEP_LONGITUDE = 0.00002;
private final static long FREQUENCY_MS = 1000;
private GoogleApiClient mGoogleApiClient;
private double mLatitude;
private double mLongitude;
public MockLocationMovingHandler(final GoogleApiClient googleApiClient) {
super(Looper.getMainLooper());
mGoogleApiClient = googleApiClient;
}
public void start(final double initLatitude, final double initLongitude) {
if (hasMessages(SET_MOCK_LOCATION)) {
removeMessages(SET_MOCK_LOCATION);
}
mLatitude = initLatitude;
mLongitude = initLongitude;
sendEmptyMessage(SET_MOCK_LOCATION);
}
public void stop() {
if (hasMessages(SET_MOCK_LOCATION)) {
removeMessages(SET_MOCK_LOCATION);
}
}
@Override
public void handleMessage(Message message) {
switch (message.what) {
case SET_MOCK_LOCATION:
Location location = new Location("network");
location.setLatitude(mLatitude);
location.setLongitude(mLongitude);
location.setTime(System.currentTimeMillis());
location.setAccuracy(3.0f);
location.setElapsedRealtimeNanos(System.nanoTime());
LocationServices.FusedLocationApi.setMockLocation(mGoogleApiClient, location);
mLatitude += STEP_LATITUDE;
mLongitude += STEP_LONGITUDE;
sendEmptyMessageDelayed(SET_MOCK_LOCATION, FREQUENCY_MS);
break;
}
}
}
希望这能有所帮助...
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new MyLocationListener();
if (lm.getProvider("Test") == null) {
lm.addTestProvider("Test", false, false, false, false, false, false, false, 0, 1);
}
lm.setTestProviderEnabled("Test", true);
lm.requestLocationUpdates("Test", 0, 0, ll);
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng l) {
Location loc = new Location("Test");
loc.setLatitude(l.latitude);
loc.setLongitude(l.longitude);
loc.setAltitude(0);
loc.setAccuracy(10f);
loc.setElapsedRealtimeNanos(System.nanoTime());
loc.setTime(System.currentTimeMillis());
lm.setTestProviderLocation("Test", loc);
}
};
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}
使用AS运行您的应用程序。在安卓6.0及以上版本中,会出现安全异常。现在进入设置中的开发人员选项,并选择“选择虚拟位置应用程序”。从列表中选择您的应用程序。
现在当您在地图上点击时,onLocationChanged() 将携带您点击位置的坐标。
我刚刚弄清楚了这个问题,所以现在我不必手持手机在附近走来走去了。
添加到您的清单中
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation,ProtectedPermissions" />
void setMockLocation() {
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
mockLocation.setLatitude(-33.852); // Sydney
mockLocation.setLongitude(151.211);
mockLocation.setAltitude(10);
mockLocation.setAccuracy(5);
mockLocation.setTime(System.currentTimeMillis());
mockLocation.setElapsedRealtimeNanos(System.nanoTime());
locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mockLocation);
}
您还需要在设备的开发者设置中启用模拟位置。如果没有此选项,请在上述步骤完成后将“模拟位置应用程序”设置为您的应用程序。