How to disable Mobile Data on Android
Asked Answered
K

8

44

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 my mobile data connection. That seems have worked out fairly well. However, the settings are just very restricted (even on the paid versions).

As of right now I am trying to develop a much more customizable battery saving application. The main thing I am trying to do first be able to enable/disable the mobile data connection at will.

The problem is I can't find any code snippets or articles on how to do this. The only thing I have found is the following. I don't know how accurate this is, but this was all I could piece together browsing developer.android.com

ConnectivityManager cm = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);
cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "android.net.conn.CONNECTIVITY_CHANGE");

State state = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
textView.setText(state.name());

If anyone can point me to anything that could help, it would be most appreciated.

UPDATE

It appears that the HTC Evo on Sprint does not use APN settings. I tested this by downloading APNDroid and watching it not work. I then made a quick app to dump all APN entries to the screen. That yielded one result and it was for mms.

Looking at the phone info when JuiceDefender is running, I found that the GSRP network is getting turned on and off. This leaves me to believe it is possible to do it through code even though every page I find asking about this same issue says it cannot be done. The kicker is they all say to do it like APNDroid. Please someone give me some insight.

Thanks!

Kaleb answered 4/9, 2010 at 21:57 Comment(0)
M
39

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);
Macintyre answered 29/11, 2010 at 13:18 Comment(3)
This does not work on Gingerbread 2.3+: #4715750Pearlpearla
The above solution from phaniKumar also requires <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> declared in AndroidManifest.xml. Without the permission, you'll get a InvocationTargetException error thrown.Cellini
i tried the above code..its giving me java.lang.SecurityException: Neither user 10126 nor current process has android.permission.MODIFY_PHONE_STATE... When i include <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> in manifest. i am getting "Permission is only granted to system apps"..error..is there no other way that i can access this feature. ?Gillen
C
73

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

Cutter answered 22/1, 2012 at 15:35 Comment(7)
3G won't stay on when WiFi is on, in my real phone. It flashes on briefly then turns back off. How to keep it on?Pearlpearla
InvocationTargetException in 2.2.1Ker
java.lang.IllegalArgumentException: expected receiver of type android.net.IConnectivityManager$Stub$Proxy, but got java.lang.Class<android.net.IConnectivityManager$Stub$Proxy>. What can i do?Farleigh
Note this method is deprecated since Android 4.3. This will not work anymore.Prevot
So which method should be used for turn on mobile data for OS version 4.3?Keloid
Is there a reason why setMobileDataEnabled is invoked on private mService field and not using ConnectivityManager directly? I.e pastebin.com/tjNin7yR ?Amourpropre
can u provice some way in android 5+Plasticine
M
39

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);
Macintyre answered 29/11, 2010 at 13:18 Comment(3)
This does not work on Gingerbread 2.3+: #4715750Pearlpearla
The above solution from phaniKumar also requires <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> declared in AndroidManifest.xml. Without the permission, you'll get a InvocationTargetException error thrown.Cellini
i tried the above code..its giving me java.lang.SecurityException: Neither user 10126 nor current process has android.permission.MODIFY_PHONE_STATE... When i include <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> in manifest. i am getting "Permission is only granted to system apps"..error..is there no other way that i can access this feature. ?Gillen
U
4

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.

Underplay answered 18/3, 2011 at 22:8 Comment(0)
T
3

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.

Transposition answered 5/9, 2010 at 15:41 Comment(2)
Thanks a lot. Looking at the code for APNDroid that appears to be what is going on. Thought for sure I could just flip a bit. Oh well, hehe.Kaleb
Blast! Downloaded the application, it appears as though it does not work for the Evo 4G.Kaleb
S
3

Notice that "android.permission.MODIFY_PHONE_STATE" is no longer supported for Android 2.3 and up.

why 2.3 version of android does not hava android.permission.MODIFY_PHONE_STATE ? and what is the solution for this?

Stimulant answered 18/4, 2011 at 8:43 Comment(0)
H
3

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

Hartzog answered 27/6, 2012 at 11:1 Comment(0)
A
0

@Mariux: You probably forgot to add <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> to AndroidManifest.xml

Ainsworth answered 15/2, 2011 at 15:44 Comment(1)
Hey i tried all data connection permissions but that doesn't work in Android 4.0.4 Tablet..Early
D
0
    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
Disney answered 15/6, 2018 at 10:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.