27

Did I make a mistake? It's not working.

public void airplane() {
    boolean isEnabled = Settings.System.getInt(this.getApplicationContext().getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;
    Settings.System.putInt(context.getContentResolver(),Settings.System.AIRPLANE_MODE_ON,isEnabled ? 0 : 1);
    //Settings.System.putInt(this.getApplicationContext().getContentResolver(),Settings.System.AIRPLANE_MODE_ON,isEnabled ? 0 : 1);
    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
user669046
  • 323
  • 2
  • 5
  • 13
  • 1
    Possible duplicate of [How to set the AIRPLANE_MODE_ON to "True" or ON?](http://stackoverflow.com/questions/3249245/how-to-set-the-airplane-mode-on-to-true-or-on) – Peter Mortensen Jun 05 '11 at 12:42

10 Answers10

45

This answer contains code necessary to do this. Also make sure you have the WRITE_SETTINGS permission.

Adapted from Controlling Airplane Mode:

// read the airplane mode setting
boolean isEnabled = Settings.System.getInt(
      getContentResolver(), 
      Settings.System.AIRPLANE_MODE_ON, 0) == 1;

// toggle airplane mode
Settings.System.putInt(
      getContentResolver(),
      Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0 : 1);

// Post an intent to reload
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", !isEnabled);
sendBroadcast(intent);
Community
  • 1
  • 1
Matthew Willis
  • 44,037
  • 10
  • 96
  • 87
  • 21
    This is no longer possible starting from Android 4.2 and above. – Tommie Nov 23 '12 at 16:31
  • 30
    yeah, it won't work on 4.2.x= because it now requires a WRITE_SECURE_SETTINGS permission that is only available to system apps. Thanks Google - slowly alienating us little guys. – jmroyalty Mar 02 '13 at 18:36
  • 3
    Please note that toggling airplane mode on/off is no longer possible as of Android 4.2 (Jelly Bean major release 1). This is because Google has adopted a BANDAGE / CONVENIENT solution (for themselves) to address shortcomings in Android instead of re-examining its security model. There are ways to get around this issue - e.g. like having a rooted device and/or install an app as a system app - to allow airplane mode to work. Unfortunately, this will not be something a "home user" will know how to do or WANT to do... – ChuongPham May 17 '13 at 08:51
  • 4
    The Settings.System.AIRPLANE_MODE_ON is deprecated in API level 17. Use Settings.Global.AIRPLANE_MODE_ON instead. – Nguyen Minh Binh Feb 12 '14 at 03:45
  • @ChuongPham How does it work on rooted device? does it use "adb grant" on the "write_secure_settings" permission? – android developer Sep 04 '14 at 06:37
  • @androiddeveloper: No. But if you're interested, ask your question regarding Airplane mode on rooted devices and I will answer it there. I don't think SO moderators will allow a question within a question. ;) – ChuongPham Sep 04 '14 at 11:26
  • @ChuongPham Of course it's ok... plus it's still related to the original question. of course, if it's too long, i can put it in a new question... – android developer Sep 04 '14 at 11:28
  • @androiddeveloper: Yes, please post it as a separate question and point me to the link and I'll be happy to answer it there. Thanks. – ChuongPham Sep 04 '14 at 11:30
  • 1
    In Android 5.0 when i trying to send broadcast (ACTION_AIRPLANE_MODE_CHANGED), i got a security exception. I put all requried permissions and my application is a system application. – yasinkafadar Dec 11 '14 at 06:59
  • 1
    Please may I know the functionality is working after putting below permission ? `` `` – Navas pk Feb 27 '17 at 08:03
13

The following can be used on a rooted device.

From commandline, you can toggle airplane mode on/off with the following:

ON:
settings put global airplane_mode_on 1
am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true

OFF:
settings put global airplane_mode_on 0
am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false

This works with android 4.4.2+

A.J.
  • 1,260
  • 14
  • 21
siesta
  • 1,195
  • 2
  • 12
  • 21
13

Works for all API versions.

  • switch authomaticaly for API < 17
  • open Default Activity of Airplane mode for user actions for API >= 17

no root, no system level permission!


in AndroidManifest.xml add permission:

<!--airplane mode-->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

then:

@SuppressWarnings("deprecation")
    private void initAirplanemodeBtn() {
        airplanemodeButton = (ToggleButton) findViewById(R.id.airplanemode_btn);
        airplanemodeButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (android.os.Build.VERSION.SDK_INT < 17) {
                    try {
                        // read the airplane mode setting
                        boolean isEnabled = Settings.System.getInt(
                                getContentResolver(),
                                Settings.System.AIRPLANE_MODE_ON, 0) == 1;

                        // toggle airplane mode
                        Settings.System.putInt(
                                getContentResolver(),
                                Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0 : 1);

                        // Post an intent to reload
                        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
                        intent.putExtra("state", !isEnabled);
                        sendBroadcast(intent);
                    } catch (ActivityNotFoundException e) {
                        Log.e(TAG, e.getMessage());
                    }
                } else {
                    try {
                        Intent intent = new Intent(android.provider.Settings.ACTION_AIRPLANE_MODE_SETTINGS);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    } catch (ActivityNotFoundException e) {
                        try {
                            Intent intent = new Intent("android.settings.WIRELESS_SETTINGS");
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        } catch (ActivityNotFoundException ex) {
                            Toast.makeText(buttonView.getContext(), R.string.not_able_set_airplane, Toast.LENGTH_SHORT).show();
                        }
                    }
                }

            }
        });
    }
