2014-07-05 72 views
0

在以下鏈接的幫助下,我嘗試編寫用於啓用/禁用數據的代碼。啓用/禁用數據問題-java.lang.NoSuchMethodException

http://stackoverflow.com/questions/23100298/android-turn-on-off-mobile-data-using-code 

但運行代碼時我得到java.lang.NoSuchMethodException

主代碼

import java.lang.reflect.Field; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import android.content.Context; 
import android.net.ConnectivityManager; 
import android.telephony.TelephonyManager; 
import android.util.Log; 


//the method below enables/disables mobile data depending on the Boolean 'enabled' parameter. 
     public void setMobileDataEnabled(Context context, boolean enabled) { 
      this.context = context; 
      //create instance of connectivity manager and get system connectivity service 
       final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       try { 
        //create instance of class and get name of connectivity manager system service class 
        Class conmanClass = Class.forName(conman.getClass().getName()); 
        //create instance of field and get mService Declared field 
        final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); 
        //Attempt to set the value of the accessible flag to true 
        iConnectivityManagerField.setAccessible(true); 
        //create instance of object and get the value of field conman 
        final Object iConnectivityManager = iConnectivityManagerField.get(conman); 
        //create instance of class and get the name of iConnectivityManager field 
        final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); 
        //create instance of method and get declared method and type 
        final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled",Boolean.TYPE); 
        //Attempt to set the value of the accessible flag to true 
        setMobileDataEnabledMethod.setAccessible(true); 
        //dynamically invoke the iConnectivityManager object according to your need (true/false) 
        setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled); 
        //Thread.sleep(1000L); 
       } catch (ClassNotFoundException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (NoSuchFieldException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalAccessException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (NoSuchMethodException e) { 
        Log.d("POST", "Method not found"); 
        e.printStackTrace(); 
       } catch (InvocationTargetException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 

     // below method returns true if mobile data is on and vice versa 
     public boolean mobileDataEnabled(Context context){ 
       boolean mobileDataEnabled = false; // Assume disabled 
       ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       try { 
        Class cmClass = Class.forName(cm.getClass().getName()); 
        Method method = cmClass.getDeclaredMethod("getMobileDataEnabled"); 
        method.setAccessible(true); // Make the method callable 
        // get the setting for "mobile data" 
        mobileDataEnabled = (Boolean)method.invoke(cm); 
       } catch (Exception e) { 
        // Some problem accessible private API 
        // TODO do whatever error handling you want here 
       } 
       return mobileDataEnabled; 
      } 

無法弄清楚我在哪裏失去了一些東西。可有人指出我代碼中的缺失點。

錯誤:

01-03 06:18:05.549: W/System.err(5663): java.lang.NoSuchMethodException: setMobileDataEnabled [boolean] 
01-03 06:18:05.559: W/System.err(5663):  at java.lang.Class.getConstructorOrMethod(Class.java:472) 
01-03 06:18:05.559: W/System.err(5663):  at java.lang.Class.getDeclaredMethod(Class.java:640) 
01-03 06:18:05.559: W/System.err(5663):  at Core.MobileDataNetwrokHandler.setMobileDataEnabled(MobileDataNetwrokHandler.java:129) 
01-03 06:18:05.559: W/System.err(5663):  at com.test.post.MainActivity.mobileData(MainActivity.java:59) 
01-03 06:18:05.559: W/System.err(5663):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-03 06:18:05.559: W/System.err(5663):  at java.lang.reflect.Method.invoke(Method.java:515) 
01-03 06:18:05.559: W/System.err(5663):  at android.view.View$1.onClick(View.java:3818) 
01-03 06:18:05.559: W/System.err(5663):  at android.view.View.performClick(View.java:4438) 
01-03 06:18:05.559: W/System.err(5663):  at android.view.View$PerformClick.run(View.java:18439) 
+0

這是因爲該方法沒有導出,因此您無法調用它 - 即使通過反射。我猜你會遇到Android L模擬器的上述錯誤? – ChuongPham

+0

@ChuongPham對於不被導出的方法意味着什麼?你能給我發電子郵件在[email protected]嗎?我真的很想找到解決方案。 – Flyview

+0

@Flyview:我會在這裏發表我的評論,以便其他人可以閱讀,而不是將我的回覆郵寄給您。當Google工程師構建Android固件版本(例如Android L)時,該版本將導出公共方法(即'公共標識符)或私有/隱藏方法(即聲明爲「私有」和/或標記爲@隱藏標識符)。然後可以通過第三方應用程序的Refletion訪問隱藏的方法。所以,如果一個方法沒有用固件導出,那麼它就不存在了。所以,使用Reflection來調用這樣的方法將返回'NoSuchMethodException'。而已。 – ChuongPham

回答

0

要查看是否ConnectivityManager類的方法是通過反射調用,嘗試:

final Class<?> conmanClass = Class.forName(GlobalService.getConnectivityService(context).getClass().getName()); 
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); 
iConnectivityManagerField.setAccessible(true); 
final Object iConnectivityManager = iConnectivityManagerField.get(GlobalService.getConnectivityService(context)); 
final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); 
final Method[] methods = iConnectivityManagerClass.getDeclaredMethods(); 
for (final Method method : methods) { 
    if (method.toGenericString().contains("set")) { 
     Log.i("TESTING", "Method: " + method.getName()); 
    } 
} 

如果該方法不存在(例如,setMobileDataEnabled)在LogCat輸出,那麼它是而不是可調用的。

+0

什麼是GlobalService? –

+0

再次詢問:\t 什麼是GlobalService? – user2659694