1

I am trying to get method reportLocation() through reflection from "android.location.ILocationManager$Stub".

CODE:

 Class<?> mStub = Class.forName("android.location.ILocationManager$Stub");
 Method getInterface = mStub.getMethod("asInterface", IBinder.class);

 Class mServiceManager = Class.forName("android.os.ServiceManager");
 Method getService = mServiceManager.getMethod("getService", String.class);

 Object iBindermInterface = getService.invoke(null, "location");
 Object mInterface = getInterface.invoke(null, (IBinder) iBindermInterface);

 Method method = mInterface.getClass().getMethod("reportLocation", Location.class, Boolean.class);

ERROR:

java.lang.NoSuchMethodException: android.location.ILocationManager$Stub$Proxy.reportLocation [class android.location.Location, class java.lang.Boolean]

I do not see this method when I trying to print all methods from "android.location.ILocationManager$Stub":

 Class<?> mStub = Class.forName("android.location.ILocationManager$Stub");
  Method[] getInterfaceAll = mStub.getMethods();
        for (Method getInt : getInterfaceAll)
          Log.d(LOG_TAG, "getInt = "+getInt);

In Android P (SDK 28) I have no problem with it.

In Android Q (SDK 29) interface android.location.ILocationManager does not have reportLocation() method, instead, to my assumptions, interface com.android.internal.location.ILocationProviderManager has onReportLocation(). But this interface contains the abstract method onReportLocation() and I cannot get its implementation.

What interface contain this method or it has been changed (renamed) to another method?

vkozhemi
  • 371
  • 2
  • 7

2 Answers2

0

This is the life of using internals API with reflection.

The problem it's simple, the reportLocation(in Location location, boolean passive) method was present until Android 9 in the ILocationManager.aidl interface, check here

But starting from Android 10 the method has been removed as you can see in the internal section here

You should probably change your code to use some public APIs, or you will have hard time scanning the current APIs and find a replacement to use with reflection. (and you will still risking they blacklisting the API in the future)

PS: Just for complete information, probably the functionality has been moved here (I've followed some commits, but this could be completely unusable/different and I really discourage you to try to use it)

MatPag
  • 41,742
  • 14
  • 105
  • 114
  • Any idea how to call that function now from LocationProviderBase? Thanks! Or better to just call ILocationProviderManager.onReportLocation? – eXistenZ Oct 16 '20 at 12:59
0

I found out how to put location on report.

Use the public boolean injectLocation(@NonNull Location newLocation) method, it can be obtained from ILocationManager.

        Class<?> mStub = Class.forName("android.location.ILocationManager$Stub");
        Method getInterface = mStub.getMethod("asInterface", IBinder.class);
        Method getService = Class.forName("android.os.ServiceManager")
            .getMethod("getService", String.class);
        Object mInterface = getInterface
            .invoke(null, (IBinder) getService.invoke(null, "location"));
        Method method = mInterface.getClass()
            .getMethod("injectLocation", Location.class);
        method.invoke(mInterface, location);
       
vkozhemi
  • 371
  • 2
  • 7
  • This seems to be blocked now in Android 10. Is there any alternative? – eXistenZ Oct 03 '20 at 20:42
  • it works on Android 10 and 11, but I did not mentioned that it works with the system apps. If you interested in It looks like android:sharedUserId="android.uid.system" need to add in AndroidManifest.xml and so on. https://stackoverflow.com/questions/17222535/create-system-application – vkozhemi Oct 05 '20 at 09:13
  • Thanks for the info! Are you using compileSdkVersion 29 or 30? – eXistenZ Oct 05 '20 at 14:38
  • I am getting this error on Android 10: java.lang.NoSuchMethodException: android.location.ILocationManager$Stub$Proxy.injectLocation [class android.location.Location] Can you please explain why android:sharedUserId="android.uid.system" is needed and how does that change anything? My app is already a system app. Also would Google Play Store maybe complain if you add that in the manifest? Thanks! – eXistenZ Oct 15 '20 at 23:30
  • So basically it is not allowed to use it: Accessing hidden method Landroid/location/ILocationManager;->injectLocation(Landroid/location/Location;)Z (greylist-max-o, reflection, denied) – eXistenZ Oct 16 '20 at 14:18