How can one detect airplane mode on Android?
Asked Answered
G

13

103

I have code in my application that detects if Wi-Fi is actively connected. That code triggers a RuntimeException if airplane mode is enabled. I would like to display a separate error message when in this mode anyway. How can I reliably detect if an Android device is in airplane mode?

Gopak answered 30/11, 2010 at 22:11 Comment(1)
Depending on how you do your checks, it's good to be aware that it's possible to have both airplane mode and Wi-Fi enabled at the same time: heresthethingblog.com/2013/08/28/…Amused
D
150
/**
* Gets the state of Airplane Mode.
* 
* @param context
* @return true if enabled.
*/
private static boolean isAirplaneModeOn(Context context) {

   return Settings.System.getInt(context.getContentResolver(),
           Settings.Global.AIRPLANE_MODE_ON, 0) != 0;

}
Distinctly answered 30/11, 2010 at 22:16 Comment(5)
In Jelly Bean 4.2, this setting has moved to Settings.Global.Pichardo
This delivered indeterminate results when I called it in response to the intent android.intent.action.AIRPLANE_MODE, since the mode change takes time to complete. Check against Intent.ACTION_AIRPLANE_MODE_CHANGED if you want to do that.Pathogen
Just a hint: != 0 returns false (airplane mode is off) and == 0 returns true (airplane mode is on)Psychopathist
is it the same as network data enabled ? If not - is there other settings status to know if data was enabled by user ?Leucippus
compiler says AIRPLANE_MODE_ON is deprecatedMccrae
F
100

By extending Alex's answer to include SDK version checking we have:

/**
 * Gets the state of Airplane Mode.
 * 
 * @param context
 * @return true if enabled.
 */
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
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;
    }       
}
Furnary answered 11/6, 2013 at 17:2 Comment(3)
Eclipse won't compile this unless you add @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) before the method.Pathogen
I can't make this work in Intellij. I cater to 2.2, so i have minSdk=8, and therefor have the "Android 2.2" as a Project SDK". This, however, means that the "Settings.Global" code is red and won't compile. I don't want to set 4.2 as project SDK since i might miss something not available in 2.2... this drives me crazy, what is best practice here? Any idea?Radiolarian
Change your targetSDKNiersteiner
P
55

And if you don't want to poll if the Airplane Mode is active or not, you can register a BroadcastReceiver for the SERVICE_STATE Intent and react on it.

Either in your ApplicationManifest (pre-Android 8.0):

<receiver android:enabled="true" android:name=".ConnectivityReceiver">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE"/>
    </intent-filter>
</receiver>

or programmatically (all Android versions):

IntentFilter intentFilter = new IntentFilter("android.intent.action.AIRPLANE_MODE");

BroadcastReceiver receiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
            Log.d("AirplaneMode", "Service state changed");
      }
};

context.registerReceiver(receiver, intentFilter);

And as described in the other solutions, you can poll the airplane mode when your receiver was notified and throw your exception.

Pablopabon answered 30/11, 2010 at 22:24 Comment(7)
Interesting idea. I will keep that in mind if I decide that I need to check the status more than once. Thanks!Gopak
note: since there are other SERVICE_STATE notifications, you will have to check and store the state of airplane mode prior to receiving the SERVICE_STATE notification, and then check the state of it when receiving the service state notification, then compare the two -- to know if airplane mode actually changed.Jig
mpstx: or use: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); / <action android:name="android.intent.action.AIRPLANE_MODE" />Tripe
For this solution you will need the permission: <uses-permission android:name="android.permission.READ_PHONE_STATE"/>Cone
Last two comments was gold to me ;)Maffei
Use Intent.ACTION_AIRPLANE_MODE_CHANGEDExcavation
Also to get if the air plane mode is turned on or off, we can use the boolean extra value in the intent we received. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); The boolean isPlaneModeOn will be true if the user has turned on the plane mode or false if it is turned offVindicate
A
20

When registering the Airplane Mode BroadcastReceiver (@saxos answer) I think it makes a lot of sense to get the state of the Airplane Mode setting right away from the Intent Extras in order to avoid calling Settings.Global or Settings.System :

