How to disable Mobile Data on Android

后端 未结 8 1847
予麋鹿
予麋鹿 2020-11-22 12:13

Quick back story before someone tells me to buy an app. =)

I just got an EVO and it chews through the battery fairly quick. I downloaded JuiceDefender to manage

相关标签:
8条回答
  • 2020-11-22 12:28

    The Dataconnection disable and enabling APIS are hidden in the SDK and not exposed to the user, this can be achived by accessing the ITelephony interface using the java reflection technique.

    here you go:

        Method dataConnSwitchmethod;
        Class telephonyManagerClass;
        Object ITelephonyStub;
        Class ITelephonyClass;
    
        TelephonyManager telephonyManager = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
    
        if(telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED){
            isEnabled = true;
        }else{
            isEnabled = false;  
        }   
    
        telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
        Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
        getITelephonyMethod.setAccessible(true);
        ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
        ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
    
        if (isEnabled) {
            dataConnSwitchmethod = ITelephonyClass
                    .getDeclaredMethod("disableDataConnectivity");
        } else {
            dataConnSwitchmethod = ITelephonyClass
                    .getDeclaredMethod("enableDataConnectivity");   
        }
        dataConnSwitchmethod.setAccessible(true);
        dataConnSwitchmethod.invoke(ITelephonyStub);
    
    0 讨论(0)
  • 2020-11-22 12:30

    I think there are two primary types of mobile data connection on an android device: WiFi and 3G/HSDPA/etc.

    And afaik you should be able to disable WiFi programmatically, but I think the 3G/HSDPA/etc connections can only be disabled by changing the APN's name. The reason I'm saying this is because the popular application APNDroid does it that way.

    0 讨论(0)
  • 2020-11-22 12:30
        final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        final Class conmanClass = Class.forName(conman.getClass().getName());
        final Field connectivityManagerField = conmanClass.getDeclaredField("mService");
        connectivityManagerField.setAccessible(true);
        final Object connectivityManager = connectivityManagerField.get(conman);
        final Class connectivityManagerClass = Class.forName(connectivityManager.getClass().getName());
        final Method setMobileDataEnabledMethod = connectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
        setMobileDataEnabledMethod.setAccessible(true);
    
        setMobileDataEnabledMethod.invoke(connectivityManager, enabled); // pass true or false
    
    0 讨论(0)
  • 2020-11-22 12:32

    to add a toggle button you can use this code in addition Vladimir's Answer:

    TelephonyManager telephonyManager = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
    switch (telephonyManager.getDataState()) {
            case TelephonyManager.DATA_CONNECTED:
                setMobileDataEnabledMethod.invoke(iConnectivityManager, false);
                break;
            case TelephonyManager.DATA_DISCONNECTED:
                setMobileDataEnabledMethod.invoke(iConnectivityManager, true);
                break;
            }
    

    This reflection workaround is still working for me on android 4.0.4

    0 讨论(0)
  • 2020-11-22 12:46

    Starting from 'Gingerbread' you can use the IConnectivityManager.setMobileDataEnabled() method. It's hidden in API, but can be accessed with reflection. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/net/ConnectivityManager.java#376

    With this method you can change the system setting: 'Settings -> Wireless & network -> Mobile network settings -> Data Enabled'

    Code example:

    private void setMobileDataEnabled(Context context, boolean enabled) {
        final ConnectivityManager conman = (ConnectivityManager) context.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, enabled);
    }
    

    Also you need the CHANGE_NETWORK_STATE permission.

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

    Needless to say that this approach might not work in future android versions. But I guess that applications such as '3G watchdog', 'APNdroid' or 'DataLock' work this way.


    UPDATE:
    setMobileDataEnabled method is no longer available on Lollipop

    0 讨论(0)
  • 2020-11-22 12:47

    Switching the mobile data net connectivity by changing the APN's name doesn't work well any more since Gingerbread. And while the reflection code is probably the right way to do the trick, it won't work, because the application needs the android.permission.MODIFY_PHONE_STATE permission as explained by Alex P. Otherwise you get this nasty exception:

    03-18 21:54:55.074: WARN/System.err(1851): java.lang.reflect.InvocationTargetException
    (...)
    03-18 21:54:55.263: WARN/System.err(1851): Caused by: java.lang.SecurityException: Neither user 10037 nor current process has android.permission.MODIFY_PHONE_STATE.
    (...)
    03-18 21:54:55.303: WARN/System.err(1851):     at com.android.internal.telephony.ITelephony$Stub$Proxy.disableDataConnectivity(ITelephony.java:888)
    

    Unfortunately, you cannot set this permission, because it is a level 3 permission not allowed for applications:

    03-18 21:48:39.334: WARN/PackageManager(75): Not granting permission android.permission.MODIFY_PHONE_STATE to package XXX (protectionLevel=3 flags=0x8be46)
    

    I don't suppose anyone has a way to override the permission grant suppression other than by using own firmware.

    0 讨论(0)
提交回复
热议问题