1

在我的应用程序中,我有两个切换按钮,一个用于 wifi,另一个用于移动数据。当应用程序启动时,如果我的 WiFi 处于打开状态,则切换按钮处于打开状态。但是,如果我的移动数据打开,切换按钮不会显示,它仍然是灰色的(无论 WiFi 发生了什么)。当我按下它时,它变成绿色并且我的移动数据仍然处于开启状态......知道为什么吗?

gprs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                try {
                    turnData(isChecked);  //Klasa za ukljucivanje gprsa
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        });

移动数据类

void turnData(boolean ON) throws Exception {
Log.i("version:", "Found Gingerbread+");
       final ConnectivityManager conman = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
       final Class conmanClass = Class.forName(conman.getClass().getName());
       final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
       iConnectivityManagerField.setAccessible(true);
       final Object iConnectivityManager = iConnectivityManagerField.get(conman);
       final Class iConnectivityManagerClass =  Class.forName(iConnectivityManager.getClass().getName());
       final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
       setMobileDataEnabledMethod.setAccessible(true);
       setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
}
4

2 回答 2

1

你为什么要为此使用反射?如果我是谷歌,我不是,我会在 API 中设置保护,这样人们就不能在低级系统中使用对 F 的反射。允许对这类东西进行反射会使系统变得如此脆弱,以至于没有人能够使用它。

如果您查看源代码树,您会发现 IConnectivityManager 甚至不是一个 java 类,它是一个辅助资源,这意味着它可能由本机代码 (C/C++) 支持,所以我不知道反射是否会在那里工作。

如果您查看setMobileDataEnabled您尝试访问的方法,它在ConnectivityManager源中是公开的。

/**
 * Sets the persisted value for enabling/disabling Mobile data.
 *
 * @param enabled Whether the user wants the mobile data connection used
 *            or not.
 * @hide
 */
public void setMobileDataEnabled(boolean enabled) {
    try {
        mService.setMobileDataEnabled(enabled);
    } catch (RemoteException e) {
    }
}

我没有使用它,但为什么要尝试破解底层服务而不只是使用它呢?

于 2013-08-07T13:41:37.540 回答
0

你可以试试这个,它在 KitKat 上对我有用。

public boolean invokeMethod(String methodName, Object[] args) throws Exception {
    ConnectivityManager mcm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    Class ownerClass = mcm.getClass();
    Class[] argsClass = null;
    if (args != null) {
        argsClass = new Class[1];
        argsClass[0] = args.getClass();
    }
    Method method = ownerClass.getMethod(methodName, argsClass);
    return (Boolean)method.invoke(mcm, args);
}

public Object invokeBooleanArgMethod(String methodName, boolean value) throws Exception {
    ConnectivityManager mcm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    Class ownerClass = mcm.getClass();
    Class[]  argsClass = new Class[1];
    argsClass[0] = boolean.class;
    Method method = ownerClass.getMethod(methodName,argsClass);
    return method.invoke(mcm, value);
}

/* use these two method like these */
Object[] arg = null;
try {
    boolean isMobileDataEnable = invokeMethod("getMobileDataEnabled", arg);
    if(!isMobileDataEnable){
        invokeBooleanArgMethod("setMobileDataEnabled", true);
    }
} catch (Exception e) {
    e.printStackTrace();
}

此外,在 中AndroidManifest.xml,您需要添加

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
于 2014-09-16T06:09:37.527 回答