I'm trying to mock the GPS location in my app but as soon as I set mocked location, any app using the google play services is unable to get the location of the device, whether it's the real one or the mocked one.
For instance, if I open Google Map and try to go to my location, i'll get the message
waiting for the location
and nothing will happen. That's the same in my app, the location is never found
my code is the following:
public class MockLocationService {
protected Context context;
// Define a LocationClient object
public LocationClient mLocationClient;
// provider of fake locations
private static final String PROVIDER = "flp";
// TAG for the logs
protected static final String TAG = "MockLocationService";
// intens for states
public static final String MOCK_LOCATION_SERVICE_CONNECTED = "CONNECTED";
public static final String MOCK_LOCATION_SERVICE_DECONNECTED = "DECONNECTED";
public static final String MOCK_LOCATION_SERVICE_FAILED = "FAILED";
public static final String MOCK_LOCATION_SERVICE_SETTING_NOT_ENABLED = "SETTING_NOT_ENABLED";
// current mockLocation
protected static Location currentMockLocation;
public MockLocationService(Context context) {
this.context = context;
// connect to the Google play services
mLocationClient = new LocationClient(context, connectionCallbacks,
onConnectionFailedListener);
}
/**
* Connect to the API to enable mocking the location
*/
public void connect() {
// Connect to Location Services
// ONLY WHEN CALLBACK IS CALLED, ACT
mLocationClient.connect();
}
/**
* Disconnect from the API, stops mocking the location
*/
public void disconnect() {
// terminate aTask
aTask.cancel(true);
currentMockLocation=null;
// disconnect
mLocationClient.disconnect();
}
/**
* Sets the location from a LocationMessage object as the device current
* location
*
* @param location
*/
public void setLocation(LocationMessage location) {
if (location.getLat() == null || location.getLng() == null
|| location.getAccuracy() == null)
return;
Location newLocation = new Location(PROVIDER);
newLocation.setLatitude(location.getLat());
newLocation.setLongitude(location.getLng());
newLocation.setAccuracy(1);
newLocation.setTime(System.currentTimeMillis());
newLocation.setBearing(0F);
newLocation.setAltitude(0F);
// set it as a mocked location
this.setMockLocation(newLocation);
// Create a new Location
Log.d(TAG,
"New mocked location: lat: " + location.getLat() + " - lng: "
+ location.getLng() + " - accuracy: "
+ location.getAccuracy());
}
/**
* Sets a Location object as the location for the device
*
* @param mockLocation
* the mocked Location object
*/
protected void setMockLocation(Location mockLocation) {
if (!mLocationClient.isConnected())
return;
currentMockLocation = mockLocation;
if (currentMockLocation==null) {
aTask.execute((Void) null);
}
}
// asynchronously send the mock location every second (for GPS)
final RestAsyncTask<Boolean[]> aTask = new RestAsyncTask<Boolean[]>() {
// executes on background thread
@Override
protected Boolean[] doInBackground(Void... lists) {
// set mock location
do {
mLocationClient.setMockLocation(currentMockLocation);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (true);
}
@Override
protected void onPostExecute(Boolean[] result) {
return;
}
};
/**
* When connect/unconnect from the location client
*/
protected ConnectionCallbacks connectionCallbacks = new ConnectionCallbacks() {
@Override
public void onDisconnected() {
sendIntent(MOCK_LOCATION_SERVICE_DECONNECTED);
}
@Override
public void onConnected(Bundle arg0) {
sendIntent(MOCK_LOCATION_SERVICE_CONNECTED);
// When the location client is connected, set mock mode
try {
mLocationClient.setMockMode(true);
} catch (Exception e) {
sendIntent(MOCK_LOCATION_SERVICE_SETTING_NOT_ENABLED);
}
}
};
/**
* When connection failed to the location client
*/
protected OnConnectionFailedListener onConnectionFailedListener = new OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult arg0) {
sendIntent(MOCK_LOCATION_SERVICE_FAILED);
}
};
/**
* Send an intent with the correct type
*
* @param action
* : the action parameter of the intent
*/
protected static void sendIntent(String action) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(action);
LocalBroadcastManager.getInstance(PEApplication.getInstance())
.sendBroadcast(broadcastIntent);
}
}
am I missing something?
thanks!