Mam w aplikacji kod, który wykrywa aktywne połączenie Wi-Fi. Ten kod wyzwala wyjątek RuntimeException, jeśli włączony jest tryb samolotowy. Chciałbym mimo wszystko wyświetlić oddzielny komunikat o błędzie w tym trybie. Jak mogę niezawodnie wykryć, czy urządzenie z Androidem działa w trybie samolotowym?
93
Odpowiedzi:
/** * 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; }
źródło
Settings.Global
.android.intent.action.AIRPLANE_MODE
, ponieważ zmiana trybu wymaga czasu. Sprawdź,Intent.ACTION_AIRPLANE_MODE_CHANGED
jeśli chcesz to zrobić.Rozszerzając odpowiedź Alexa o sprawdzenie wersji SDK, otrzymaliśmy:
/** * 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; } }
źródło
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
przed metodą.A jeśli nie chcesz sondować, czy tryb samolotowy jest aktywny, czy nie, możesz zarejestrować odbiornik BroadcastReceiver dla intencji SERVICE_STATE i zareagować na to.
Albo w pliku ApplicationManifest (przed Androidem 8.0):
<receiver android:enabled="true" android:name=".ConnectivityReceiver"> <intent-filter> <action android:name="android.intent.action.AIRPLANE_MODE"/> </intent-filter> </receiver>
lub programowo (wszystkie wersje Androida):
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);
I jak opisano w innych rozwiązaniach, możesz odpytać tryb samolotowy, gdy twój odbiornik został powiadomiony i zgłosić wyjątek.
źródło
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
/<action android:name="android.intent.action.AIRPLANE_MODE" />
boolean isPlaneModeOn = intent.getBooleanExtra("state", false);
Wartość logicznaisPlaneModeOn
będzie,true
jeśli użytkownik włączył tryb samolotowy lubfalse
jeśli jest wyłączonyPodczas rejestracji trybu samolotowego
BroadcastReceiver
(odpowiedź @saxos) wydaje mi się, że bardzo sensowne jest uzyskanie stanu ustawienia trybu samolotowego od razuIntent Extras
, aby uniknąć dzwonieniaSettings.Global
lubSettings.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 } }
źródło
Od tutaj :
public static boolean isAirplaneModeOn(Context context){ return Settings.System.getInt( context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; }
źródło
aby pozbyć się reklamacji amortyzacji (celując w API17 + i nie przejmując się zbytnio kompatybilnością wsteczną), należy porównać z
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); }
rozważając niższe 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; } }
źródło
W Oreo nie używaj broadCastReceiver w trybie samolotowym. jest to ukryta intencja. został usunięty. Oto aktualna lista wyjątków . nie ma go obecnie na liście, więc nie powinien odebrać danych. Uważaj to za martwe.
jak stwierdził inny użytkownik powyżej, użyj następującego kodu:
@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; } }
źródło
Statyczny odbiornik transmisji
Kod manifestu:
<receiver android:name=".airplanemodecheck" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.AIRPLANE_MODE"></action> </intent-filter> </receiver>
Kod Java: plik java odbiornika transmisji
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(); }
LUB
Dynamiczny odbiornik transmisji
Kod Java: plik Java aktywności
Zarejestruj odbiornik transmisji przy otwartej aplikacji nie ma potrzeby dodawania kodu w manifeście, jeśli wykonujesz akcję tylko wtedy, gdy Twoja aktywność jest otwarta, np. Sprawdź, czy tryb samolotowy jest włączony lub wyłączony, kiedy uzyskujesz dostęp do Internetu itp.
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); }
Kod Java: plik java odbiornika transmisji
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(); }
źródło
Od poziomu 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; }
źródło
Napisałem te zajęcia, które mogą być pomocne. Nie zwraca bezpośrednio wartości logicznej, aby powiedzieć, czy tryb samolotowy jest włączony, czy wyłączony, ale powiadomi Cię, gdy tryb samolotowy zostanie zmieniony z jednego na drugi.
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); }
Stosowanie
// 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(); }
źródło
Oto jedyna rzecz, która zadziałała dla mnie (API 27):
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); this.registerReceiver(br, filter);
Gdzie
br
jest twój BroadcastReceiver. Uważam, że w związku z ostatnimi zmianami w pozwoleniach teraz zarównoConnectivityManager.CONNECTIVITY_ACTION
i jakIntent.ACTION_AIRPLANE_MODE_CHANGED
są potrzebne.źródło
Od czasu Jelly Bean (kod kompilacji 17) to pole zostało przeniesione do ustawień globalnych. Dlatego, aby uzyskać najlepszą kompatybilność i solidność, musimy zadbać o oba przypadki. Poniższy przykład jest napisany w Kotlinie.
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 }
/** * @deprecated Use {@link android.provider.Settings.Global#AIRPLANE_MODE_ON} instead */ @Deprecated public static final String AIRPLANE_MODE_ON = Global.AIRPLANE_MODE_ON;
To jest powyższa wersja poprzedniego kodu z galaretką.
fun isInAirplane(context: Context): Boolean { return Settings.Global.getInt( context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0 ) != 0 }
źródło
Możesz sprawdzić, czy internet jest włączony
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; }
}
źródło