Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to SET Android Mock GPS location?

Description

I'm having a issue while trying to use android mock locations, my main goal is to set the android GPS into thinking we are in a different spot, AKA fake GPS.

Current attempts

I have currently tried two different similar solutions, avaiable in both this websites:

  • Programming Jungle
  • Mobiarch

Both tutorials are from 2012, I don't know if they are outdated or I'm having a hard time implementing them to work.

Coding development

First I make sure I have permissions:

  1. ACCESS_COARSE_LOCATION
  2. ACCESS_FINE_LOCATION
  3. ACCESS_MOCK_LOCATION *

Note: 1 and 2 are both checked, if they are not available I ask permission using requestPermissions function. The third one is not avaiable to be asked, in fact it can only be added through AndroidManifest.xml on debug mode.

I also made sure I have my APP selected in Settings > Developer options > Allow MOCK locations.

After all this, I have made this function that I tried calling through OnCreate method or OnClick of a button:

public void mockLocation(){
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy( Criteria.ACCURACY_FINE );
    String mocLocationProvider = lm.getBestProvider( criteria, true );
    if ( mocLocationProvider == null ) {
        Toast.makeText(getApplicationContext(), "No location provider found!", Toast.LENGTH_SHORT).show();
        return;
    }
    lm.addTestProvider(mocLocationProvider, false, false,
            false, false, true, true, true, 0, 5);
    lm.setTestProviderEnabled(mocLocationProvider, true);

    Location loc = new Location(mocLocationProvider);
    Location mockLocation = new Location(mocLocationProvider); // a string
    mockLocation.setLatitude(-26.902038);  // double
    mockLocation.setLongitude(-48.671337);
    mockLocation.setAltitude(loc.getAltitude());
    mockLocation.setTime(System.currentTimeMillis());
    lm.setTestProviderLocation( mocLocationProvider, mockLocation);
    Toast.makeText(getApplicationContext(), "Working", Toast.LENGTH_SHORT).show();
}

If I compile and test this way I'll receive the Toast: "No location provider found!". But if I change mocLocationProvider to:

String mocLocationProvider = LocationManager.NETWORK_PROVIDER;

I get APP crash and in LogCat it says that crashed during this line:

lm.setTestProviderLocation(mocLocationProvider, mockLocation);

So I'm currently out of options and don't know how to advance.

like image 443
Guilherme Garcia da Rosa Avatar asked Jan 05 '23 18:01

Guilherme Garcia da Rosa


1 Answers

you must set first:

allow mock location in setting

second set permissions:

ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION ACCESS_MOCK_LOCATION

third use this method :

setMock(some_lat,some_lon,some accuracy);

private void setMock(double latitude, double longitude, float accuracy) {
 locMgr.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(latitude);
    newLocation.setLongitude(longitude);
    newLocation.setAccuracy(accuracy);
    newLocation.setAltitude(0);
    newLocation.setAccuracy(500);
    newLocation.setTime(System.currentTimeMillis());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        newLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }
    locMgr.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);

    locMgr.setTestProviderStatus(LocationManager.GPS_PROVIDER,
            LocationProvider.AVAILABLE,
            null,System.currentTimeMillis());

    locMgr.setTestProviderLocation(LocationManager.GPS_PROVIDER, newLocation);}
like image 145
Hadi Avatar answered Jan 08 '23 06:01

Hadi