Come si rileva la modalità aereo su Android?


92

Ho un codice nella mia applicazione che rileva se il Wi-Fi è connesso attivamente. Questo codice attiva una RuntimeException se la modalità aereo è abilitata. Vorrei comunque visualizzare un messaggio di errore separato quando in questa modalità. Come posso rilevare in modo affidabile se un dispositivo Android è in modalità aereo?


A seconda di come si eseguono i controlli, è bene sapere che è possibile avere sia la modalità aereo che il Wi-Fi abilitati contemporaneamente: heresthethingblog.com/2013/08/28/…
nibarius

Risposte:


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;

}

33
In Jelly Bean 4.2, questa impostazione è stata spostata in Settings.Global.
Chris Feist

1
Ciò ha prodotto risultati indeterminati quando l'ho chiamato in risposta all'intento android.intent.action.AIRPLANE_MODE, poiché il completamento del cambio di modalità richiede tempo. Controlla Intent.ACTION_AIRPLANE_MODE_CHANGEDse vuoi farlo.
Noumenon

7
Solo un suggerimento
:!

è lo stesso dei dati di rete abilitati? In caso contrario, esistono altri stati delle impostazioni per sapere se i dati sono stati abilitati dall'utente?
ransh

il compilatore dice che AIRPLANE_MODE_ON è deprecato
Jean Raymond Daher

96

Estendendo la risposta di Alex per includere il controllo della versione dell'SDK, abbiamo:

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

5
Eclipse non lo compilerà a meno che non venga aggiunto @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)prima del metodo.
Noumenon

1
Non posso farlo funzionare in Intellij. Mi occupo di 2.2, quindi ho minSdk = 8, e quindi "Android 2.2" come Project SDK ". Ciò, tuttavia, significa che il codice" Settings.Global "è rosso e non verrà compilato. Non lo faccio. Non voglio impostare 4.2 come SDK di progetto poiché potrei perdere qualcosa non disponibile in 2.2 ... questo mi fa impazzire, qual è la migliore pratica qui? Qualche idea?
Mathias

1
Cambia il tuo target SDK
Louis CAD

53

E se non vuoi sondare se la modalità aereo è attiva o meno, puoi registrare un BroadcastReceiver per l'intento SERVICE_STATE e reagire su di esso.

O nel tuo 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 in modo programmatico (tutte le versioni di 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);

E come descritto nelle altre soluzioni, puoi interrogare la modalità aereo quando il ricevitore è stato notificato e lanciare la tua eccezione.


2
nota: poiché ci sono altre notifiche SERVICE_STATE, dovrai controllare e memorizzare lo stato della modalità aereo prima di ricevere la notifica SERVICE_STATE, quindi controllarne lo stato quando ricevi la notifica dello stato del servizio, quindi confrontare i due - per sapere se la modalità aereo è effettivamente cambiata.
mattorb

11
mpstx: oppure usa: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Nappy

3
Per questa soluzione avrai bisogno dell'autorizzazione: <uses-permission android: name = "android.permission.READ_PHONE_STATE" />
Thomas Dignan,

4
Usa Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar

4
Inoltre, per ottenere se la modalità aereo è attivata o disattivata, possiamo utilizzare il valore booleano extra nell'intento che abbiamo ricevuto. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Il valore booleano isPlaneModeOnsarà truese l'utente ha attivato la modalità aereo o falsese è disattivata
Sudara

20

Quando si registra la Modalità aereo BroadcastReceiver(risposta di @saxos), penso che abbia molto senso ottenere lo stato dell'impostazione Modalità aereo subito da Intent Extrasper evitare di chiamare 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
    }
}

3
Questo è il modo più efficiente per recuperare lo stato effettivo della modalità aereo. Questo dovrebbe aumentare i voti ed essere la nuova risposta accettata. +1 per aver letto i documenti che parlano di questo intento extra di "stato". Ho provato e funziona correttamente.
Louis CAD

7

Da qui :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }

"Settings.System.AIRPLANE_MODE_ON" è lo stesso dei dati di rete abilitati? In caso contrario, esistono altri stati delle impostazioni per sapere se i dati sono stati abilitati dall'utente? -
ransh


5

per sbarazzarsi del reclamo di deprezzamento (quando si prende di mira API17 + e non ci si preoccupa troppo della compatibilità con le versioni precedenti), si deve confrontare 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);
}

quando si considera un'API inferiore:

/** 
 * @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;
    }
}

1
Settings.Global.AIRPLANE_MODE_ON Funzionerà solo per API 17+, cronaca
Joseph Casey

1
aggiunta la compatibilità con le versioni precedenti, sebbene sia quasi la stessa dell'esempio sopra ora.
Martin Zeitler

"Settings.System.AIRPLANE_MODE_ON" è lo stesso dei dati di rete abilitati? In caso contrario, esistono altri stati delle impostazioni per sapere se i dati sono stati abilitati dall'utente?
Ransh

2

In Oreo, non utilizzare la modalità aereo broadCastReceiver. è un intento implicito. è stato rimosso. Ecco la corrente elenco delle eccezioni . non è attualmente nell'elenco, quindi dovrebbe non riuscire a ricevere i dati. Consideralo morto.

come affermato da un altro utente sopra, utilizzare il codice seguente:

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

1

Ricevitore di trasmissione statica

Codice manifest:

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

Codice Java: file 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();
}

O

Ricevitore di trasmissione dinamica

Codice Java: file Java di attività

Registra il ricevitore di trasmissione sull'applicazione aperta non è necessario aggiungere codice nel manifest se esegui un'azione solo quando la tua attività si apre come controllare che la modalità aereo sia attiva o disattiva quando accedi a Internet, ecc.

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

Codice Java: file 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();
}

1

Dal livello 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;

    }

0

Ho scritto questo corso che potrebbe essere utile. Non restituisce direttamente un valore booleano per dirti se la modalità aereo è abilitata o disabilitata, ma ti avviserà quando la modalità aereo viene modificata dall'una all'altra.

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

}

Utilizzo

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

0

Ecco l'unica cosa che ha funzionato per me (API 27):

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

Dov'è il brtuo BroadcastReceiver. Credo che con le recenti modifiche alle autorizzazioni ora sia ConnectivityManager.CONNECTIVITY_ACTIONe Intent.ACTION_AIRPLANE_MODE_CHANGEDsiano necessari.


0

Da Jelly Bean (codice build 17), questo campo è stato spostato nelle impostazioni globali. Pertanto, per ottenere la migliore compatibilità e robustezza dobbiamo prenderci cura di entrambi i casi. Il seguente esempio è scritto 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
}

Nota: se non si mantiene il supporto per le versioni precedenti a Jelly Bean, è possibile omettere la clausola if.
Il valore che ottieni facendo riferimento Settings.System.AIRPLANE_MODE_ONè lo stesso di quello che trovi in ​​Globale. *

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

Questa è la versione sopra jelly bean del codice precedente.

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

-4

Puoi controllare se Internet è attivo

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

}


Il problema con il metodo sopra è che non tiene conto delle situazioni in cui altre app modificano la connettività. Esempio se un utente attiva la modalità aereo, ma un'altra app con i privilegi appropriati abilita una radio. E inoltre, supponiamo che la radio sia accesa ma poi non ci sia connessione ... in ogni caso la risposta sopra non ci dice davvero se la modalità aereo è specificamente attivata o disattivata, solo se il dispositivo ha una connessione. Due cose diverse.
logray
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.