简体   繁体   English

如何在 Android 上检测飞行模式?

[英]How can one detect airplane mode on Android?

I have code in my application that detects if Wi-Fi is actively connected.我的应用程序中有代码可以检测 Wi-Fi 是否已主动连接。 That code triggers a RuntimeException if airplane mode is enabled.如果启用飞行模式,该代码会触发 RuntimeException。 I would like to display a separate error message when in this mode anyway.无论如何,我想在此模式下显示单独的错误消息。 How can I reliably detect if an Android device is in airplane mode?如何可靠地检测 Android 设备是否处于飞行模式?

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

}

By extending Alex's answer to include SDK version checking we have:通过扩展 Alex 的答案以包括 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;
    }       
}

And if you don't want to poll if the Airplane Mode is active or not, you can register a BroadcastReceiver for the SERVICE_STATE Intent and react on it.如果您不想轮询飞行模式是否处于活动状态,您可以为 SERVICE_STATE 意图注册一个 BroadcastReceiver 并对其做出反应。

Either in your ApplicationManifest (pre-Android 8.0):在您的 ApplicationManifest(Android 8.0 之前)中:

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

or programmatically (all Android versions):或以编程方式(所有 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);

And as described in the other solutions, you can poll the airplane mode when your receiver was notified and throw your exception.正如其他解决方案中所述,您可以在接收器收到通知时轮询飞行模式并抛出异常。

When registering the Airplane Mode BroadcastReceiver (@saxos answer) I think it makes a lot of sense to get the state of the Airplane Mode setting right away from the Intent Extras in order to avoid calling Settings.Global or Settings.System :在注册飞行模式BroadcastReceiver (@saxos 答案)时,我认为立即从Intent Extras获取飞行模式设置的状态以避免调用Settings.GlobalSettings.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
    }
}

From here :这里

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

in order to get rid of the the depreciation complaint (when targeting API17+ and not caring too much about the backward compatibility), one has to compare with Settings.Global.AIRPLANE_MODE_ON :为了摆脱折旧抱怨(当针对 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);
}

when considering lower API:在考虑较低的 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;
    }
}

In Oreo please do not use the airplane mode broadCastReceiver.在奥利奥中请不要使用飞行模式 BroadCastReceiver。 it is an implicit intent.这是一个隐含的意图。 it has been removed.它已被删除。 Here is the current exceptions list .这是当前的例外列表 its not currently on the list so should fail to receive data.它目前不在列表中,因此应该无法接收数据。 Consider it dead.认为它死了。

as stated by another user above use the following 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;
        }
    }

Static Broadcast Receiver静态广播接收器

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: Broadcast Receiver java file Java代码:广播接收器java文件

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

OR或者

Dynamic Broadcast Receiver动态广播接收器

Java code: Activity java file Java代码:活动java文件

Register broadcast receiver on application open no need to add code in manifest if you take an action only when your activity open like check airplane mode is on or off when you access the 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);
}

Java code: Broadcast Receiver java file Java代码:广播接收器java文件

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

From API Level - 17从 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;

    }

I wrote this class that might be helpful.我写了这门课,可能会有所帮助。 It doesn't directly return a boolean to tell you if Airplane Mode is enabled or disabled, but it will notify you when Airplane Mode is changed from one to the other.它不会直接返回一个布尔值来告诉您飞行模式是启用还是禁用,但它会在飞行模式从一种更改为另一种时通知您。

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

Here's the only thing what worked for me (API 27):这是唯一对我有用的东西(API 27):

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

Where br is your BroadcastReceiver.其中br是您的 BroadcastReceiver。 I believe that with the recent changes in permission now both ConnectivityManager.CONNECTIVITY_ACTION and Intent.ACTION_AIRPLANE_MODE_CHANGED are needed.我相信随着最近权限的变化,现在需要ConnectivityManager.CONNECTIVITY_ACTIONIntent.ACTION_AIRPLANE_MODE_CHANGED

Since Jelly Bean (Build Code 17), this field has been moved to Global settings.自 Jelly Bean (Build Code 17) 起,此字段已移至全局设置。 Thus, to achieve the best compatibility and robustness we have to take care of both cases.因此,为了获得最佳的兼容性和健壮性,我们必须兼顾这两种情况。 The following example is written in Kotlin.以下示例是用 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
}

Note: If you do not keep support for versions before Jelly Bean, you can omit the if clause.注意:如果不支持 Jelly Bean 之前的版本,则可以省略 if 子句。
The value that you get while referencing Settings.System.AIRPLANE_MODE_ON , is the same as the one you find under Global.*您在引用Settings.System.AIRPLANE_MODE_ON获得的值与您在 Global.* 下找到的值相同

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

This is the above-jelly bean version of the previous code.这是之前代码的上述果冻豆版本。

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

You could check if the internet is on你可以检查互联网是否打开

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何更改Android的飞行模式的行为,以便它不会关闭蜂窝无线电? - How can I change the behavior of Android's airplane mode so that it will not turn off the cellular radio? 在Android 6.0上切换飞行模式 - Toggling Airplane mode on Android 6.0 在Android模拟器中以“飞机”模式进行测试 - Testing in “Airplane” mode in Android Emulator 打开和关闭飞行模式以及如何在android中打开移动数据 - turning airplane mode on and off and how to turn on mobile data in android 使用MQTT Android服务从飞行模式重新连接 - Reconnecting from Airplane Mode with MQTT Android Service Android 关闭飞行模式时应用程序崩溃 - Android App crushes when airplane mode is turned off 如何检测“在呼叫模式下” Android Java - How to detect “in call mode” android java 关闭飞行模式时,为什么 Android 应用程序 go 通过活动和片段生命周期方法 - Why does an Android app go through the activity and fragment lifecycle methods when airplane mode is turned off 如何在Android“小米MIUI”设备中检测“省电模式”? - How to detect “power save mode” in Android “Xiaomi MIUI” devices? 如何检测Android应用程序是否在屏幕兼容模式下运行? - How to detect if an Android app runs in screen compatibility mode?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM