无法从 Android 中的 "android.location.ILocationManager" 中找到方法 reportLocation() Q

Can not find method reportLocation() from "android.location.ILocationManager" in Android Q

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

代码:

 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);

错误:

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

当我尝试打印来自 "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);

在AndroidP(SDK 28)我没问题

在AndroidQ(SDK 29)接口android.location.ILocationManager中没有reportLocation()方法,相反,根据我的假设,接口com.android.internal.location.ILocationProviderManageronReportLocation() .但是这个接口包含抽象方法onReportLocation(),我无法得到它的实现。

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

这就是使用内部组件API和反射的生活。

问题很简单,reportLocation(in Location location, boolean passive)方法一直存在到Android9在ILocationManager.aidl界面,检查here

但是从 Android 10 开始,该方法已被删除,您可以在内部部分看到 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:只是为了获得完整的信息,可能功能已被移动 here(我遵循了一些提交,但这可能完全是 unusable/different,我真的不鼓励你尝试使用它)

我找到了如何在报告中添加位置信息。

使用public boolean injectLocation(@NonNull Location newLocation)方法,可以从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);