反射调用setMobileDataEnabled方法设置移动数据网络失败

来源:互联网 发布:bs公式推导过程 知乎 编辑:程序博客网 时间:2024/04/29 17:28
Android编程在代码中打开移动网络,网上好多人都说这种方法可以,但是我用的时候就报错了:


java.lang.NoSuchMethodException: setMobileDataEnabled [boolean]
    at java.lang.Class.getConstructorOrMethod(Class.java:472)
    at java.lang.Class.getDeclaredMethod(Class.java:640)
    at cn.basewin.pos.SystemSetActivity$override.toggleMobileData(SystemSetActivity.java:184)
    at cn.basewin.pos.SystemSetActivity$override.onClick(SystemSetActivity.java:143)
    at cn.basewin.pos.SystemSetActivity$override.access$dispatch(SystemSetActivity.java)
    at cn.basewin.pos.SystemSetActivity.onClick(SystemSetActivity.java:0)
    at android.view.View.performClick(View.java:4438)
    at android.widget.CompoundButton.performClick(CompoundButton.java:100)
    at android.view.View$PerformClick.run(View.java:18439)
    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:5069)
    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:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
    at dalvik.system.NativeStart.main(Native Method)



/**
     * 移动网络开关
     */
    private void toggleMobileData(Context context, boolean enabled) {
        ConnectivityManager conMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        Class<?> conMgrClass = null; // ConnectivityManager类
        Field iConMgrField = null; // ConnectivityManager类中的字段
        Object iConMgr = null; // IConnectivityManager类的引用
        Class<?> iConMgrClass = null; // IConnectivityManager类
        Method setMobileDataEnabledMethod = null; // setMobileDataEnabled方法
        try {
            // 取得ConnectivityManager类
            conMgrClass = Class.forName(conMgr.getClass().getName());
            // 取得ConnectivityManager类中的对象mService
            iConMgrField = conMgrClass.getDeclaredField("mService");
            // 设置mService可访问
            iConMgrField.setAccessible(true);
            // 取得mService的实例化类IConnectivityManager
            iConMgr = iConMgrField.get(conMgr);
            // 取得IConnectivityManager类
            iConMgrClass = Class.forName(iConMgr.getClass().getName());
            // 取得IConnectivityManager类中的setMobileDataEnabled(boolean)方法
            setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
            // 设置setMobileDataEnabled方法可访问
            setMobileDataEnabledMethod.setAccessible(true);
            // 调用setMobileDataEnabled方法
            setMobileDataEnabledMethod.invoke(iConMgr, enabled);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }


从报错信息是提示找不到方法,于是我用反射的方法查看这个方法传入参数的形式,一看吓一跳,这个方法不只一个参数,需要两个参数
setMobileDataEnabled(String packageName, boolean enable)//packageName为当前包名
可能是Android的版本不同导致的setMobileDataEnabled方法改变了


所以解决方法如下:
两行红的代码分别改为:

setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod("setMobileDataEnabled",String.class,boolean.class);


setMobileDataEnabledMethod.invoke(iConMgr,getPackageName() ,enabled);



getDeclaredMethod通过传入的方法名和参数查找方法,这个写就能正常调用了!



有问题qq:1024883177

1 1
原创粉丝点击