Wie kann man den Flugzeugmodus auf Android erkennen?

92

Ich habe Code in meiner Anwendung, der erkennt, ob Wi-Fi aktiv verbunden ist. Dieser Code löst eine RuntimeException aus, wenn der Flugzeugmodus aktiviert ist. In diesem Modus möchte ich ohnehin eine separate Fehlermeldung anzeigen. Wie kann ich zuverlässig erkennen, ob sich ein Android-Gerät im Flugzeugmodus befindet?

Sean W.
quelle
Abhängig davon, wie Sie Ihre Überprüfungen durchführen, ist es gut zu wissen, dass sowohl der Flugzeugmodus als auch Wi-Fi gleichzeitig aktiviert sein können: heresthethingblog.com/2013/08/28/…
nibarius

Antworten:

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
quelle
33
In Jelly Bean 4.2 wurde diese Einstellung verschoben Settings.Global.
Chris Feist
1
Dies lieferte unbestimmte Ergebnisse, als ich es als Reaktion auf die Absicht aufrief android.intent.action.AIRPLANE_MODE, da der Moduswechsel einige Zeit in Anspruch nimmt. Prüfen Intent.ACTION_AIRPLANE_MODE_CHANGEDSie, ob Sie das tun möchten.
Noumenon
7
Nur ein Hinweis :! = 0 gibt false zurück (Flugzeugmodus ist ausgeschaltet) und == 0 gibt true zurück (Flugzeugmodus ist eingeschaltet)
jfmg
Ist es dasselbe wie bei aktivierten Netzwerkdaten? Wenn nicht - Gibt es einen anderen Einstellungsstatus, um festzustellen, ob die Daten vom Benutzer aktiviert wurden?
Ransh
Compiler sagt, AIRPLANE_MODE_ON ist veraltet
Jean Raymond Daher
96

Durch die Erweiterung von Alex 'Antwort um die Überprüfung der SDK-Version haben wir:

