如何在设备上模拟位置?

如何在物理设备(NexusOne)上模拟我的位置?

我知道您可以在模拟器控制面板中使用模拟器进行此操作,但这不适用于物理设备。

259949 次浏览

如果你只在开发实验室使用这款手机,有一个机会,你可以焊接起来的 GPS 芯片和饲料串行端口直接与 NMEA 序列从其他设备。

似乎唯一的方法是使用模拟位置提供程序。

必须在设置的开发面板中启用模拟位置并添加

   <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />

你的货单。

现在可以在代码中创建自己的模拟位置提供程序并设置此提供程序的位置。

您可以使用“位置服务”权限来模拟位置..。

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

我希望我的电缆在手边。我知道你可以远程连接到模拟器来改变它的位置

$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK

我不记得你是否可以远程连接到你的设备,但我认为你可以。我希望这有所帮助。

您将需要 adb (android 调试桥接器)来完成此操作(CLI)。

我已经成功使用了以下代码。尽管出于某种原因,它给了我一个单一的锁(即使我尝试了不同的 LatLng 对) ,它为我工作。mLocationManager是一个连接到 LocationListenerLocationManager:

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

Dr1Ku 发布的代码很有效。今天使用了这个代码,但是需要添加更多的锁。 所以这里有一些改进:

可选项: 不使用 LocationManager.GPS _ PROVIDER String,您可能希望定义自己的 constat PROVIDER _ NAME 并使用它。注册位置更新时,通过条件选择提供程序,而不是直接将其指定为字符串。

首先: 不要调用 RemoveTestProvider,首先检查是否有要删除的提供程序(以避免 IllegalArgumentException) :

if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
mLocationManager.removeTestProvider(PROVIDER_NAME);
}

第二: 要发布多个位置,你必须设置位置的时间:

newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);

似乎还有一个使用 MockLocationProvider 的 google Test: 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》 您还会在模拟器上找到一些实际适用于我的代码。

http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/上佩德罗提供的解决方案对我来说非常有效。但是,它不支持正确启动、停止和重新启动模拟 GPS 提供程序。

我稍微修改了他的代码,并将类重写为 AsyncTask 而不是 Thread。这允许我们与 UI 线程通信,因此我们可以在停止提供程序时重新启动它。这在屏幕方向改变时很方便。

这些代码以及 Eclipse 的一个示例项目可以在 GitHub 上找到: Https://github.com/paulhoux/android-mockprovidergps

所有的功劳都应该归功于佩德罗做了大部分的艰苦工作。

Android 市场上有一些应用程序可以让你为你的设备指定一个“模拟 GPS 位置”。

我搜索了 https://market.android.com,找到了一个名为“我的假地点”的应用程序,它对我很有用。

上面 Paul 提到的 Mock GPS Provider (在 http://www.cowlumbus.nl/forum/MockGpsProvider.zip上)是另一个包含源代码的例子——尽管我无法安装提供的 APK (它说失败[ INSTALL _ FAILED _ OLDER _ SDK ] ,可能只需要重新编译)

为了使用 GPS 模拟位置,您需要在设备设置中启用它。 进入设置-> 应用程序-> 开发和检查“允许模拟位置”

然后你可以使用一个像上面描述的应用程序来设置 GPS 坐标,谷歌地图和其他应用程序将使用你指定的模拟 GPS 位置。

我想知道您是否需要精心设置的模拟位置。在我的例子中,一旦我得到了一个修复位置,我就调用一个函数来处理这个新位置。在计时器中创建一个模拟位置。并使用该位置调用函数。一直以来我们都知道,在短时间内 GPS 就会找到一个真实的当前位置。没关系。如果设置的更新时间足够长。

如果您的设备是插入到您的计算机和您试图改变发送 GPS 线通过模拟器控制,它将无法工作。
这是一个模拟器控件的原因。
设置一下,随时向你汇报 GPS 的变化。

lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);


ll = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
onGPSLocationChanged(location);
}


public void onStatusChanged(String provider, int status, Bundle extras) {
bigInfo.setText("Changed "+ status);
}


public void onProviderEnabled(String provider) {
bigInfo.setText("Enabled "+ provider);
}


public void onProviderDisabled(String provider) {
bigInfo.setText("Disabled "+ provider);
}
};

当 GPS 更新时,重写下面的方法来做你想要它做的事情;

public void onGPSLocationChanged(Location location){
if(location != null){
double pLong = location.getLongitude();
double pLat = location.getLatitude();
textLat.setText(Double.toString(pLat));
textLong.setText(Double.toString(pLong));
if(autoSave){
saveGPS();
}
}
}

别忘了把这些放在旅客名单里
权限.ACCESS _ FINE _ LOCATION
ACCESS _ MOCK _ LOCATION