@Override
public void onReceive(Context context, Intent intent) {

    boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);
    if(isAirplaneModeOn){

       // handle Airplane Mode on
    } else {
       // handle Airplane Mode off
    }
}
Argentiferous answered 11/4, 2015 at 12:15 Comment(0)
P
7

From here :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }
Pedanticism answered 30/11, 2010 at 22:18 Comment(2)
Is "Settings.System.AIRPLANE_MODE_ON" the same as network data enabled ? If not - is there other settings status to know if data was enabled by user ? –Leucippus
#12807209 @LeucippusPedanticism
S
5

in order to get rid of the the depreciation complaint (when targeting API17+ and not caring too much about the backward compatibility), one has to compare with Settings.Global.AIRPLANE_MODE_ON:

/** 
 * @param Context context
 * @return boolean
**/
private static boolean isAirplaneModeOn(Context context) {
   return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0);
}

when considering lower API:

/** 
 * @param Context context
 * @return boolean
**/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressWarnings({ "deprecation" })
private static boolean isAirplaneModeOn(Context context) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1){
        /* API 17 and above */
        return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
    } else {
        /* below */
        return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
    }
}
Stanger answered 26/9, 2015 at 13:32 Comment(3)
Settings.Global.AIRPLANE_MODE_ON This will only work for API 17+, fyiNardi
added backward compatibility - while it's almost the same as the example above now.Stanger
Is "Settings.System.AIRPLANE_MODE_ON" the same as network data enabled ? If not - is there other settings status to know if data was enabled by user ?Leucippus
B
3

In Oreo please do not use the airplane mode broadCastReceiver. it is an implicit intent. it has been removed. Here is the current exceptions list. its not currently on the list so should fail to receive data. Consider it dead.

as stated by another user above use the following code:

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    @SuppressWarnings({ "deprecation" })
    public static boolean isAirplaneModeOn(Context context) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1){
        /* API 17 and above */
            return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
        } else {
        /* below */
            return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
        }
    }
Binucleate answered 29/11, 2017 at 11:34 Comment(0)
S
1

Static Broadcast Receiver

Manifest code:

<receiver android:name=".airplanemodecheck" android:enabled="true"
 android:exported="true">
  <intent-filter>
     <action android:name="android.intent.action.AIRPLANE_MODE"></action>
  </intent-filter>
</receiver>

Java code: Broadcast Receiver java file

if(Settings.System.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0)== 0)
{
  Toast.makeText(context, "AIRPLANE MODE Off", Toast.LENGTH_SHORT).show();
}
else
{
 Toast.makeText(context, "AIRPLANE MODE On", Toast.LENGTH_SHORT).show();
}

OR

Dynamic Broadcast Receiver

Java code: Activity java file

Register broadcast receiver on application open no need to add code in manifest if you take an action only when your activity open like check airplane mode is on or off when you access the internet etc

airplanemodecheck reciver;

@Override
protected void onResume() {
   super.onResume();
   IntentFilter intentFilter = new IntentFilter();
   intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
   reciver = new airplanemodecheck();
   registerReceiver(reciver, intentFilter);
}

@Override
protected void onStop() {
  super.onStop();
  unregisterReceiver(reciver);
}

Java code: Broadcast Receiver java file

if(Settings.System.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0)== 0)
{
  Toast.makeText(context, "AIRPLANE MODE Off", Toast.LENGTH_SHORT).show();
}
else
{
 Toast.makeText(context, "AIRPLANE MODE On", Toast.LENGTH_SHORT).show();
}
Sickroom answered 6/5, 2017 at 21:13 Comment(0)
G
1

From API Level - 17

/**
     * Gets the state of Airplane Mode.
     *
     * @param context
     * @return true if enabled.
     */
    private static boolean isAirplaneModeOn(Context context) {

        return Settings.Global.getInt(context.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0) != 0;

    }
Genetics answered 23/5, 2017 at 13:19 Comment(0)
L
1

Since Jelly Bean (Build Code 17), this field has been moved to Global settings. Thus, to achieve the best compatibility and robustness we have to take care of both cases. The following example is written in Kotlin.

fun isInAirplane(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        Settings.Global.getInt(
            context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0
        )
    } else {
        Settings.System.getInt(
            context.contentResolver, Settings.System.AIRPLANE_MODE_ON, 0
        )
    } != 0
}

