Làm cách nào để phát hiện chế độ trên máy bay trên Android?


92

Tôi có mã trong ứng dụng của mình để phát hiện xem Wi-Fi có được kết nối tích cực hay không. Mã đó kích hoạt RuntimeException nếu chế độ máy bay được bật. Tôi vẫn muốn hiển thị một thông báo lỗi riêng khi ở chế độ này. Làm cách nào tôi có thể phát hiện một cách đáng tin cậy nếu thiết bị Android đang ở chế độ trên máy bay?


Tùy thuộc vào cách bạn làm séc của bạn, nó tốt đến mức khó nhận thức được rằng nó có thể có cả hai chế độ máy bay và Wi-Fi được kích hoạt cùng lúc: heresthethingblog.com/2013/08/28/...
nibarius

Câu trả lời:


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
Trong Jelly Bean 4.2, cài đặt này đã chuyển sang Settings.Global.
Chris Feist

1
Điều này mang lại kết quả không xác định khi tôi gọi nó theo ý định android.intent.action.AIRPLANE_MODE, vì quá trình thay đổi chế độ cần có thời gian để hoàn thành. Kiểm tra lại Intent.ACTION_AIRPLANE_MODE_CHANGEDnếu bạn muốn làm điều đó.
Noumenon

7
! Chỉ cần một gợi ý: = 0 false trả (chế độ máy bay là off) và == 0 trả về true (chế độ máy bay là trên)
jfmg

nó có giống với dữ liệu mạng được kích hoạt không? Nếu không - có trạng thái cài đặt khác để biết liệu người dùng có bật dữ liệu không?
ransh

trình biên dịch cho biết AIRPLANE_MODE_ON không được dùng nữa
Jean Raymond Daher

96

Bằng cách mở rộng câu trả lời của Alex để bao gồm kiểm tra phiên bản SDK, chúng tôi có:

/**
 * 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 sẽ không biên dịch điều này trừ khi bạn thêm vào @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)trước phương thức.
Noumenon

1
Tôi không thể làm cho điều này hoạt động trong Intellij. Tôi phục vụ cho phiên bản 2.2, vì vậy tôi có minSdk = 8 và do đó có "Android 2.2" làm SDK dự án ". Tuy nhiên, điều này có nghĩa là mã" Settings.Global "có màu đỏ và sẽ không biên dịch. Tôi không" Tôi không muốn đặt 4.2 làm SDK dự án vì tôi có thể bỏ lỡ thứ gì đó không có sẵn trong 2.2 ... điều này khiến tôi phát điên, phương pháp hay nhất ở đây là gì? Bạn có ý kiến ​​gì không?
Mathias

1
Thay đổi mục tiêu của bạn SDK
Louis CAD

54

Và nếu bạn không muốn thăm dò xem Chế độ trên máy bay có đang hoạt động hay không, bạn có thể đăng ký BroadcastReceiver cho Ý định SERVICE_STATE và phản ứng trên đó.

Trong ApplicationManifest của bạn (trước Android 8.0):

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

hoặc theo chương trình (tất cả các phiên bản 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);

Và như được mô tả trong các giải pháp khác, bạn có thể thăm dò chế độ trên máy bay khi người nhận của bạn được thông báo và đưa ra ngoại lệ.


2
lưu ý: vì có các thông báo SERVICE_STATE khác, bạn sẽ phải kiểm tra và lưu trữ trạng thái của chế độ trên máy bay trước khi nhận thông báo SERVICE_STATE, sau đó kiểm tra trạng thái của nó khi nhận được thông báo trạng thái dịch vụ, sau đó so sánh hai trạng thái này - để biết nếu chế độ máy bay thực sự thay đổi.
mattorb

11
mpstx: hoặc sử dụng: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Nappy

3
Đối với giải pháp này, bạn sẽ cần sự cho phép: <dụng-phép android: name = "android.permission.READ_PHONE_STATE" />
Thomas Dignan

4
Sử dụng Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar,

4
Ngoài ra, để biết chế độ máy bay được bật hay tắt, chúng tôi có thể sử dụng giá trị bổ sung boolean trong ý định mà chúng tôi nhận được. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Boolean isPlaneModeOnsẽ là truenếu người dùng đã bật chế độ máy bay hoặc falsenếu nó bị tắt
Sudara

20

Khi đăng ký Chế độ trên máy bay BroadcastReceiver(@saxos answer), tôi nghĩ rất có ý nghĩa khi nhận được trạng thái của cài đặt Chế độ trên máy bay ngay lập tức Intent Extrasđể tránh gọi Settings.Globalhoặc 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
Đây là cách hiệu quả nhất để truy xuất trạng thái chế độ máy bay thực tế. Điều này sẽ nhận được phiếu bầu và là câu trả lời mới được chấp nhận. +1 để đọc các tài liệu nói về mục đích bổ sung "trạng thái" này. Tôi đã thử nghiệm và nó hoạt động bình thường.
Louis CAD

7

Từ đây :

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

"Cài đặt.System.AIRPLANE_MODE_ON" có giống với dữ liệu mạng được bật không? Nếu không - có trạng thái cài đặt khác để biết liệu người dùng có bật dữ liệu không? -
ransh


5

để loại bỏ khiếu nại về khấu hao (khi nhắm mục tiêu API17 + và không quan tâm quá nhiều đến khả năng tương thích ngược), người ta phải so sánh với 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);
}

khi xem xét API thấp hơn:

/** 
 * @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 Điều này sẽ chỉ hoạt động cho API 17+, fyi
Joseph Casey

1
đã thêm khả năng tương thích ngược - trong khi nó gần giống như ví dụ ở trên bây giờ.
Martin Zeitler

"Cài đặt.System.AIRPLANE_MODE_ON" có giống với dữ liệu mạng được bật không? Nếu không - có trạng thái cài đặt khác để biết liệu người dùng có bật dữ liệu không?
ransh

2

Trong Oreo, vui lòng không sử dụng chế độ máy bay wideCastReceiver. nó là một ý định ngầm. nó đã bị loại bỏ. Đây là danh sách ngoại lệ hiện tại . nó hiện không có trong danh sách nên không nhận được dữ liệu. Coi như đã chết.

như được nêu bởi một người dùng khác ở trên, hãy sử dụng mã sau:

 @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

Máy thu phát sóng tĩnh

Mã kê khai:

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

Mã Java: Tệp 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();
}

HOẶC LÀ

Máy thu phát sóng động

Mã Java: Tệp java hoạt động

Đăng ký bộ thu phát sóng trên ứng dụng đang mở, không cần thêm mã vào tệp kê khai nếu bạn thực hiện một hành động chỉ khi hoạt động của bạn mở như kiểm tra chế độ máy bay đang bật hoặc tắt khi bạn truy cập internet, v.v.

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

Mã Java: Tệp 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

Từ cấp độ 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

Tôi đã viết lớp học này có thể hữu ích. Nó không trực tiếp trả về boolean để cho bạn biết nếu Chế độ trên máy bay được bật hay tắt, nhưng nó sẽ thông báo cho bạn khi Chế độ trên máy bay được thay đổi từ chế độ này sang chế độ khác.

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

}

Sử dụng

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

Đây là điều duy nhất phù hợp với tôi (API 27):

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

brBroadcastReceiver của bạn ở đâu . Tôi tin rằng với những thay đổi gần đây về quyền bây giờ ConnectivityManager.CONNECTIVITY_ACTIONIntent.ACTION_AIRPLANE_MODE_CHANGEDlà cần thiết.


0

Kể từ Jelly Bean (Mã xây dựng 17), trường này đã được chuyển sang Cài đặt chung. Do đó, để đạt được khả năng tương thích tốt nhất và mạnh mẽ, chúng ta phải quan tâm đến cả hai trường hợp. Ví dụ sau đây được viết bằng 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
}

Lưu ý: Nếu bạn không giữ hỗ trợ cho các phiên bản trước Jelly Bean, bạn có thể bỏ qua mệnh đề if.
Giá trị mà bạn nhận được khi tham chiếuSettings.System.AIRPLANE_MODE_ON , giống với giá trị bạn tìm thấy trong Toàn cầu. *

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

Đây là phiên bản đậu thạch ở trên của mã trước.

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

-4

Bạn có thể kiểm tra xem Internet đã được bật chưa

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

}


Vấn đề với phương pháp trên là không tính đến các tình huống mà các ứng dụng khác sửa đổi kết nối. Ví dụ: nếu người dùng bật chế độ trên máy bay, nhưng sau đó một ứng dụng khác có đặc quyền thích hợp sẽ bật radio. Và xa hơn, giả sử radio đang bật nhưng sau đó không có kết nối ... dù sao câu trả lời ở trên thực sự không cho chúng ta biết chế độ máy bay cụ thể đang bật hay tắt, chỉ cần thiết bị có kết nối. Hai điều khác nhau.
logray
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.