[android] How to mock location on device?

How can I mock my location on a physical device (Nexus One)?

I know you can do this with the emulator in the Emulator Control panel, but this doesn't work for a physical device.

This question is related to android gps location mocking

The answer is


I wonder if you need the elaborate Mock Location setup. In my case once I got a fix location I was calling a function to do something with that new location. In a timer create a mock location. And call the function with that location instead. Knowing all along that in a short while GPS would come up with a real current location. Which is OK. If you have the update time set sufficiently long.


The above solutions did not work for me because I was testing on an Android device with the latest Google Play Services version which utilizes the FusedLocationProviderClient. After setting the mock location permission in the app manifest and the app as the specified mock location app in the developer settings (as mentioned in the previous answers), I then added the Kotlin code below which successfully mocked the location.

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)

What Dr1Ku posted works. Used the code today but needed to add more locs. So here are some improvements:

Optional: Instead of using the LocationManager.GPS_PROVIDER String, you might want to define your own constat PROVIDER_NAME and use it. When registering for location updates, pick a provider via criteria instead of directly specifying it in as a string.

First: Instead of calling removeTestProvider, first check if there is a provider to be removed (to avoid IllegalArgumentException):

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

Second: To publish more than one location, you have to set the time for the location:

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

There also seems to be a google Test that uses MockLocationProviders: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/location/LocationManagerProximityTest.java

Another good working example can be found at: http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/

Another good article is: http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 You'll also find some code that actually works for me on the emulator.


You can use the Location Services permission to mock location...

"android.permission.ACCESS_MOCK_LOCATION"

and then in your java code,

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

Maybe it's not 'programmer' approach, but if you want save your time and get working solution instant try one of the apps which are dedicated to mock location available in Google Play:

Fake GPS Location Spoofer

Mock Locations

Fake GPS location


Fake GPS app from google play did the trick for me. Just make sure you read all the directions in the app description. You have to disable other location services as well as start your app after you enable "Fake GPS". Worked great for what I needed.

Here is the link to the app on GooglePlay: Fake GPS


I wish I had my cable handy. I know you can telnet to the emulator to change its location

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

I cannot remember if you can telnet to your device, but I think you can. I hope this helps.

You'll need adb (android debugging bridge) for this (CLI).


This worked for me (Android Studio):

Disable GPS and WiFi tracking on the phone. On Android 5.1.1 and below, select "enable mock locations" in Developer Options.

Make a copy of your manifest in the src/debug directory. Add the following to it (outside of the "application" tag):

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

Set up a map Fragment called "map". Include the following code in 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);
    }
};

Note that you may have to temporarily increase "minSdkVersion" in your module gradle file to 17 in order to use the "setElapsedRealtimeNanos" method.

Include the following code inside the main activity class:

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

Run your app with AS. On Android 6.0 and above you will get a security exception. Now go to Developer Options in Settings and select "Select mock location app". Select your app from the list.

Now when you tap on the map, onLocationChanged() will fire with the coordinates of your tap.

I just figured this out so now I don't have to tramp around the neighborhood with phones in hand.


There are apps available in the Android Market that allow you to specify a "Mock GPS Location" for your device.

I searched https://market.android.com and found an app called "My Fake Location" that works for me.