/**
 * 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
quelle
5
Eclipse kompiliert dies nur, wenn Sie es @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)vor der Methode hinzufügen .
Noumenon
1
Ich kann das in Intellij nicht zum Laufen bringen. Ich kümmere mich um 2.2, also habe ich minSdk = 8 und daher das "Android 2.2" als Projekt-SDK. Dies bedeutet jedoch, dass der Code "Settings.Global" rot ist und nicht kompiliert werden kann. Ich möchte 4.2 nicht als Projekt-SDK festlegen, da ich möglicherweise etwas verpasse, das in 2.2 nicht verfügbar ist. Das macht mich verrückt. Was ist hier die beste Vorgehensweise? Irgendeine Idee?
Mathias
1
Ändern Sie Ihre targetSDK
Louis CAD
53

Und wenn Sie nicht abfragen möchten, ob der Flugzeugmodus aktiv ist oder nicht, können Sie einen BroadcastReceiver für die Absicht SERVICE_STATE registrieren und darauf reagieren.

Entweder in Ihrem ApplicationManifest (vor Android 8.0):

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

oder programmgesteuert (alle Android-Versionen):

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

Und wie in den anderen Lösungen beschrieben, können Sie den Flugzeugmodus abfragen, wenn Ihr Empfänger benachrichtigt wurde, und Ihre Ausnahme auslösen.

Saxos
quelle
2
Hinweis: Da es andere SERVICE_STATE-Benachrichtigungen gibt, müssen Sie den Status des Flugzeugmodus überprüfen und speichern, bevor Sie die SERVICE_STATE-Benachrichtigung erhalten, und dann den Status beim Empfang der Service-Statusbenachrichtigung überprüfen und dann die beiden vergleichen, um zu wissen wenn sich der Flugzeugmodus tatsächlich geändert hat.
Mattorb
11
mpstx: oder benutze: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Windel
3
Für diese Lösung benötigen Sie die Berechtigung: <Verwendungsberechtigung android: name = "android.permission.READ_PHONE_STATE" />
Thomas Dignan
4
Verwenden Sie Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar
4
Um festzustellen, ob der Flugzeugmodus ein- oder ausgeschaltet ist, können wir den booleschen Zusatzwert in der Absicht verwenden, die wir erhalten haben. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Der boolean isPlaneModeOnwird , truewenn der Benutzer auf der Ebene Modus eingeschaltet ist oder falsewenn es ausgeschaltet ist
Sudara
20

Bei der Registrierung des Flugzeugmodus BroadcastReceiver(Antwort von @saxos) halte ich es für sehr sinnvoll, den Status der Einstellung für den Flugzeugmodus sofort zu ändern Intent Extras, um einen Anruf zu vermeiden Settings.Globaloder 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
quelle
3
Dies ist der effizienteste Weg, um den tatsächlichen Status des Flugzeugmodus abzurufen. Dies sollte Stimmen erhalten und die neu akzeptierte Antwort sein. +1 zum Lesen der Dokumente, die über diese "Zustands" -Absicht extra sprechen. Ich habe getestet und es funktioniert richtig.
Louis CAD
7

Von hier aus :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }
Preet Sangha
quelle
Entspricht "Settings.System.AIRPLANE_MODE_ON" den aktivierten Netzwerkdaten? Wenn nicht - Gibt es einen anderen Einstellungsstatus, um festzustellen, ob die Daten vom Benutzer aktiviert wurden? -
Ransh
5

Um die Abschreibungsbeschwerde loszuwerden (wenn Sie auf API17 + abzielen und sich nicht zu sehr um die Abwärtskompatibilität kümmern), müssen Sie Folgendes vergleichen 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);
}

wenn Sie eine niedrigere API in Betracht ziehen:

/** 
 * @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
quelle
1
Settings.Global.AIRPLANE_MODE_ON Dies funktioniert nur für API 17+, fyi
Joseph Casey
1
Abwärtskompatibilität hinzugefügt - während es jetzt fast das gleiche wie im obigen Beispiel ist.
Martin Zeitler
Entspricht "Settings.System.AIRPLANE_MODE_ON" den aktivierten Netzwerkdaten? Wenn nicht - Gibt es einen anderen Einstellungsstatus, um festzustellen, ob die Daten vom Benutzer aktiviert wurden?
Ransh
2

Verwenden Sie in Oreo bitte nicht den Flugzeugmodus BroadCastReceiver. es ist eine implizite Absicht. es wurde entfernt. Hier ist die aktuelle Ausnahmeliste . Es ist derzeit nicht auf der Liste und sollte daher keine Daten empfangen. Betrachten Sie es als tot.

Verwenden Sie, wie oben von einem anderen Benutzer angegeben, den folgenden 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;
        }
    }
j2emanue
quelle
1

Statischer Rundfunkempfänger

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: Java-Datei des Broadcast Receivers

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

ODER

Dynamischer Rundfunkempfänger

Java-Code: Aktivitäts-Java-Datei

Registrieren Sie den Rundfunkempfänger bei geöffneter Anwendung. Sie müssen keinen Code im Manifest hinzufügen, wenn Sie nur dann eine Aktion ausführen, wenn Ihre Aktivität geöffnet ist. Überprüfen Sie, ob der Flugzeugmodus aktiviert oder deaktiviert ist, wenn Sie auf das Internet zugreifen

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: Java-Datei des Broadcast Receivers

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();
}
AXN Unicode Technologies
quelle
1

Ab API-Ebene - 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
quelle
0

Ich habe diese Klasse geschrieben, die hilfreich sein könnte. Es wird kein Boolescher Wert direkt zurückgegeben, der angibt, ob der Flugzeugmodus aktiviert oder deaktiviert ist. Es werden Sie jedoch benachrichtigt, wenn der Flugzeugmodus von einem zum anderen geändert wird.

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

}

Verwendung

// 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.
quelle
0

Hier ist das einzige, was für mich funktioniert hat (API 27):

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

Wo brist Ihr BroadcastReceiver? Ich glaube, dass mit den jüngsten Änderungen in der Erlaubnis jetzt beide ConnectivityManager.CONNECTIVITY_ACTIONund Intent.ACTION_AIRPLANE_MODE_CHANGEDnotwendig sind.

Gus
quelle
0

Seit Jelly Bean (Build Code 17) wurde dieses Feld in die globalen Einstellungen verschoben. Um die beste Kompatibilität und Robustheit zu erzielen, müssen wir uns also um beide Fälle kümmern. Das folgende Beispiel ist in Kotlin geschrieben.

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
}

Hinweis: Wenn Sie Versionen vor Jelly Bean nicht unterstützen, können Sie die if-Klausel weglassen.
Der Wert, den Sie beim Referenzieren erhalten Settings.System.AIRPLANE_MODE_ON, ist der gleiche wie der unter Global. *

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

Dies ist die obige Jelly Bean-Version des vorherigen Codes.

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

Sie können überprüfen, ob das Internet aktiviert ist

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
quelle
Das Problem bei der obigen Methode besteht darin, dass Situationen, in denen andere Apps die Konnektivität ändern, nicht berücksichtigt werden. Beispiel: Wenn ein Benutzer den Flugzeugmodus einschaltet, dann aber eine andere App mit den entsprechenden Berechtigungen ein Radio aktiviert. Nehmen wir weiter an, das Radio ist eingeschaltet, aber dann besteht keine Verbindung. Die obige Antwort sagt uns jedoch nicht wirklich, ob der Flugzeugmodus speziell ein- oder ausgeschaltet ist, nur wenn das Gerät eine Verbindung hat. Zwei verschiedene Dinge.
Logray