1

I have a need to create a test application which can mock the location. On clicking button, the latitude and longitude values provided in text box need to be set as the mock location. I am trying to build this using simple way using fused location provider APIs

Location mockLocation = new Location("flp");
mockLocation.setLatitude(12);
mockLocation.setLongitude(82);
mockLocation.setAccuracy(1.0f);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
mockLocation.setTime(new Date().getTime());


Criteria criteria = new Criteria();
criteria.setAccuracy( Criteria.ACCURACY_FINE );
String provider = locationManager.getBestProvider( criteria, true );

if ( provider == null ) {
   Log.e( "", "No location provider found!" );
   return;
}

// provider and LocationManager.GPS_PROVIDER are same - "gps"

locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mockLocation); // --> I am getting exception here

I gave all possible permissions in manifest file:

ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ALLOW_MOCK_LOCATIONS
ACCESS_MOCK_LOCATION

Also manually enabled developer options, application permissions, and mock location provider app in settings.

I am getting except on setTestProviderLocation:

java.lang.IllegalStateException: Could not execute method for android:onClick at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390) at android.view.View.performClick(View.java:6266) at android.view.View$PerformClick.run(View.java:24730) at android.os.Handler.handleCallback(Handler.java:793) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:173) at android.app.ActivityThread.main(ActivityThread.java:6698) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) ... 9 more Caused by: java.lang.IllegalArgumentException: Provider "gps" unknown at android.os.Parcel.readException(Parcel.java:1955) at android.os.Parcel.readException(Parcel.java:1897) at android.location.ILocationManager$Stub$Proxy.setTestProviderLocation(ILocationManager.java:1340) at android.location.LocationManager.setTestProviderLocation(LocationManager.java:1305)

Any way to fix this?

Thanks, raj

Roy
  • 43
  • 4
  • What kind of widget did you call the OnClickListener ? – mohammadReza Abiri Apr 28 '19 at 09:09
  • @raj, Did you declare button view in activity class? means `findViewById` – Nikunj Sorathiya Apr 28 '19 at 09:10
  • public void onTestButtonClick(View v) { Toast.makeText(getApplicationContext(),"Hello", Toast.LENGTH_SHORT).show(); //createMockLocation(); } // This is a button click listener and it works (Toast) – Roy Apr 28 '19 at 09:17
  • Did you tried to `locationManager.setTestProviderEnabled(getBestProvider(), true);` before you call _setTestProviderLocation_? – p72b Sep 28 '19 at 19:02
  • locationManager.getBestProvider can return "passive" as well and will end up in `IllegalArgumentException: Cannot mock the passive location provider`. – p72b Sep 28 '19 at 19:11

1 Answers1

0

Since Android 10 my fake location app has the same issue and the app is crashing with:

java.lang.IllegalArgumentException: Provider "gps" unknown

But on older Android versions same code is working. I tested it on 6,7,8 and 9. My temporary solution for it is to catch the exception (until I find a better way). The mock should still work.

try {
   mLocationManager.removeTestProvider(getBestProvider());
} catch (IllegalArgumentException e) {
   // handle the error e.getMessage()
}

Druing debugging I can see the provider gps inside the locationManager list like

mLocationManager.getProvider(getBestProvider())
p72b
  • 106
  • 2
  • 5