谷歌上的假 GPS 应用帮了我大忙。只要确保你阅读了应用程序描述中的所有说明。你必须关闭其他定位服务,并启动你的应用程序后,你启用“假 GPS”。对我的需求很有帮助。

下面是 GooglePlay 上这个应用程序的链接: 假 GPS

这对我很有用(Android Studio) :

关闭手机上的 GPS 和 WiFi 跟踪功能。在 Android 5.1.1及以下版本中,在开发者选项中选择“启用模拟位置”。

在 src/debug 目录中复制清单。添加以下内容(在“ application”标记之外) :

Name = “ android.permission. ACCESS _ MOCK _ LOCATION”

设置一个名为“ map”的 map 片段,在 onCreate ()中包含以下代码:

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

注意,为了使用“ setElapseRealtimeNanos”方法,您可能必须暂时将模块 gradle 文件中的“ minSdkVersion”增加到17。

在主活动类中包含以下代码:

private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
// do whatever you want, scroll the map, etc.
}
}

用 AS 运行你的应用程序。在 Android 6.0及以上版本中,你会得到一个安全异常。现在转到“设置”中的“开发人员选项”,并选择“选择模拟位置应用程序”。从列表中选择您的应用程序。

现在,当您点击地图时,onLocationChanged ()将使用您点击的坐标触发。

我刚想明白,这样我就不用拿着电话在附近闲逛了。

在这里可以找到关于这样做的 Google 教程,它提供了代码示例并解释了这个过程。

Http://developer.android.com/training/location/location-testing.html#sendmocklocations : sendMockLocations”rel = “ nofollow”

也许这不是“程序员”的方法,但是如果你想节省你的时间并得到工作解决方案立即尝试其中一个应用程序,这是专门用于模拟位置可在 Google Play:

伪造 GPS 位置欺骗程序

模拟地点

伪造的 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) {


}
};

Handler 类:

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

希望能帮上忙。

安装 假的 GPS 应用 Https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en

开发者选项-> 选择模拟位置应用程序(意思是,选择了假定位应用程序)。

假 GPS 应用程序 :

双标签在地图上添加-> 点击播放按钮-> 显示吐司“假位置停止”

最后检查谷歌地图应用程序。

我写了一个应用程序,运行一个 WebServer (REST-Like)在您的 Android 手机,所以你可以 远程设置 GPS 定位。该网站提供了一个地图,您可以点击设置一个新的位置,或使用“ wasd”键向任何方向移动。这个应用程序是一个快速的解决方案,所以几乎没有 UI 和文档,但是实现是直接的,你可以在(只有四个)类中查找一切。

项目存储库: https://github.com/juliusmh/RemoteGeoFix

在清单文件中使用此权限

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">

Android 工作室将建议“ Mock 位置应该只在测试或调试特定的清单文件(通常是 src/debug/AndroidManifest.xml)中请求” 只是 禁止检查

现在,请确保您已经检查了“ 允许模拟位置”在开发商设置您的手机

使用 LocationManager

locationManager.addTestProvider(mocLocationProvider, false, false,
false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);

现在把位置设置到你想要的任何地方

Location mockLocation = new Location(mocLocationProvider);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lng);
mockLocation.setAltitude(alt);
mockLocation.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation);

使用非常方便和免费的 Android 手机和平板电脑交互式位置模拟器(称为 CATLES)。它在整个系统层面上(甚至在谷歌地图或 Facebook 应用程序中)模拟 GPS 定位,它在物理设备和虚拟设备上都可以工作:

网址: http://ubicom.snet.tu-berlin.de/catles/index.html

视频: https://www.youtube.com/watch?v=0WSwH5gK7yg

添加到您的清单

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

您还需要在设备开发人员设置中启用模拟位置。如果这不可用,那么在实现上述功能之后,将“模拟位置应用程序”设置为您的应用程序。

上面的解决方案对我不起作用,因为我正在一个 Android 设备上测试最新的 Google Play Services 版本,它利用了 FusedLocationProviderClient。在应用程序清单中设置了模拟位置权限,在开发者设置中将应用程序设置为指定的模拟位置应用程序(如前面的答案所述) ,然后我添加了 Kotlin 代码,成功地模拟了位置。

locationProvider = FusedLocationProviderClient(context)
locationProvider.setMockMode(true)


val loc = Location(providerName)
val mockLocation = Location(providerName) // a string
mockLocation.latitude = latitude  // double
mockLocation.longitude = longitude
mockLocation.altitude = loc.altitude
mockLocation.time = System.currentTimeMillis()
mockLocation.accuracy = 1f
mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mockLocation.bearingAccuracyDegrees = 0.1f
mockLocation.verticalAccuracyMeters = 0.1f
mockLocation.speedAccuracyMetersPerSecond = 0.01f
}
//        locationManager.setTestProviderLocation(providerName, mockLocation)
locationProvider.setMockLocation(mockLocation)