Як можна виявити режим польоту на Android?


92

У моїй програмі є код, який визначає, чи активно підключений Wi-Fi. Цей код запускає RuntimeException, якщо ввімкнено режим польоту. Я хотів би показати окреме повідомлення про помилку в будь-якому випадку в цьому режимі. Як я можу надійно виявити, чи пристрій Android перебуває в режимі польоту?


Залежно від того, як ви робите свої перевірки, радимо пам’ятати, що можна одночасно вмикати і режим польоту, і Wi-Fi: heresthethingblog.com/2013/08/28/…
nibarius

Відповіді:


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
У Jelly Bean 4.2 це налаштування перенесено на Settings.Global.
Chris Feist

1
Це дало невизначені результати, коли я зателефонував йому у відповідь на намір android.intent.action.AIRPLANE_MODE, оскільки для зміни режиму потрібен час. Перевірте, Intent.ACTION_AIRPLANE_MODE_CHANGEDчи хочете ви це зробити.
Noumenon

7
Лише підказка
:!

це те саме, що ввімкнено мережеві дані? Якщо ні - чи існує інший статус налаштувань, щоб дізнатись, чи ввімкнув дані користувач?
ransh

компілятор каже, що AIRPLANE_MODE_ON застарілий
Jean Raymond Daher

96

Розширивши відповідь Алекса на включення перевірки версій SDK, ми маємо:

/**
 * 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 не буде компілювати це, якщо ви не додасте @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)до методу.
Noumenon

1
Я не можу зробити цю роботу в Intellij. Я задовольняю 2.2, тому у мене є minSdk = 8, і для цього я маю "Android 2.2" як SDK проекту ". Однак це означає, що код" Settings.Global "червоний і не компілюється. Я не ' я не хочу встановити 4.2 як проектний SDK, оскільки я можу пропустити щось недоступне в 2.2 ... це зводить мене з розуму, яка найкраща практика тут? Будь-яка ідея?
Матіас

1
Змініть ціль SDK
Louis CAD

54

І якщо ви не хочете проводити опитування, якщо режим польоту активний чи ні, ви можете зареєструвати BroadcastReceiver для наміру SERVICE_STATE і реагувати на нього.

Або у вашому ApplicationManifest (до Android 8.0):

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

або програмно (усі версії 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);

І, як описано в інших рішеннях, ви можете опитати режим польоту, коли ваш приймач отримав повідомлення, і кинути своє виняток.


2
Примітка: оскільки є інші сповіщення SERVICE_STATE, вам доведеться перевірити та зберегти стан режиму польоту до отримання сповіщення SERVICE_STATE, а потім перевірити стан його при отриманні сповіщення про стан служби, а потім порівняти два - щоб знати якщо режим польоту насправді змінився.
mattorb

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

3
Для цього рішення вам знадобиться дозвіл: <koristi-дозвіл android: name = "android.permission.READ_PHONE_STATE" />
Томас Дігнан

4
Use Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar

4
Також для того, щоб увімкнути або вимкнути режим повітряного літака, ми можемо використовувати логічне додаткове значення в отриманому намірі. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Логічне значення isPlaneModeOnбуде, trueякщо користувач увімкнув режим літака або falseякщо його вимкнено
Судара,

20

Під час реєстрації режиму BroadcastReceiverпольоту (відповідь @saxos) я вважаю, що має сенс отримувати стан налаштування режиму польоту відразу Intent Extras, щоб уникнути дзвінків Settings.Globalабо 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
Це найефективніший спосіб отримати фактичний стан режиму польоту. Це повинно набрати голосів і бути новою прийнятою відповіддю. +1 за читання документів, які розповідають про цей "державний" намір додатково. Я протестував, і він працює належним чином.
Louis CAD

7

Від сюди :

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

Чи ввімкнено "Settings.System.AIRPLANE_MODE_ON" так само, як мережеві дані? Якщо ні - чи існує інший статус налаштувань, щоб дізнатись, чи ввімкнув дані користувач? -
ransh


5

щоб позбутися скарги на амортизацію (при націлюванні на API17 + і не надто дбаючи про зворотну сумісність), слід порівняти з 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);
}

розглядаючи нижчий 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;
    }
}

1
Settings.Global.AIRPLANE_MODE_ON Це буде працювати лише для API 17+, fyi
Джозеф Кейсі

1
додана зворотна сумісність - хоча це майже те ж саме, що і в прикладі вище.
Martin Zeitler

Чи ввімкнено "Settings.System.AIRPLANE_MODE_ON" так само, як мережеві дані? Якщо ні - чи існує інший статус налаштувань, щоб дізнатись, чи ввімкнув дані користувач?
ransh

2

В Oreo, будь ласка, не використовуйте режим польоту broadCastReceiver. це неявний намір. його було видалено. Ось поточний список винятків . його зараз немає у списку, тому не слід отримувати дані. Вважайте це мертвим.

як зазначено іншим користувачем вище, використовуйте такий код:

 @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

Приймач статичного мовлення

Код маніфесту:

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

АБО

Динамічний широкомовний приймач

Код Java: файл Java-активності

Зареєструйте трансляційний приймач у відкритому додатку. Не потрібно додавати код у маніфест, якщо ви виконуєте дії лише тоді, коли ваша діяльність відкрита, наприклад, перевірте режим польоту, увімкнено або вимкнено під час доступу до Інтернету тощо

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: 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

Від рівня 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

Я написав цей клас, який може бути корисним. Він не повертає безпосередньо логічну форму, щоб повідомити, чи ввімкнено чи вимкнено режим польоту, але він повідомить вас, коли режим польоту буде змінено з одного на інший.

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

}

Використання

// 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

Ось єдине, що мені вдалося (API 27):

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

Де brваш BroadcastReceiver. Я вважаю, що з нещодавніми змінами в дозволі зараз потрібні і те, ConnectivityManager.CONNECTIVITY_ACTIONі інше Intent.ACTION_AIRPLANE_MODE_CHANGED.


0

Починаючи з Jelly Bean (Код збірки 17), це поле було переміщено до Глобальних налаштувань. Таким чином, для досягнення найкращої сумісності та надійності ми повинні подбати про обидва випадки. Наступний приклад написаний у Котліні.

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
}

Примітка: Якщо ви не зберігаєте підтримку версій до Jelly Bean, ви можете опустити пункт if.
Значення, яке ви отримуєте під час посилання Settings.System.AIRPLANE_MODE_ON, таке саме, як і те, яке ви знайдете в Глобальному. *

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

Це версія желейних бобів попереднього коду.

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

-4

Ви можете перевірити, чи ввімкнено Інтернет

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

}


Проблема вищевказаного методу полягає в тому, що він не враховує ситуації, коли інші програми змінюють підключення. Приклад, якщо користувач вмикає режим польоту, але тоді інша програма з відповідними привілеями вмикає радіо. І далі, припустимо, радіо ввімкнено, але тоді зв’язку немає ... так чи інакше, наведена вище відповідь насправді не говорить нам, чи конкретно режим літака ввімкнено чи вимкнено, просто якщо пристрій має зв’язок. Дві різні речі.
logray
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.