Why can't a method with a boolean parameter be found through reflection?

I play with some reflection calls to invoke a method that is usually hidden from me.

I know that this is not good behavior, but as I said, he plays.

I used this code to extract and call a 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 find out if the method was declared in the class and if it tried to find all the methods and call the required 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 result:

 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 conclusion shows me that Method exists, and I can name it, despite the fact that the Android health check runs and prevents the call of deeper system methods.

Why is this method not found through getDeclaredMethod ?

+4
source share
4 answers

Two possible causes of this problem cannot be said to be without a source:

  • Is the parameter type Boolean and not Boolean ? Different types, potentially different overloaded methods, so literals like boolean.class exist and should be used here.
  • Is the method inherited? getDeclaredMethod() considers only class methods, not those that are inherited. You will need to go through the class hierarchy to get the inherited methods.
+16
source

In the title of the question you write boolean (lowercase), but in your code you are looking for boolean (uppercase). Try if the parameter type is boolean (primitive):

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

Is setMobileDataEnabled in a ConnectivityManager or parent class? Looking at getDeclaredMethod, I think it should be in the class itself, while getMethod gets methods from the entire inheritance tree.

0
source

Set the correct usage permissions in AndroidManifest.xml

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

You are having a security issue.

0
source

Source: https://habr.com/ru/post/1341965/


All Articles