-1

I am trying to mock GPS locations in my Android App.

I do:

  • use com.google.android.gms:play-services-location:9.4.0
  • have a registered GoogleApiClient
  • have all necessary permissions: ALLOW_MOCK_LOCATIONS, ACCESS_MOCK_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION
  • run the application on a real device in debug mode
  • receive real locations when not trying to mock

My receiver class registers for location updates like this:

private void registerLocationListener(){
    if(isStarted&&googleApiClient.isConnected()) {
        LocationRequest request = new LocationRequest()
                .setInterval(1000)
                .setSmallestDisplacement(0.5f)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(
                googleApiClient, request, this);
        LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    }
}

and I have another class which shares the same GoogleApiClient that looks something like this:

public class LocationMocker{
    private final GoogleApiClient googleApiClient;

    public LocationMocker(GoogleApiClient apiClient){
        this.googleApiClient = apiClient;
    }


    private void start(){
        LocationServices.FusedLocationApi.setMockMode(googleApiClient, true).setResultCallback(new ResultCallbacks<Status>() {
            @Override
            public void onSuccess(@NonNull Status status) {
                Log.e(TAG,"SUCCESS "+status);

                new Thread(){
                    public void run(){
                        while(!this.isInterrupted()){
                            Thread.sleep(timeout);

                        LocationServices.FusedLocationApi.setMockLocation(googleApiClient, generateMockLocation())
                                    .setResultCallback(new ResultCallbacks<Status>() {
                                        @Override
                                        public void onSuccess(@NonNull Status status) {
                                            Log.e(TAG,"NEW MOCKED LOCATION!");
                                        }

                                        @Override
                                        public void onFailure(@NonNull Status status) {
                                            Log.e(TAG,"FAILURE "+status);
                                        }
                                    });
                        }
                    }
                }.start();
            }

            @Override
            public void onFailure(@NonNull Status status) {
                Log.e(TAG,"FAILURE "+status);
            }
        });
    }
}

What happens is, that everything registers the correct way (I log all callbacks) and I also see periodically my "NEW MOCKED LOCATION!" log, but my LocationListeners onLocationChanged(Location location) is never called.

I also tried different orders (register locationlistener first, setMockMode first, ...).

Any ideas what I do wrong? As I already said: everything works fine if I use real GPS.

simmerl
  • 9
  • 1
  • 5

1 Answers1

-1

Why are you using a thread to keep fusedlocation updated? You should use:

LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);

and

@Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    }

Read this: https://developer.android.com/training/location/receive-location-updates.html

Alessandro Verona
  • 1,157
  • 9
  • 23
  • If you check the class you might recognise that the Thread is inside `LocationMocker`and if you check the run method you would see that I call `LocationServices.FusedLocationApi.setMockLocation` so what I do here is I PROVIDE location information - not listen to its changes. – simmerl Jan 25 '17 at 15:10