¿Cómo se puede detectar el modo avión en Android?

92

Tengo un código en mi aplicación que detecta si Wi-Fi está conectado activamente. Ese código activa una RuntimeException si el modo avión está habilitado. De todos modos, me gustaría mostrar un mensaje de error por separado cuando esté en este modo. ¿Cómo puedo detectar de manera confiable si un dispositivo Android está en modo avión?

Sean W.
fuente
Dependiendo de cómo realice sus comprobaciones, es bueno tener en cuenta que es posible tener el modo avión y el Wi-Fi habilitados al mismo tiempo: heresthethingblog.com/2013/08/28/…
nibarius

Respuestas:

137
/**
* 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;

}
Alex Volovoy
fuente
33
En Jelly Bean 4.2, esta configuración se ha movido a Settings.Global.
Chris Feist
1
Esto arrojó resultados indeterminados cuando lo llamé en respuesta a la intención android.intent.action.AIRPLANE_MODE, ya que el cambio de modo tarda en completarse. Verifique Intent.ACTION_AIRPLANE_MODE_CHANGEDsi quiere hacer eso.
Noumenon
7
Solo una pista
:!
¿Es lo mismo que los datos de red habilitados? De lo contrario, ¿hay otros estados de configuración para saber si el usuario habilitó los datos?
ransh
El compilador dice que AIRPLANE_MODE_ON está obsoleto
Jean Raymond Daher
96

Al extender la respuesta de Alex para incluir la verificación de la versión del SDK, tenemos:

/**
 * 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;
    }       
}
Tiago
fuente
5
Eclipse no compilará esto a menos que agregue @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)antes del método.
Noumenon
1
No puedo hacer que esto funcione en Intellij. Me adapto a 2.2, así que tengo minSdk = 8 y, por lo tanto, tengo "Android 2.2" como un SDK de proyecto ". Sin embargo, esto significa que el código" Settings.Global "es rojo y no se compilará. No No quiero establecer 4.2 como SDK del proyecto ya que podría perderme algo que no está disponible en 2.2 ... esto me vuelve loco, ¿cuál es la mejor práctica aquí? ¿Alguna idea?
Mathias
1
Cambie su targetSDK
Louis CAD
54

Y si no desea sondear si el Modo Avión está activo o no, puede registrar un BroadcastReceiver para SERVICE_STATE Intent y reaccionar al respecto.

O en su 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>

o programáticamente (todas las versiones de Android):

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

Y como se describe en las otras soluciones, puede sondear el modo avión cuando se notifique a su receptor y lanzar su excepción.

saxos
fuente
2
nota: dado que hay otras notificaciones de SERVICE_STATE, tendrá que verificar y almacenar el estado del modo avión antes de recibir la notificación SERVICE_STATE, y luego verificar el estado cuando reciba la notificación del estado del servicio, luego comparar los dos - para saber si el modo avión realmente cambió.
mattorb
11
mpstx: o use: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Pañal
3
Para esta solución, necesitará el permiso: <uses-allow android: name = "android.permission.READ_PHONE_STATE" />
Thomas Dignan
4
Use Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar
4
Además, para saber si el modo avión está activado o desactivado, podemos usar el valor booleano adicional en la intención que recibimos. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); El booleano isPlaneModeOnserá truesi el usuario ha activado el modo avión o falsesi está desactivado
Sudara
20

Al registrar el modo avión BroadcastReceiver(respuesta de @saxos), creo que tiene mucho sentido obtener el estado de la configuración del modo avión de inmediato Intent Extraspara evitar llamadas Settings.Globalo 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
    }
}
eldjon
fuente
3
Ésta es la forma más eficaz de recuperar el estado real del modo avión. Esto debería obtener votos y ser la nueva respuesta aceptada. +1 por leer los documentos que hablan sobre esta intención de "estado" adicional. Probé y funciona correctamente.
Louis CAD
7

Desde aqui :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }
Preet Sangha
fuente
¿"Settings.System.AIRPLANE_MODE_ON" es lo mismo que los datos de red habilitados? De lo contrario, ¿hay otros estados de configuración para saber si el usuario habilitó los datos? -
ransh
5

Para deshacerse de la queja de depreciación (cuando se apunta a API17 + y no se preocupa demasiado por la compatibilidad con versiones anteriores), uno tiene que comparar con 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);
}

al considerar una API más baja:

/** 
 * @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;
    }
}
Martin Zeitler
fuente
1
Settings.Global.AIRPLANE_MODE_ON Esto solo funcionará para API 17+, fyi
Joseph Casey
1
se agregó compatibilidad con versiones anteriores, aunque ahora es casi igual que el ejemplo anterior.
Martin Zeitler
¿"Settings.System.AIRPLANE_MODE_ON" es lo mismo que los datos de red habilitados? De lo contrario, ¿hay otros estados de configuración para saber si el usuario habilitó los datos?
ransh
2

En Oreo, no utilice el modo avión broadCastReceiver. es una intención implícita. ha sido eliminado. Aquí está la lista de excepciones actual . no está actualmente en la lista, por lo que no debería recibir datos. Considérelo muerto.

como lo indicó otro usuario arriba, use el siguiente código:

 @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;
        }
    }
j2emanue
fuente
1

Receptor de transmisión estática

Código manifiesto:

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

Código Java: archivo java de Broadcast Receiver

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

O

Receptor de transmisión dinámica

Código Java: archivo Java de actividad

Registre el receptor de transmisión en la aplicación abierta sin necesidad de agregar código en el manifiesto si realiza una acción solo cuando su actividad se abre, como verificar que el modo de avión está encendido o apagado cuando accede a 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);
}

Código Java: archivo java de Broadcast Receiver

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();
}
Tecnologías AXN Unicode
fuente
1

Desde el nivel API - 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;

    }
Vineesh TP
fuente
0

Escribí esta clase que podría ser útil. No devuelve directamente un booleano para indicarle si el modo avión está habilitado o deshabilitado, pero le notificará cuando el modo avión cambie de uno a otro.

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

}

Uso

// 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();
}
Nathan F.
fuente
0

Esto es lo único que funcionó para mí (API 27):

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

¿Dónde brestá su BroadcastReceiver? Creo que con los cambios recientes en el permiso ahora se necesitan ambos ConnectivityManager.CONNECTIVITY_ACTIONy Intent.ACTION_AIRPLANE_MODE_CHANGED.

Gus
fuente
0

Desde Jelly Bean (código de compilación 17), este campo se ha movido a la configuración global. Así, para conseguir la mejor compatibilidad y robustez tenemos que ocuparnos de ambos casos. El siguiente ejemplo está escrito en 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
}

Nota: Si no mantiene el soporte para versiones anteriores a Jelly Bean, puede omitir la cláusula if.
El valor que obtiene al hacer referencia Settings.System.AIRPLANE_MODE_ONes el mismo que encuentra en Global. *

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

Esta es la versión anterior del código anterior.

fun isInAirplane(context: Context): Boolean {
    return Settings.Global.getInt(
        context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0
    ) != 0
}
Andrea Cioccarelli
fuente
-4

Puede comprobar si Internet está encendido

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

}

MoschDev
fuente
El problema con el método anterior es que no tiene en cuenta situaciones en las que otras aplicaciones modifican la conectividad. Ejemplo si un usuario activa el modo avión, pero luego otra aplicación con los privilegios adecuados habilita una radio. Y además, supongamos que la radio está encendida pero luego no hay conexión ... de todos modos, la respuesta anterior realmente no nos dice si el modo avión específicamente está encendido o apagado, solo si el dispositivo tiene una conexión. Dos cosas distintas.
logray