Note: If you do not keep support for versions before Jelly Bean, you can omit the if clause.
The value that you get while referencing Settings.System.AIRPLANE_MODE_ON, is the same as the one you find under Global.*

    /**
     * @deprecated Use {@link android.provider.Settings.Global#AIRPLANE_MODE_ON} instead
     */
    @Deprecated
    public static final String AIRPLANE_MODE_ON = Global.AIRPLANE_MODE_ON;

This is the above-jelly bean version of the previous code.

fun isInAirplane(context: Context): Boolean {
    return Settings.Global.getInt(
        context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0
    ) != 0
}
Lutes answered 19/12, 2019 at 18:47 Comment(0)
U
0

I wrote this class that might be helpful. It doesn't directly return a boolean to tell you if Airplane Mode is enabled or disabled, but it will notify you when Airplane Mode is changed from one to the other.

public abstract class AirplaneModeReceiver extends BroadcastReceiver {

    private Context context;

    /**
     * Initialize tihe reciever with a Context object.
     * @param context
     */
    public AirplaneModeReceiver(Context context) {
        this.context = context;
    }

    /**
     * Receiver for airplane mode status updates.
     *
     * @param context
     * @param intent
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        if(Settings.System.getInt(
                context.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0
        ) == 0) {
            airplaneModeChanged(false);
        } else {
            airplaneModeChanged(true);
        }
    }

    /**
     * Used to register the airplane mode reciever.
     */
    public void register() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        context.registerReceiver(this, intentFilter);
    }

    /**
     * Used to unregister the airplane mode reciever.
     */
    public void unregister() {
        context.unregisterReceiver(this);
    }

    /**
     * Called when airplane mode is changed.
     *
     * @param enabled
     */
    public abstract void airplaneModeChanged(boolean enabled);

}

Usage

// Create an AirplaneModeReceiver
AirplaneModeReceiver airplaneModeReceiver;

@Override
protected void onResume()
{
    super.onResume();

    // Initialize the AirplaneModeReceiver in your onResume function
    // passing it a context and overriding the callback function
    airplaneModeReceiver = new AirplaneModeReceiver(this) {
        @Override
        public void airplaneModeChanged(boolean enabled) {
            Log.i(
                "AirplaneModeReceiver",
                "Airplane mode changed to: " + 
                ((active) ? "ACTIVE" : "NOT ACTIVE")
            );
        }
    };

    // Register the AirplaneModeReceiver
    airplaneModeReceiver.register();
}

@Override
protected void onStop()
{
    super.onStop();

    // Unregister the AirplaneModeReceiver
    if (airplaneModeReceiver != null)
        airplaneModeReceiver.unregister();
}
Unseam answered 20/6, 2017 at 17:33 Comment(0)
J
0

Here's the only thing what worked for me (API 27):

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
this.registerReceiver(br, filter);

Where br is your BroadcastReceiver. I believe that with the recent changes in permission now both ConnectivityManager.CONNECTIVITY_ACTION and Intent.ACTION_AIRPLANE_MODE_CHANGEDare needed.

Jeanette answered 5/4, 2018 at 15:49 Comment(0)
F
-5

You could check if the internet is on

public class ConnectionDetector {

private Context _context;

public ConnectionDetector(Context context){
    this._context = context;
}

public boolean isConnectingToInternet(){
    ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
      if (connectivity != null)
      {
          NetworkInfo[] info = connectivity.getAllNetworkInfo();
          if (info != null)
              for (int i = 0; i < info.length; i++)
                  if (info[i].getState() == NetworkInfo.State.CONNECTED)
                  {
                      return true;
                  }

      }
      return false;
}

}

Foulmouthed answered 3/11, 2012 at 10:51 Comment(1)
The problem with the above method is that is does not take into account situations where other apps modify connectivity. Example if a user switches airplane mode on, but then another app with the proper privileges enables a radio. And further, lets suppose the radio is on but then there is no connection... anyhow the above answer really doesn't tell us if airplane mode specifically is on or off, just if the device has a connection. Two different things.Billon

© 2022 - 2024 — McMap. All rights reserved.