Yuliia Ashomok
  • 7,177
  • 1
  • 53
  • 59
  • 1
    +1 I think that is the way that google wants us to do this: send user to the correct settings page and let themselves do the setting - if they are not just too ignorant to do this ;) A promt (like a dialog with text explaining what to do and an "OK" and "Not now" button) would be adviced though – FrankKrumnow Nov 30 '17 at 14:08
  • @FrankKrumnow Is the given permission applicable for non-system apps? I am getting the warning. – Vivek Pratap Singh Dec 13 '19 at 07:09
  • On Android 8 onward the permission to write settints is itself a (revokable) runtime permission. Meaning you will not get it right away. But it can be set by the user. The answer how to check and where to send the user to is here: [stackoverflow](stackoverflow.com/questions/32083410/cant-get-write-settings-permission) – FrankKrumnow Jan 20 '20 at 12:38
11

Note: it was pointed out by NarendraR that this is not working on the latest version.

I think "Settings.System.AIRPLANE_MODE_ON" is deprecated, Im using:

public class AirplaneModeService {
    public boolean run(Context context) {
        boolean isEnabled = isAirplaneModeOn(context);
        // Toggle airplane mode.
        setSettings(context, isEnabled?1:0);
        // Post an intent to reload.
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", !isEnabled);
        context.sendBroadcast(intent);
        return true;
    }
    public static boolean isAirplaneModeOn(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return Settings.System.getInt(context.getContentResolver(), 
                    Settings.System.AIRPLANE_MODE_ON, 0) != 0;          
        } else {
            return Settings.Global.getInt(context.getContentResolver(), 
                    Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
        }       
    }
    public static void setSettings(Context context, int value) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Settings.System.putInt(
                      context.getContentResolver(),
                      Settings.System.AIRPLANE_MODE_ON, value);
        } else {
            Settings.Global.putInt(
                      context.getContentResolver(),
                      Settings.Global.AIRPLANE_MODE_ON, value);
        }       
    }
}

I hope this help someone.