The Mock GPS Provider mentioned by Paul above (at http://www.cowlumbus.nl/forum/MockGpsProvider.zip) is another example that includes source code -- although I wasn't able to install the provided APK (it says Failure [INSTALL_FAILED_OLDER_SDK] and may just need a recompile)

In order to use GPS mock locations you need to enable it in your device settings. Go to Settings -> Applications -> Development and check "Allow mock locations"

You can then use an app like the ones described above to set GPS coordinates and Google maps and other apps will use the mock GPS location you specify.


I wrote an App that runs a WebServer (REST-Like) on your Android Phone, so you can set the GPS position remotely. The website provides an Map on which you can click to set a new position, or use the "wasd" keys to move in any direction. The app was a quick solution so there is nearly no UI nor Documentation, but the implementation is straight forward and you can look everything up in the (only four) classes.

Project repository: https://github.com/juliusmh/RemoteGeoFix


Make use of the very convenient and free interactive location simulator for Android phones and tablets (named CATLES). It mocks the GPS-location on a system-wide level (even within the Google Maps or Facebook apps) and it works on physical as well as virtual devices:

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

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


I've had success with the following code. Albeit it got me a single lock for some reason (even if I've tried different LatLng pairs), it worked for me. mLocationManager is a LocationManager which is hooked up to a 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
    );      
}

If your device is plugged into your computer and your trying to changed send GPS cords Via the Emulator control, it will not work.
This is an EMULATOR control for a reason.
Just set it up to update you on GPS change.

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

When GPS is updated rewrite the following method to do what you want it to;

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

Dont forget to put these in the manifest
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION


I've created a simple Handler simulating a moving position from an initial position.

Start it in your connection callback :

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

Hope it can help..


The Google tutorial for doing this can be found here, it provides code examples and explains the process.

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


The solution mentioned by icyerasor and provided by Pedro at http://pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/ worked very well for me. However, it does not offer support for properly starting, stopping and restarting the mock GPS provider.

I have changed his code a bit and rewritten the class to be an AsyncTask instead of a Thread. This allows us to communicate with the UI Thread, so we can restart the provider at the point where we were when we stopped it. This comes in handy when the screen orientation changes.

The code, along with a sample project for Eclipse, can be found on GitHub: https://github.com/paulhoux/Android-MockProviderGPS

All credit should go to Pedro for doing most of the hard work.


Use this permission in manifest file

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

android studio will recommend that "Mock location should only be requested in a test or debug-specific manifest file (typically src/debug/AndroidManifest.xml)" just disable the inspection

Now make sure you have checked the "Allow mock locations" in developer setting of your phone

Use LocationManager

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

Now set the location wherever you want

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

If you use this phone only in development lab, there is a chance you can solder away GPS chip and feed serial port directly with NMEA sequences from other device.


Add to your manifest

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    tools:ignore="MockLocation,ProtectedPermissions" />

Mock location function

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

You'll also need to enable mock locations in your devices developer settings. If that's not available, set the "mock location application" to your application once the above has been implemented.


Install Fake GPS app https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en

Developer options -> Select mock location app(It's mean, Fake location app selected).

Fake GPS app:

Double tab on the map to add -> click the play button -> Show the toast "Fake location stopped"

finally check with google map apps.


Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to gps

Android "gps requires ACCESS_FINE_LOCATION" error, even though my manifest file contains this Best way to get user GPS location in background in Android How to set fake GPS location on IOS real device Android Location Manager, Get GPS location ,if no GPS then get to Network Provider location How to get current location in Android How to get Android GPS location Is Android using NTP to sync time? Does GPS require Internet? Android: How to get accurate altitude? Get GPS location via a service in Android

Examples related to location

Nginx serves .php files as downloads, instead of executing them Get User's Current Location / Coordinates Location Services not working in iOS 8 How to set fake GPS location on IOS real device Android Google Maps API V2 Zoom to Current Location What is meaning of negative dbm in signal strength? How does it work - requestLocationUpdates() + LocationRequest/Listener How to get Android GPS location Redirect using AngularJS How to check if Location Services are enabled?

Examples related to mocking

How can I mock the JavaScript window object using Jest? How can I mock an ES6 module import using Jest? Mocking a function to raise an Exception to test an except block Unfinished Stubbing Detected in Mockito Python mock multiple return values How do I mock a service that returns promise in AngularJS Jasmine unit test? How do Mockito matchers work? Mocking static methods with Mockito How to spyOn a value property (rather than a method) with Jasmine How do I mock a class without an interface?