Comment détecter le mode avion sur Android?

92

J'ai un code dans mon application qui détecte si le Wi-Fi est activement connecté. Ce code déclenche une RuntimeException si le mode avion est activé. Je voudrais quand même afficher un message d'erreur séparé dans ce mode. Comment puis-je détecter de manière fiable si un appareil Android est en mode avion?

Sean W.
la source
En fonction de la façon dont vous effectuez vos vérifications, il est bon de savoir qu'il est possible d' activer
simultanément le

Réponses:

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
la source
33
Dans Jelly Bean 4.2, ce paramètre est passé à Settings.Global.
Chris Feist
1
Cela a donné des résultats indéterminés lorsque je l'ai appelé en réponse à l'intention android.intent.action.AIRPLANE_MODE, car le changement de mode prend du temps. Vérifiez Intent.ACTION_AIRPLANE_MODE_CHANGEDsi vous voulez faire cela.
Noumenon
7
Juste un indice:! = 0 renvoie false (le mode avion est désactivé) et == 0 renvoie true (le mode avion est activé)
jfmg
est-ce la même chose que les données réseau activées? Sinon, y a-t-il d'autres états de paramètres pour savoir si les données ont été activées par l'utilisateur?
ransh le
compilateur dit AIRPLANE_MODE_ON est obsolète
Jean Raymond Daher
96

En étendant la réponse d'Alex pour inclure la vérification de la version du SDK, nous avons:

