46

Although this is a "duplicate", the current answers are out of date and, mostly, no longer apply. I thought it would be good to provide an updated resource here, if possible, to save people time, as I have just done, researching this issue.

I've been googling around to see the latest information on being able to enable and disable mobile data from within an app (if wifi is not available).

This is one of the latest things I can find:
Did you know you can no longer Disable/Enable Data on lollipop from a widget?

There is an answer to that, I quote:

There was never an API for it. Developers were using a workaround by calling the method via Reflections. All Google did was close this "exploit".

There is also this discussion:

Replacement for setMobileDataEnabled() api
Which is Feb 2015.

There are these questions here:

How to disable Mobile Data on Android

This was asked in 2010 and the latest answer was updated with a one liner on Dec 2014.

Enable/disable data connection in android programmatically

And this, the accepted answer in 2012.

What's the latest on this issue?

Can it still be done?

Community
  • 1
  • 1
  • 1
    http://stackoverflow.com/questions/26539445/the-setmobiledataenabled-method-is-no-longer-callable-as-of-android-l-and-later – CommonsWare Jul 11 '15 at 10:58
  • 3
    @Heyyou Doesn't look like it's possible any more. At best you could detect whether it was on or not and then prompt the user to turn it on by taking them to the settings page – Nyx Jul 13 '15 at 10:46
  • http://stackoverflow.com/a/27198925/2378691 Go to update 3 on this answer. It helps to turn on/off mobile data on lollipop. – Ido Naveh Jul 13 '15 at 18:02

5 Answers5

20

It wont work on non-rooted phone as they added MODIFY_PHONE_STATE permission check. This permission is only given to system or signature apps refer-here.

Check the code below from PhoneInterfaceManager:

   @Override
   public void setDataEnabled(boolean enable) {
       enforceModifyPermission();
       mPhone.setDataEnabled(enable);
   }
   private void enforceModifyPermission() {
       mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
   }
Selman Tosun
  • 428
  • 5
  • 14
rupesh jain
  • 3,410
  • 1
  • 14
  • 22
  • @YvetteColomb i know this is old , but is this still the case? Also signature application means if it has a signed apk it will work without rooting phone? – Peter Haddad Sep 26 '17 at 10:31
  • So how a custom theme app for Notification Panel can enable the mobile data from their own designed button. They require phone, notification and accessibility permission. You can chek Power Shader app on play store. – Shubham Gupta Sep 13 '21 at 03:49
15

Unless you have a rooted phone I don't think you can enable and disable data programmatically because in order to do so we have to include MODIFY_PHONE_STATE permission which is only given to system or signature apps.

setMobileDataEnabled() method is no longer callable via reflection. It was callable since Android 2.1 (API 7) to Android 4.4 (API 19) via reflection, but as of Android 5.0 and later, even with the rooted phones, the setMobileDataEnabled() method is not callable.

Chitra Lekha
  • 281
  • 3
  • 4
13

Fast forward to the end of 2018...

The short answer is it is no longer allowed to enable/disable mobile data programmatically. Here is the solution that I use all the time.

This code opens system data usage settings screen, where the user can disable mobile data manually.

public void enableDisableMobileData() {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName(
        "com.android.settings", 
        "com.android.settings.Settings$DataUsageSummaryActivity"));
    startActivity(intent);
}

EDIT 2019:

The answer above does not work starting on API 28. This is what works:

Intent intent = new Intent(Settings.ACTION_DATA_USAGE_SETTINGS);
startActivity(intent);
user1506104
  • 6,554
  • 4
  • 71
  • 89
2

None of the above worked for me, but if your device is rooted, you may use this for enabling it.

private void enableMobileData(){

        try {
            String[] cmds = {"svc data enable"};
            Process p = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }
            os.writeBytes("exit\n");
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

}

And this for disabling it:

private void disableMobileData(){

    try {
        String[] cmds = {"svc data disable"};
        Process p = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(p.getOutputStream());
        for (String tmpCmd : cmds) {
            os.writeBytes(tmpCmd + "\n");
        }
        os.writeBytes("exit\n");
        os.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }

}
0

Easy Method.

public void setMobileDataState(boolean mobileDataEnabled)
{
    try{
        ConnectivityManager dataManager;
        dataManager  = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        Method dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
        dataMtd.setAccessible(true);
        dataMtd.invoke(dataManager, mobileDataEnabled);
    }catch(Exception ex){
        //Error Code Write Here
    }
}