Toggle airplane mode in Android
Asked Answered
C

10

32

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);
}
Cellulose answered 4/4, 2011 at 2:0 Comment(2)
Possible duplicate of How to set the AIRPLANE_MODE_ON to "True" or ON?Thinia
Does this answer your question? How to set the AIRPLANE_MODE_ON to "True" or ON?Danais
Q
48

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);
Quirinal answered 4/4, 2011 at 2:12 Comment(11)
This is no longer possible starting from Android 4.2 and above.Herder
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.Eglantine
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...Ichnite
The Settings.System.AIRPLANE_MODE_ON is deprecated in API level 17. Use Settings.Global.AIRPLANE_MODE_ON instead.Forfeiture
@Ichnite How does it work on rooted device? does it use "adb grant" on the "write_secure_settings" permission?Randers
@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. ;)Ichnite
@Ichnite 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...Randers
@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.Ichnite
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.Briscoe
Please may I know the functionality is working after putting below permission ? <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS"/>Disputation
@Briscoe Your app needs to be a persistent app, or have a whitelisted UserId (at least for now). Go to android.googlesource.com/platform/frameworks/base/+/master/… and search for "Permission Denial: not allowed to send broadcast".Kanaka
A
16

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

            }
        });
    }
Amos answered 11/6, 2016 at 10:42 Comment(3)
+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 thoughIncomputable
@Incomputable Is the given permission applicable for non-system apps? I am getting the warning.Airdrop
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](https://mcmap.net/q/223936/-can-39-t-get-write_settings-permission)Incomputable
L
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+

Loyal answered 16/7, 2014 at 15:46 Comment(3)
Working on 4.2.2 here. Very helpful!Bernita
@Loyal Working on 4.3Nihi
Working on android 5. @Michal, are you executing this as root? It needs to be executed as root from android 4.2 onwards.Finnish
O
12

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.

Oriya answered 3/8, 2013 at 19:11 Comment(3)
The setSettings function won't work on Jelly Bean: Settings.Global is read only.Enschede
This requires android.permission.WRITE_SECURE_SETTINGS, which is not available to 3rd party applications. See this linkBlockhead
Thanks @NarendraR I just updated the post with your comment.Oriya
C
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;
    }
}
Chapeau answered 16/7, 2014 at 12:12 Comment(1)
Not working for Naugat. Throwing exception NoSuchMethodException setRadioQuiteri
G
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);

    }

}
Gamete answered 18/3, 2014 at 23:33 Comment(1)
have you checked this with new versions of Android? Which permission is required to achieve this?Airdrop
B
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); 
Briscoe answered 3/3, 2015 at 7:48 Comment(3)
available in kitkat +Aranyaka
No such method exist its showing error in Android studio "mgr.setAirplaneMode(true);"Nigelniger
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); } } } catchDisputation
E
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.

Enschede answered 12/5, 2014 at 20:57 Comment(0)
G
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" />
Greaten answered 20/4, 2017 at 18:52 Comment(2)
How did you make it work? how did you make your app a system app?Randolph
i worked for an OEM and that was a preloaded app in the system image.Greaten
S
-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();
    }
}
Skedaddle answered 27/4, 2015 at 6:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.