/**
 * 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
la source
5
Eclipse ne compilera pas ceci à moins que vous ne l'ajoutiez @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)avant la méthode.
Noumenon
1
Je ne peux pas faire fonctionner cela dans Intellij. Je réponds à 2.2, donc j'ai minSdk = 8, et pour cela j'ai le "Android 2.2" comme SDK de projet ". Cela, cependant, signifie que le code" Settings.Global "est rouge et ne compile pas. Je ne Je veux définir 4.2 comme SDK de projet car je pourrais manquer quelque chose qui n'est pas disponible dans la version 2.2 ... cela me rend fou, quelle est la meilleure pratique ici? Une idée?
Mathias
1
Changer votre cibleSDK
Louis CAD
54

Et si vous ne voulez pas interroger si le mode avion est actif ou non, vous pouvez enregistrer un BroadcastReceiver pour l'intention SERVICE_STATE et y réagir.

Soit dans votre ApplicationManifest (pré-Android 8.0):

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

ou par programmation (toutes les versions d'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);

Et comme décrit dans les autres solutions, vous pouvez interroger le mode avion lorsque votre récepteur a été notifié et lever votre exception.

saxos
la source
2
Remarque: comme il existe d'autres notifications SERVICE_STATE, vous devrez vérifier et stocker l'état du mode avion avant de recevoir la notification SERVICE_STATE, puis en vérifier l'état lors de la réception de la notification d'état du service, puis comparer les deux - pour savoir si le mode avion a réellement changé.
mattorb
11
mpstx: ou utilisez: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Nappy
3
Pour cette solution, vous aurez besoin de l'autorisation: <uses-permission android: name = "android.permission.READ_PHONE_STATE" />
Thomas Dignan
4
Use Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar
4
Aussi pour savoir si le mode avion est activé ou désactivé, nous pouvons utiliser la valeur supplémentaire booléenne dans l'intention que nous avons reçue. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Le booléen isPlaneModeOnsera truesi l'utilisateur a activé le mode avion ou falses'il est désactivé
Sudara
20

Lors de l'enregistrement du mode avion BroadcastReceiver(réponse @saxos), je pense qu'il est très judicieux d'obtenir l'état du paramètre Mode avion immédiatement Intent Extraspour éviter d'appeler Settings.Globalou 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
la source
3
C'est le moyen le plus efficace de récupérer l'état réel du mode avion. Cela devrait susciter des votes et être la nouvelle réponse acceptée. +1 pour lire les documents qui parlent de cette intention "état" supplémentaire. J'ai testé et cela fonctionne correctement.
Louis CAD
7

D' ici :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }
Preet Sangha
la source
"Settings.System.AIRPLANE_MODE_ON" est-il le même que les données réseau activées? Sinon, y a-t-il d'autres états de paramètres pour savoir si les données ont été activées par l'utilisateur? -
ransh le
5

afin de se débarrasser de la plainte de dépréciation (lorsque vous ciblez l'API17 + et ne vous souciez pas trop de la compatibilité descendante), il faut comparer avec 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);
}

lorsque vous envisagez une API inférieure:

/** 
 * @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
la source
1
Settings.Global.AIRPLANE_MODE_ON Cela ne fonctionnera que pour l'API 17+, fyi
Joseph Casey
1
ajout de la compatibilité descendante - alors que c'est presque le même que l'exemple ci-dessus maintenant.
Martin Zeitler
"Settings.System.AIRPLANE_MODE_ON" est-il le même que les données réseau activées? Sinon, y a-t-il d'autres états de paramètres pour savoir si les données ont été activées par l'utilisateur?
ransh le
2

Dans Oreo, veuillez ne pas utiliser le mode avion broadCastReceiver. c'est une intention implicite. il a été supprimé. Voici la liste actuelle des exceptions . il n'est pas actuellement sur la liste et ne devrait donc pas recevoir de données. Considérez-le comme mort.

comme indiqué par un autre utilisateur ci-dessus, utilisez le code suivant:

 @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
la source
1

Récepteur de diffusion statique

Code manifeste:

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

Code Java: fichier java 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();
}

OU

Récepteur de diffusion dynamique

Code Java: fichier java d'activité

Enregistrez le récepteur de diffusion sur l'application ouverte pas besoin d'ajouter du code dans le manifeste si vous n'effectuez une action que lorsque votre activité est ouverte, comme vérifier que le mode avion est activé ou désactivé lorsque vous accédez à 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);
}

Code Java: fichier java 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();
}
Technologies Unicode AXN
la source
1

À partir du niveau 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
la source
0

J'ai écrit ce cours qui pourrait être utile. Il ne renvoie pas directement un booléen pour vous dire si le mode avion est activé ou désactivé, mais il vous avertit lorsque le mode avion est changé de l'un à l'autre.

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

Voici la seule chose qui a fonctionné pour moi (API 27):

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

brest votre BroadcastReceiver. Je crois que les changements récents dans l' autorisation maintenant à la fois ConnectivityManager.CONNECTIVITY_ACTIONet Intent.ACTION_AIRPLANE_MODE_CHANGEDsont nécessaires.

Gus
la source
0

Depuis Jelly Bean (Build Code 17), ce champ a été déplacé vers les paramètres globaux. Ainsi, pour obtenir la meilleure compatibilité et robustesse, nous devons prendre en charge les deux cas. L'exemple suivant est écrit 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
}

Remarque: Si vous ne conservez pas la prise en charge des versions antérieures à Jelly Bean, vous pouvez omettre la clause if.
La valeur que vous obtenez lors du référencement Settings.System.AIRPLANE_MODE_ONest la même que celle que vous trouvez sous Global. *

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

Il s'agit de la version ci-dessus du code précédent.

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

Vous pouvez vérifier si Internet est activé

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
la source
Le problème avec la méthode ci-dessus est qu'elle ne prend pas en compte les situations où d'autres applications modifient la connectivité. Exemple si un utilisateur active le mode avion, mais qu'une autre application avec les privilèges appropriés active une radio. Et de plus, supposons que la radio soit allumée mais qu'il n'y ait pas de connexion ... de toute façon, la réponse ci-dessus ne nous dit vraiment pas si le mode avion est spécifiquement activé ou désactivé, juste si l'appareil a une connexion. Deux choses différentes.
logray