为什么通过反射找不到带有布尔参数的方法?

发布于 2024-10-19 22:16:13 字数 3346 浏览 1 评论 0原文

我正在尝试一些反射调用来调用通常对我隐藏的方法。

我知道这不是好行为,但正如我所说,我只是在玩玩。

我使用此代码来检索和调用该方法:

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

setData = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", Boolean.class);
setData.setAccessible(true);
setData.invoke(cm, false);

这给了我这个异常:

03-02 12:21:40.411: ERROR/test(1052): java.lang.NoSuchMethodException: setMobileDataEnabled
03-02 12:21:40.411: ERROR/test(1052):     at java.lang.ClassCache.findMethodByName(ClassCache.java:308)
03-02 12:21:40.411: ERROR/test(1052):     at java.lang.Class.getDeclaredMethod(Class.java:748)

然后我尝试查看该方法是否在类中声明,并尝试查找所有方法并调用所需的方法:

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

Method[] methods = cm.getClass().getMethods();
for (Method method : methods) {
   Log.d(Test.class.getSimpleName(), "Method name is: " + method.getName());
   if (method.getName().equals("setMobileDataEnabled")) {
      Log.d(Test.class.getSimpleName(), "Found method calling");
       method.setAccessible(true);
       method.invoke(cm, false);
   }
}

这给了我以下输出:

03-02 12:19:41.851: DEBUG/Test(980): Method name is: getActiveNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getAllNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getBackgroundDataSetting
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getLastTetherError
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getMobileDataEnabled
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkInfo
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkPreference
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableIfaces
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableUsbRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableWifiRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetheredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: getTetheringErroredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: isTetheringSupported
03-02 12:19:41.871: DEBUG/Test(980): Method name is: requestRouteToHost
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setBackgroundDataSetting
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setMobileDataEnabled
03-02 12:19:41.871: DEBUG/Test(980): Found method calling
03-02 12:19:41.871: DEBUG/ConnectivityService(127): setMobileDataEnabled(false)
03-02 12:19:41.891: DEBUG/ConnectivityService(127): getMobileDataEnabled returning true
03-02 12:19:41.931: ERROR/Test(980): InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980): java.lang.reflect.InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980):     at android.net.ConnectivityManager.setMobileDataEnabled(ConnectivityManager.java:379)
03-02 12:19:41.931: ERROR/Test(980):     at java.lang.reflect.Method.invokeNative(Native Method)
03-02 12:19:41.931: ERROR/Test(980):     at java.lang.reflect.Method.invoke(Method.java:521)
03-02 12:19:41.931: ERROR/Test(980):     at Test(Test.java:84)

此输出向我显示 Method 存在,并且我可以调用它,尽管 Android 健全性检查已启动并禁止调用更深层次的系统方法。

为什么通过getDeclaredMethod找不到该方法?

I'm playing around with some reflection calls to call a method that is normally hidden from me.

I know that this isn't good behaviour but as I said im playing around.

I used this code to retrieve and invoke the method:

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

setData = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", Boolean.class);
setData.setAccessible(true);
setData.invoke(cm, false);

This gives me this Exception:

03-02 12:21:40.411: ERROR/test(1052): java.lang.NoSuchMethodException: setMobileDataEnabled
03-02 12:21:40.411: ERROR/test(1052):     at java.lang.ClassCache.findMethodByName(ClassCache.java:308)
03-02 12:21:40.411: ERROR/test(1052):     at java.lang.Class.getDeclaredMethod(Class.java:748)

Then i tried to see if the method is declared in the class and tried this to find all methods and invoke the wanted method:

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

Method[] methods = cm.getClass().getMethods();
for (Method method : methods) {
   Log.d(Test.class.getSimpleName(), "Method name is: " + method.getName());
   if (method.getName().equals("setMobileDataEnabled")) {
      Log.d(Test.class.getSimpleName(), "Found method calling");
       method.setAccessible(true);
       method.invoke(cm, false);
   }
}

This gives me the following output:

03-02 12:19:41.851: DEBUG/Test(980): Method name is: getActiveNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getAllNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getBackgroundDataSetting
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getLastTetherError
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getMobileDataEnabled
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkInfo
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkPreference
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableIfaces
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableUsbRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableWifiRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetheredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: getTetheringErroredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: isTetheringSupported
03-02 12:19:41.871: DEBUG/Test(980): Method name is: requestRouteToHost
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setBackgroundDataSetting
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setMobileDataEnabled
03-02 12:19:41.871: DEBUG/Test(980): Found method calling
03-02 12:19:41.871: DEBUG/ConnectivityService(127): setMobileDataEnabled(false)
03-02 12:19:41.891: DEBUG/ConnectivityService(127): getMobileDataEnabled returning true
03-02 12:19:41.931: ERROR/Test(980): InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980): java.lang.reflect.InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980):     at android.net.ConnectivityManager.setMobileDataEnabled(ConnectivityManager.java:379)
03-02 12:19:41.931: ERROR/Test(980):     at java.lang.reflect.Method.invokeNative(Native Method)
03-02 12:19:41.931: ERROR/Test(980):     at java.lang.reflect.Method.invoke(Method.java:521)
03-02 12:19:41.931: ERROR/Test(980):     at Test(Test.java:84)

This output shows me that the Method is there and I can call it despite the fact that the Android sanity check kicks in and forbids the calling of the deeper system methods.

Why is it that the method is not found via getDeclaredMethod?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

渔村楼浪 2024-10-26 22:16:13

此问题的两个可能原因,在不知道来源的情况下无法说出哪一个:

  • 参数类型实际上是 Boolean 而不是 boolean 吗?不同的类型,可能有不同的重载方法,这就是为什么像 boolean.class 这样的文字存在并且必须在此处使用的原因。
  • 方法是继承的吗? getDeclaredMethod() 仅查看类自己的方法,而不查看已继承的方法。您必须遍历类层次结构才能获取继承的方法。

Two possible causes of this problem, can't say which without knowning the source:

  • Is the parameter type actually Boolean and not boolean? Different types, potentially different overloaded methods, which is why literals like boolean.class exist and have to be used here.
  • Is the method inherited? getDeclaredMethod() only looks at the class's own methods, not those that have been inherited. You'll have to iterate through the class hierarchy to get inherited methods.
半世晨晓 2024-10-26 22:16:13

在问题标题中,您编写 boolean(小写),但在代码中,您搜索 Boolean(大写)。如果参数类型为布尔值(原始),请尝试此操作:

setData = ConnectivityManager.class.getDeclaredMethod(
          "setMobileDataEnabled", boolean.class);

In the Question title, you write boolean (lower case), but in your code, you search for Boolean (upper case). Try this if the parameter type is boolean (primitive):

setData = ConnectivityManager.class.getDeclaredMethod(
          "setMobileDataEnabled", boolean.class);
调妓 2024-10-26 22:16:13

setMobileDataEnabled 是在 ConnectivityManager 还是父类上?看看 getDeclaredMethod,我认为它需要在类本身上,而 getMethod 从整个继承树中获取方法。

Is setMobileDataEnabled on ConnectivityManager or a parent class? Looking at getDeclaredMethod, I think it needs to be on the class itself, whereas getMethod gets methods from the entire inheritance tree.

兲鉂ぱ嘚淚 2024-10-26 22:16:13

将正确的使用权限放入 AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

您遇到的问题是安全问题。

Put the proper uses permissions in the AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

The problem you are having is a security issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文