After downloading and using 'Fake Gps' from google store, I thought of creating one for educational purposes.
I am using GoogleApiClient FusedLocationAPI for getting my current location and for creating a mock location. I am able to get my current location, but am unable to mock location.
public class GoogleApiClientGeoLocation implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleApiClient googleApiClient;
public GoogleApiClientGeoLocation(Context activity) {
googleApiClient = new GoogleApiClient.Builder(activity, this, this).addApi(LocationServices.API).build();
....
}
public void connect() {
if (googleApiClient != null) {
googleApiClient.connect();
}
}
public void disconnect() {
googleApiClient.disconnect();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
Log.e("TAG","Location changed"+location.getLatitude() + ", "+ location.getLongitude());
}
private static final String PROVIDER = LocationManager.NETWORK_PROVIDER;//"flp";
private static final double LAT = 37.377166;
private static final double LNG = -122.086966;
private static final float ACCURACY = 3.0f;
public Location createLocation(double lat, double lng, float accuracy) { //<-for testing purposes using a static lat,long
// Create a new Location
Location newLocation = new Location(PROVIDER);
newLocation.setLatitude(LAT);
newLocation.setLongitude(LNG);
newLocation.setAltitude(1000);
newLocation.setElapsedRealtimeNanos(System.nanoTime());
newLocation.setTime(System.currentTimeMillis());
newLocation.setAccuracy(500);
return newLocation;
}
public void startMock() {
LocationServices.FusedLocationApi.setMockMode(googleApiClient, true);
}
public void stopMock() {
LocationServices.FusedLocationApi.setMockMode(googleApiClient, false);
}
public void domock() {
Location testLocation = createLocation(LAT, LNG, ACCURACY);
if (ContextCompat.checkSelfPermission(_context, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.setMockLocation(googleApiClient, testLocation);
Log.e("TAG","Location Mocked");
}else{
Log.e("TAG","Can not Mock location");
}
}
}
I have a class GoogleApiClientGeoLocation which handles all the functions. Flow is initialization->connect->startmock->mock->stopmock->disconnect
If I do a connect(), locationchange() gives me current location, however when I startmock() and domock() locationchange() pauses and returns nothing, and when I stopmock() locationchange() starts giving me current location again.
I do get a log message saying 'location mocked'.
Is my 'PROVIDER' wrong?
I want to be able to create a mock location and be able to go to google map and see it pointing to mock location.
The fused location provider is a location API in Google Play services that intelligently combines different signals to provide the location information that your app needs.
"Allow Mock locations" are built-in phone settings which let users hide their GPS location while using their device.
It appears FusedLocationProvider is on a different clock then the System clock. I.e. elapsedRealTimeNanos
is different then System.nanoTime
. So the times you set by using the System clock will be off and I’m assuming the new Locations are considered stale and invalid.
To get a valid elapsedRealTimeNanos
I add an offset to the System.nanoTime()
each time I create a mock Location. I calculate that offset when I first connect to the googleApiClient:
Location current = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
nanoOffset = current.getElapsedRealtimeNanos() - System.nanoTime();
Then, the complete mock Location I create is as follows:
Location location = new Location("flp"); // indicates mock
locationlocation.setLatitude(latLon.getLat());
location.setLongitude(latLon.getLon());
location.setTime(System.currentTimeMillis());
location.setAccuracy(6f);
location.setElapsedRealtimeNanos(System.nanoTime() + nanoOffset);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With