在Android 4.4.2上以编程方式切换移动数据

我一直使用这个代码来以编程方式启用移动数据:

ConnectivityManager conman = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); @SuppressWarnings("rawtypes") final Class conmanClass = Class.forName(conman.getClass().getName()); final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); iConnectivityManagerField.setAccessible(true); final Object iConnectivityManager = iConnectivityManagerField.get(conman); @SuppressWarnings("rawtypes") final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); @SuppressWarnings("unchecked") final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); setMobileDataEnabledMethod.setAccessible(true); setMobileDataEnabledMethod.invoke(iConnectivityManager, true); 

这工作得很好,除了现在在Android 4.4.2,我得到这个exception:

 java.lang.NoSuchMethodException: setMobileDataEnabled [boolean] at java.lang.Class.getConstructorOrMethod(Class.java:472) at java.lang.Class.getDeclaredMethod(Class.java:640) at com.test.auto3gPro.ClasseConnessione.settaConnessione(ClasseConnessione.java:48) at com.test.auto3gPro.receiver.ScreenBroadcastReceiver.onReceive(ScreenBroadcastReceiver.java:108) at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5081) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) at dalvik.system.NativeStart.main(Native Method) 

有谁知道如何解决这一问题?

Related of "在Android 4.4.2上以编程方式切换移动数据"

如果你正在使用cyanogenmod,setMobileDataEnabled(boolean)方法在setMobileDataEnabled(String,boolean)中被改变…就像你在这行代码中看到的一样 。

所以你可以使用标准的方法,然后在NoSuchMethodException catch块中尝试像这样的“cyanogenmod”方式:

 Class[] cArg = new Class[2]; cArg[0] = String.class; cArg[1] = Boolean.TYPE; Method setMobileDataEnabledMethod; setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", cArg); Object[] pArg = new Object[2]; pArg[0] = getContext().getPackageName(); pArg[1] = true; setMobileDataEnabledMethod.setAccessible(true); setMobileDataEnabledMethod.invoke(iConnectivityManager, pArg); 

我不知道其他mod是否受到影响。

这在Android 4.4.4版本2上适用于我

 public void onClick(View view){ ConnectivityManager dataManager; dataManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); Method dataMtd = null; try { dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } dataMtd.setAccessible(true); try { dataMtd.invoke(dataManager, true); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

reflection仍然在最新版本的作品

看起来你已经发现使用reflection来玩类的内部的危险。 我相信这一点没有公开,因为启用移动数据应该由用户而不是应用程序来完成。 如果你真的想继续这样做,你将不得不查看Android的新源文件来找出你可以在运行时发现的未暴露的接口,并通过检查API级别来防止这些代码的调用。 我不认为我会build议以编程方式更改移动数据。

Android L已经移除了setMobileDataEnabled

用这个代替:

 TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); Method methodSet = Class.forName(tm.getClass().getName()).getDeclaredMethod( "setDataEnabled", Boolean.TYPE); methodSet.invoke(tm,true); 

确保你的清单上有这个权限:

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

此权限仅适用于系统应用程序