Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTestProviderLocation() does not trigger calling of onLocationChanged()

I'm trying to get this bit of code to work:

Testing GPS in Android

The problem is, when I run the test, onLocationChanged() is never called:

public class LocationTest0 extends AndroidTestCase implements LocationListener {
private Location received = null;
public void testExample() {
    LocationManager lm = (LocationManager)this.getContext().getSystemService(Context.LOCATION_SERVICE);
    String testProvider = "Test";

    if (null == lm.getProvider(testProvider)){
        lm.addTestProvider(testProvider, false, false, false, false, false, false, false, Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
    }

    lm.setTestProviderEnabled(testProvider, true);
    lm.requestLocationUpdates(testProvider, 0, 0, this);
    lm.setTestProviderStatus(testProvider, LocationProvider.AVAILABLE, null, System.currentTimeMillis());

    Location location = new Location(testProvider);
    location.setLatitude(1.0);
    location.setLongitude(2.0);
    location.setTime(System.currentTimeMillis());
    lm.setTestProviderLocation(testProvider, location);

    Assert.assertFalse("Received Location is null", received == null );

    lm.removeTestProvider(testProvider);
}
@Override
public void onLocationChanged(Location location) {
    received = location;
    Log.d("LocationTest0", "onLocationChanged CALLED");
    // Never gets called
}
like image 918
CL22 Avatar asked May 16 '11 09:05

CL22


3 Answers

This is what worked for me

locationManager.addTestProvider(mocLocationProvider, false, false,
                    false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);

.

Location mockLocation = new Location(mocLocationProvider); // a string
mockLocation.setLatitude(location.getLatitude());  // double 
mockLocation.setLongitude(location.getLongitude()); 
mockLocation.setAltitude(location.getAltitude()); 
mockLocation.setTime(System.currentTimeMillis()); 
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation); 

.

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">

Also in the android phone settings make sure you have the "Allow mock locations" checkbox ticked

like image 118
Reno Avatar answered Oct 16 '22 01:10

Reno


I had the same issue and could get it to work. I'll share it here in case it can help anyone else.

The thing to consider is that any call to setTestProviderLocation will invoke any listener registered on the mock providers at the time of the invocation. So if you call setTestProviderLocation and right after that call requestLocationUpdates, the onLocationChanged callback never gets called.

My problem was that I had these two (setTestProviderLocation and requestLocationUpdates) in two different threads and requestLocationUpdates was called after, so I never got a callback to onLocationChanged. If your program is multi-threaded (which very likely is) make sure setTestProviderLocation is called after requestLocationUpdates.

Also I noticed for any call to setTestProviderLocation, onLocationChanged will be called once (approximately). So you can put setTestProviderLocation in a loop to simulate a series of calls to onLocationChanged. This way you can simulate a path as well.

like image 2
m.hashemian Avatar answered Oct 16 '22 00:10

m.hashemian


I had the same problem. Couldn't resolve it and finally I gave up and added a call to onLocationChanged( location) after locationManager.setTestProviderEnabled( PROVIDER, location) manually. It's not pretty but works.

like image 1
v0rin Avatar answered Oct 16 '22 02:10

v0rin