cesaregb
  • 735
  • 1
  • 10
  • 27
  • 4
    The `setSettings` function won't work on Jelly Bean: `Settings.Global` is read only. – eggyal May 12 '14 at 20:58
  • 1
    This requires **android.permission.WRITE_SECURE_SETTINGS**, which is not available to 3rd party applications. See this [link](http://stackoverflow.com/questions/13045283/write-secure-settings-permission-error-even-when-added-in-manifest) – Marky0 Jun 01 '15 at 19:04
  • Thanks @NarendraR I just updated the post with your comment. – cesaregb Sep 18 '19 at 15:54
5

As @eggyal mentioned toggling Airplane Mode cannot be done from version 4.2 and up.

But what we can do is turn each of the wireless services:

Wifi can be controlled using WifiService ~ getSystemService(Context.WIFI_SERVICE). Bluetooth can be controlled using BluetoothAdapter- getSystemService(Context.BLUETOOTH_SERVICE).

After some research I found that using Java Reflection you can still control the Android Radios (Wifi, Network, Bluetooth) what Airplane Mode basically does is toggle the state of Bluetooth, Wifi and Networks.

So by controlling the Radios you can in effect create your own Airplane Mode.

WARNING: Using Reflection might fail on some devices (depends on manufacturer implementation of the classes).

This sample code toggles Mobile Network:

private void setMobileRadioEnabled(boolean enabled) {
    try {
        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 setRadio = iConnectivityManagerClass.getDeclaredMethod("setRadio", Integer.TYPE ,  Boolean.TYPE);
        setRadio.setAccessible(true);
        for (NetworkInfo networkInfo : conman.getAllNetworkInfo()) {
            if(isNetworkTypeMobile(networkInfo.getType())) {
                setRadio.invoke(iConnectivityManager, networkInfo.getType(), enabled);
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "Opss...", e);
    }
}

public static boolean isNetworkTypeMobile(int networkType) {
    switch (networkType) {
        case ConnectivityManager.TYPE_MOBILE:
        case ConnectivityManager.TYPE_MOBILE_MMS:
        case ConnectivityManager.TYPE_MOBILE_SUPL:
        case ConnectivityManager.TYPE_MOBILE_DUN:
        case ConnectivityManager.TYPE_MOBILE_HIPRI:
        case 10:
        case 11:
        case 12:
        case 14:
            return true;
        default:
            return false;
    }
}
Raanan
  • 4,664
  • 25
  • 45
4

here before every settings use android.provider like this :

public class MainActivity extends Activity implements OnClickListener {

    Button air;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        air = (Button) findViewById(R.id.button1);
        air.setOnClickListener(this);
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        // read the airplane mode setting
        boolean isEnabled = android.provider.Settings.System.getInt(
              getContentResolver(), 
              android.provider.Settings.System.AIRPLANE_MODE_ON, 0) == 1;

        // toggle airplane mode
        android.provider.Settings.System.putInt(
              getContentResolver(),
              android.provider.Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0 : 1);

        // Post an intent to reload
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", !isEnabled);
        sendBroadcast(intent);

    }

}
ROR
  • 283
  • 3
  • 29
4

After lollipop, you can use below method, but it is hidden api and your application needs system level permission

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

ConnectivityManager mgr =  (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
        mgr.setAirplaneMode(true); 
yasinkafadar
  • 219
  • 1
  • 12
  • available in kitkat + – sean loyola Mar 20 '15 at 19:06
  • No such method exist its showing error in Android studio "mgr.setAirplaneMode(true);" – Sanjeev Jul 15 '15 at 17:18
  • This method can be use only by system app,if your application is installed, obliviously,have to achieve by reflection `ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); try { if(mgr != null) { Method airPlane = ConnMgr.getClass().getDeclaredMethod("setAirplaneMode", boolean.class); if(null != aiPlane) { airPlane.invoke(mgr, !isEnabled); } } } catch` – Navas pk Feb 27 '17 at 09:23
3

Note that, as documented under Android 4.2 APIs (emphasis added):

New Global Settings

The system settings have been updated to support multiple users with the addition of Settings.Global. This collection of settings is similar to Settings.Secure settings because they are read-only, but applies globally across all user spaces on the device.

Several existing settings were relocated here from either Settings.System or Settings.Secure. If your app is currently making changes to settings previously defined in Settings.System (such as AIRPLANE_MODE_ON), then you should expect that doing so will no longer work on a device running Android 4.2 or higher if those settings were moved to Settings.Global. You can continue to read settings that are in Settings.Global, but because the settings are no longer considered safe for apps to change, attempting to do so will fail silently and the system will write a warning to the system log when running your app on Android 4.2 or higher.

eggyal
  • 113,121
  • 18
  • 188
  • 221
1

This one works for me

public static boolean isAirplaneModeOn() {
    return Settings.System.getInt(mContext.getContentResolver(),
            Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}

public static void setAirPlaneMode(boolean airplaneMode) {
    Logger.d(LOG_TAG + "setAirPlaneMode airplaneMode: " + airplaneMode) ;
    int state = airplaneMode ? 1 : 0;
    Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
                             state);
    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    intent.putExtra("state", state);
    mContext.sendBroadcast(intent);
}

But you need system permissions though

<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
Deepu
  • 578
  • 6
  • 12
-1

I found this workaround for 17+ if you want to shut off the internet this will work.

permission

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

method

@SuppressWarnings({ "unchecked", "rawtypes" })
private void setMobileDataEnabled(boolean state) {
    try {
        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, state);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Xjasz
  • 1,230
  • 1
  • 9
  • 21