0

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!

Maveňツ
  • 1
  • 12
  • 50
  • 89
Ben
  • 966
  • 2
  • 10
  • 24

0 Answers0