1

In my app I am having two toggle buttons, one for wifi and the other one for Mobile Data. When applications start, if my WiFi is on, toggle button is ON. But, if my Mobile Data is ON, toggle button doesn't show that, it's still grey(no matter what's happening with WiFi). When I press it, it becomes green and my Mobile Data is still ON... Any idea why?

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();
                }
            }

        });

And the class for Mobile Data

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);
}
Aleksandar Panic
  • 165
  • 1
  • 2
  • 14

2 Answers2

1

Why are you using reflection for this? If I was Google, which I'm not, I would put protections in the API so that people can't use reflection to F with the low level systems. Allowing reflection for this kind of stuff would make the system so vulnerable that no one would ever be able to use it.

If you look at the source tree you will see that IConnectivityManager isn't even a java class, it's an aidl resource, meaning it's probably backed by native code (C/C++) so I don't know that reflection would ever work there.

If you look at the setMobileDataEnabled method that you're trying to access, it's public in the ConnectivityManager source.

/**
 * 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) {
    }
}

I haven't used it, but why try to hack down to the underlying services and not just use that?

rharter
  • 2,495
  • 18
  • 34
0

You can try this, it works for me on 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();
}

Also, in AndroidManifest.xml, you need to add

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
Community
  • 1
  • 1
PageNotFound
  • 2,320
  • 2
  • 23
  • 34