user669046
user669046

Reputation: 373

Toggle airplane mode in Android

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

Upvotes: 32

Views: 81558

Answers (10)

cesaregb
cesaregb

Reputation: 765

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.

Upvotes: 12

Deepu
Deepu

Reputation: 608

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" />

Upvotes: 1

Yuliia Ashomok
Yuliia Ashomok

Reputation: 8598

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

            }
        });
    }

Upvotes: 16

Raanan
Raanan

Reputation: 4785

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

Upvotes: 5

Xjasz
Xjasz

Reputation: 1248

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

Upvotes: -1

siesta
siesta

Reputation: 1415

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+

Upvotes: 13

yasinkafadar
yasinkafadar

Reputation: 229

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

Upvotes: 4

eggyal
eggyal

Reputation: 126025

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.

Upvotes: 3

ROR
ROR

Reputation: 271

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

    }

}

Upvotes: 4

Matthew
Matthew

Reputation: 44919

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

Upvotes: 48

Related Questions