如何模拟我在物理设备(Nexus One)上的位置?我知道您可以使用“模拟器控制”面板中的模拟器来执行此操作,但这不适用于物理设备。
如何模拟我在物理设备(Nexus One)上的位置?我知道您可以使用“模拟器控制”面板中的模拟器来执行此操作,但这不适用于物理设备。
Answers:
看来唯一的方法是使用模拟位置提供程序。
您必须在设置的开发面板中启用模拟位置,然后添加
<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
我不记得您是否可以远程登录到设备,但我认为可以。我希望这有帮助。
为此,您需要adb(Android调试桥)。
您可以使用位置服务权限来模拟位置...
"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
是LocationManager
连接到的LocationListener
:
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提供商已找到“现在”修复程序,因此可以处理所述事件。
mLocationManager
是一个链接LocationManager
到LocationListener的a ” 是什么意思?我怎样才能做到这一点?谢谢..
LocationManager
服务和a 来检查位置更改LocationListener
:blog.doityourselfandroid.com/2010/12/25/…– Dr1Ku 2015
Dr1Ku发布的内容有效。今天使用了代码,但需要添加更多位置。因此,这里有一些改进:
可选:您可能不想定义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 您还将找到一些实际适用的代码我在模拟器上。
Mock Provider
电源后,普通的GPS将无法工作,我无法获得修复(我是直接在设备上进行测试)。自从Android发生了很多事情以来,情况可能并非如此。
Android电子市场中有可用的应用程序,可让您为设备指定“模拟GPS位置”。
我搜索了https://market.android.com,找到了一个适用于我的名为“我的虚假位置”的应用。
保罗在上面提到的Mock GPS提供程序(位于http://www.cowlumbus.nl/forum/MockGpsProvider.zip)是另一个包含源代码的示例-尽管我无法安装提供的APK(它说失败[INSTALL_FAILED_OLDER_SDK],可能只需要重新编译即可)
为了使用GPS模拟位置,您需要在设备设置中启用它。转到设置->应用程序->开发,然后选中“允许模拟位置”
然后,您可以使用上述应用程序来设置GPS坐标,然后Google地图和其他应用程序将使用您指定的模拟GPS位置。
这对我有用(Android Studio):
禁用手机上的GPS和WiFi跟踪。在Android 5.1.1及更低版本上,在开发人员选项中选择“启用模拟位置”。
在src / debug目录中复制清单。向其中添加以下内容(在“应用程序”标签之外):
使用权限android:name =“ android.permission.ACCESS_MOCK_LOCATION”
设置一个称为“ 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);
}
};
请注意,为了使用“ setElapsedRealtimeNanos”方法,您可能必须暂时将模块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()将使用您点击的坐标触发。
我只是想出了这一点,所以现在我不必手持电话在附近闲逛。
我创建了一个简单的Handler,从初始位置模拟了移动位置。
在连接回调中启动它:
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;
}
}
}
希望能有所帮助。
由icyerasor提及并由Pedro在http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/提供的解决方案 对我来说非常有效。但是,它不提供对正确启动,停止和重新启动模拟GPS提供程序的支持。
我稍微更改了他的代码,并将该类重写为AsyncTask而不是Thread。这使我们能够与UI线程进行通信,因此我们可以在停止该提供程序的那一刻重新启动该提供程序。当屏幕方向改变时,这很方便。
可以在GitHub上找到该代码以及Eclipse的示例项目:https: //github.com/paulhoux/Android-MockProviderGPS
所有功劳应该归功于Pedro所做的大部分努力。
添加到清单
<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);
}
您还需要在设备开发人员设置中启用模拟位置。如果不可用,请在完成上述操作后将“模拟位置应用程序”设置为您的应用程序。
可以在此处找到有关此操作的Google教程,其中提供了代码示例并说明了该过程。
http://developer.android.com/training/location/location-testing.html#SendMockLocations
安装假GPS应用程序 https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=zh-CN
开发人员选项-> 选择模拟位置应用(即选择了假位置应用)。
假GPS应用:
在地图上双击以添加->单击播放按钮->显示吐司“假位置已停止”
最后与谷歌地图应用程序检查。
我编写了一个在Android手机上运行WebServer(类似REST)的应用,因此您可以远程设置GPS位置。该网站提供了一个地图,您可以在其上单击以设置新位置,或使用“ wasd”键向任何方向移动。该应用程序是一个快速的解决方案,因此几乎没有UI或文档,但是实现非常简单,您可以在(只有四个)类中查找所有内容。
如果您的设备已插入计算机,并且您试图通过仿真器控件发送GPS线,则它将无法正常工作。
这是一个EMULATOR控件的原因。
只需进行设置即可更新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();
}
}
}
不要忘记将它们放在清单
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
利用用于Android手机和平板电脑(名为CATLES)的非常方便和免费的交互式位置模拟器。它在整个系统级别(甚至在Google Maps或Facebook应用程序中)模拟GPS位置,并且可以在物理设备和虚拟设备上使用:
在清单文件中使用此权限
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">
android studio建议“仅在测试或调试特定的清单文件(通常为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);
上述解决方案对我不起作用,因为我正在使用最新版本的Google Play服务版本(使用FusedLocationProviderClient)在Android设备上进行测试。在应用清单中设置模拟位置许可并将应用设置为开发人员设置中指定的模拟位置应用之后(如先前的答案中所述),然后我在下面添加了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)