设备上的Android模拟位置?

时间:2010-03-27 23:23:26

标签: android gps location mocking

如何在物理设备(Nexus One)上模拟我的位置?我知道您可以使用“仿真器控制”面板中的仿真器执行此操作,但这不适用于物理设备。

21 个答案:

答案 0 :(得分:159)

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

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

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

到您的清单。

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

答案 1 :(得分:100)

如果您仅在开发实验室中使用此手机,您可以直接使用其他设备的NMEA序列焊接GPS芯片和馈送串口。

答案 2 :(得分:32)

我希望我的电缆方便。我知道你可以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)。

答案 3 :(得分:28)

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

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

答案 4 :(得分:24)

我使用以下代码取得了成功。虽然它出于某种原因让我一把锁(即使我尝试过不同的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
    );      
}

答案 5 :(得分:14)

Dr1Ku发布了什么作品。今天使用了代码,但需要添加更多的loc。 所以这里有一些改进:

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

首先:不要调用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 您还可以在模拟器上找到一些实际适合我的代码。

答案 6 :(得分:9)

Android电子市场中有一些应用程序允许您为设备指定“模拟GPS位置”。

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

保罗上面提到的模拟GPS提供商(http://www.cowlumbus.nl/forum/MockGpsProvider.zip)是包含源代码的另一个例子 - 虽然我无法安装提供的APK(它说失败[INSTALL_FAILED_OLDER_SDK]并且可能只需要重新编译)

要使用GPS模拟位置,您需要在设备设置中启用它。 转到设置 - &gt;应用程序 - &gt;开发并检查“允许模拟位置”

然后,您可以使用上述应用程序来设置GPS坐标,Google地图和其他应用程序将使用您指定的模拟GPS位置。

答案 7 :(得分:8)

这对我有用(Android Studio):

禁用手机上的GPS和WiFi跟踪功能。在Android 5.1.1及更低版本中,选择“开发人员选项”中的“启用模拟位置”。

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

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

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

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

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

使用AS运行您的应用。在Android 6.0及更高版本上,您将获得安全性异常。现在转到设置中的开发者选项,然后选择“选择模拟位置应用”。从列表中选择您的应用程序。

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

我刚才想到了这一点,所以现在我不必手持手机在附近徘徊。

答案 8 :(得分:7)

我创建了一个简单的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;
        }
    }
}

希望它可以帮助..

答案 9 :(得分:6)

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

所有的功劳应归功于佩德罗所做的大部分努力。

答案 10 :(得分:3)

来自Google Play的假GPS应用为我做了伎俩。只需确保您已阅读应用说明中的所有说明。启用“假GPS”后,您必须禁用其他位置服务以及启动应用程序。为我所需要的工作做得很好。

以下是GooglePlay上应用的链接: Fake GPS

答案 11 :(得分:2)

可以在此处找到执行此操作的Google教程,它提供了代码示例并说明了该过程。

http://developer.android.com/training/location/location-testing.html#SendMockLocations

答案 12 :(得分:1)

如果您的设备已插入计算机并且您尝试更改通过仿真器控件发送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

答案 13 :(得分:1)

也许它不是&#39;程序员&#39;方法,但如果您想节省您的时间并立即获得工作解决方案,请尝试使用专门用于模拟Google Play中的位置的应用程序:

Fake GPS Location Spoofer

Mock Locations

Fake GPS location

答案 14 :(得分:1)

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

开发人员选项 - &gt; 选择模拟位置应用(这意味着,选择了假位置应用)。

假GPS应用

要添加的地图上的双重标签 - &gt;点击播放按钮 - &gt;显示吐司&#34;假位置停止&#34;

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

答案 15 :(得分:1)

添加到您的清单

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

您还需要在设备开发人员设置中启用模拟位置。如果不可用,请在完成上述操作后将“模拟位置应用程序”设置为您的应用程序。

答案 16 :(得分:0)

我想知道你是否需要精心设计的Mock Location设置。在我的情况下,一旦我得到一个修复位置,我正在调用一个功能来处理新的位置。在计时器中创建一个模拟位置。而是用该位置调用该函数。在短时间内了解GPS会产生真实的当前位置。哪个可以。如果您将更新时间设置得足够长。

答案 17 :(得分:0)

我在Android手机上编写了一个运行WebServer(类似REST)的应用程序,因此您可以远程设置GPS位置。该网站提供了一个地图,您可以在该地图上单击以设置新职位,或使用&#34; wasd&#34;钥匙向任何方向移动。该应用程序是一个快速的解决方案,所以几乎没有用户界面和文档,但实施是直接的,你可以在(只有四个)类中查看所有内容。

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

答案 18 :(得分:0)

在清单文件中使用此权限

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

android studio会建议&#34;模拟位置只应在测试或调试特定的清单文件(通常是src / debug / AndroidManifest.xml)中被请求&#34; 只需停用检查

现在确保您已选中&#34; 允许模拟位置&#34;在手机的开发者设置中

使用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); 

答案 19 :(得分:0)

利用Android手机和平板电脑(名为CATLES)的非常方便和免费的交互式位置模拟器。它在系统范围内(甚至在谷歌地图或Facebook应用程序中)嘲笑GPS位置,它适用于物理设备和虚拟设备:

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

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

答案 20 :(得分:0)

以上解决方案对我不起作用,因为我正在使用具有FusedLocationProviderClient的最新Google Play服务版本的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)