Bagaimana seseorang bisa mendeteksi mode pesawat di Android?

93

Saya memiliki kode di aplikasi saya yang mendeteksi apakah Wi-Fi terhubung secara aktif. Kode tersebut memicu RuntimeException jika mode pesawat diaktifkan. Saya ingin menampilkan pesan kesalahan terpisah ketika dalam mode ini. Bagaimana saya dapat mendeteksi dengan andal jika perangkat Android dalam mode pesawat?

Sean W.
sumber
Bergantung pada cara Anda melakukan pemeriksaan, ada baiknya untuk mengetahui bahwa mode pesawat dan Wi-Fi dapat diaktifkan pada saat yang bersamaan: heresthethingblog.com/2013/08/28/…
nibarius

Jawaban:

138
/**
* 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
sumber
33
Di Jelly Bean 4.2, pengaturan ini telah dipindahkan ke Settings.Global.
Chris Feist
1
Ini memberikan hasil yang tidak pasti ketika saya memanggilnya sebagai respons terhadap maksud android.intent.action.AIRPLANE_MODE, karena perubahan mode membutuhkan waktu untuk diselesaikan. Periksa Intent.ACTION_AIRPLANE_MODE_CHANGEDapakah Anda ingin melakukan itu.
Noumenon
7
Sekadar petunjuk
:!
apakah itu sama dengan data jaringan yang diaktifkan? Jika tidak - apakah ada status pengaturan lain untuk mengetahui apakah data diaktifkan oleh pengguna?
ransh
compiler mengatakan AIRPLANE_MODE_ON sudah usang
Jean Raymond Daher
96

Dengan memperluas jawaban Alex untuk menyertakan pemeriksaan versi SDK, kami memiliki:

/**
 * 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
sumber
5
Eclipse tidak akan mengkompilasi ini kecuali Anda menambahkan @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)sebelum metode.
Noumenon
1
Saya tidak bisa membuat ini berhasil di Intellij. Saya melayani 2.2, jadi saya punya minSdk = 8, dan untuk itu memiliki "Android 2.2" sebagai Project SDK ". Namun, ini berarti bahwa kode" Settings.Global "berwarna merah dan tidak dapat dikompilasi. Saya tidak ' Saya tidak ingin menetapkan 4.2 sebagai SDK proyek karena saya mungkin melewatkan sesuatu yang tidak tersedia di 2.2 ... ini membuat saya gila, apa praktik terbaik di sini? Ada ide?
Mathias
1
Ubah targetSDK Anda
Louis CAD
54

Dan jika Anda tidak ingin melakukan polling jika Mode Pesawat aktif atau tidak, Anda dapat mendaftarkan BroadcastReceiver untuk Maksud SERVICE_STATE dan bereaksi padanya.

Baik di ApplicationManifest Anda (sebelum Android 8.0):

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

atau secara terprogram (semua versi 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);

Dan seperti yang dijelaskan dalam solusi lain, Anda dapat melakukan polling mode pesawat saat penerima Anda diberi tahu dan memberikan pengecualian.

saksofon
sumber
2
catatan: karena ada pemberitahuan SERVICE_STATE lainnya, Anda harus memeriksa dan menyimpan status mode pesawat sebelum menerima pemberitahuan SERVICE_STATE, dan kemudian memeriksa statusnya saat menerima pemberitahuan status layanan, lalu bandingkan keduanya - untuk mengetahui jika mode pesawat benar-benar berubah.
mattorb
11
mpstx: atau gunakan: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);/<action android:name="android.intent.action.AIRPLANE_MODE" />
Popok
3
Untuk solusi ini Anda memerlukan izin: <
using
4
Gunakan Intent.ACTION_AIRPLANE_MODE_CHANGED
Jeyanth Kumar
4
Juga untuk mengetahui apakah mode pesawat udara dihidupkan atau dimatikan, kita bisa menggunakan nilai ekstra boolean dalam maksud yang kita terima. boolean isPlaneModeOn = intent.getBooleanExtra("state", false); Boolean isPlaneModeOnakan terjadi truejika pengguna telah mengaktifkan mode pesawat atau falsejika dimatikan
Sudara
20

Saat mendaftarkan Mode Pesawat BroadcastReceiver(jawaban @saxos) menurut saya masuk akal untuk mendapatkan status pengaturan Mode Pesawat langsung dari Intent Extrasuntuk menghindari panggilan Settings.Globalatau 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
sumber
3
Ini adalah cara paling efisien untuk mendapatkan kembali status mode pesawat sebenarnya. Ini harus mendapatkan suara dan menjadi jawaban baru yang diterima. 1 untuk membaca dokumen yang membicarakan tentang maksud ekstra "keadaan" ini. Saya menguji dan berfungsi dengan baik.
Louis CAD
7

Dari sini :

 public static boolean isAirplaneModeOn(Context context){
   return Settings.System.getInt(
               context.getContentResolver(),
               Settings.System.AIRPLANE_MODE_ON, 
               0) != 0;
 }
Preet Sangha
sumber
Apakah "Settings.System.AIRPLANE_MODE_ON" sama dengan data jaringan yang diaktifkan? Jika tidak - apakah ada status pengaturan lain untuk mengetahui apakah data diaktifkan oleh pengguna? -
ransh
5

untuk menghilangkan keluhan depresiasi (ketika menargetkan API17 + dan tidak terlalu peduli tentang kompatibilitas ke belakang), seseorang harus membandingkan dengan 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);
}

ketika mempertimbangkan API yang lebih rendah:

/** 
 * @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
sumber
1
Settings.Global.AIRPLANE_MODE_ON Ini hanya akan bekerja untuk API 17+, fyi
Joseph Casey
1
menambahkan kompatibilitas mundur - sementara itu hampir sama dengan contoh di atas sekarang.
Martin Zeitler
Apakah "Settings.System.AIRPLANE_MODE_ON" sama dengan data jaringan yang diaktifkan? Jika tidak - apakah ada status pengaturan lain untuk mengetahui apakah data diaktifkan oleh pengguna?
ransh
2

Di Oreo, jangan gunakan broadCastReceiver mode pesawat. itu adalah maksud implisit. itu telah dihapus. Berikut adalah daftar pengecualian saat ini . itu saat ini tidak ada dalam daftar jadi harus gagal menerima data. Anggap saja sudah mati.

seperti yang dinyatakan oleh pengguna lain di atas gunakan kode berikut:

 @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
sumber
1

Penerima Siaran Statis

Kode manifes:

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

Kode Java: File java Penerima Siaran

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

ATAU

Penerima Siaran Dinamis

Kode Java: File java aktivitas

Daftarkan penerima siaran pada aplikasi terbuka tidak perlu menambahkan kode dalam manifes jika Anda mengambil tindakan hanya ketika aktivitas Anda terbuka seperti mode pesawat centang hidup atau mati ketika Anda mengakses internet dll

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

Kode Java: File java Penerima Siaran

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();
}
Teknologi Unicode AXN
sumber
1

Dari API Level - 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
sumber
0

Saya menulis kelas ini yang mungkin bisa membantu. Itu tidak secara langsung mengembalikan boolean untuk memberi tahu Anda jika Mode Pesawat diaktifkan atau dinonaktifkan, tetapi itu akan memberi tahu Anda ketika Mode Pesawat diubah dari satu ke yang lain.

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

}

Pemakaian

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

Inilah satu-satunya hal yang berhasil untuk saya (API 27):

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

Di mana brBroadcastReceiver Anda. Saya percaya bahwa dengan perubahan izin sekarang baik ConnectivityManager.CONNECTIVITY_ACTIONdan Intent.ACTION_AIRPLANE_MODE_CHANGEDdibutuhkan.

Gus
sumber
0

Sejak Jelly Bean (Build Code 17), bidang ini telah dipindahkan ke pengaturan Global. Jadi, untuk mencapai kompatibilitas dan ketahanan terbaik, kami harus menangani kedua kasus tersebut. Contoh berikut ditulis di 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
}

Catatan: Jika Anda tidak menyimpan dukungan untuk versi sebelum Jelly Bean, Anda dapat menghilangkan klausa if.
Nilai yang Anda dapatkan saat mereferensikan Settings.System.AIRPLANE_MODE_ON, sama dengan yang Anda temukan di Global. *

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

Ini adalah versi kacang jeli di atas dari kode sebelumnya.

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

Anda dapat memeriksa apakah internet aktif

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
sumber
Masalah dengan metode di atas adalah yang tidak memperhitungkan situasi akun di mana aplikasi lain mengubah konektivitas. Contoh jika pengguna mengaktifkan mode pesawat, tetapi kemudian aplikasi lain dengan hak istimewa yang sesuai mengaktifkan radio. Dan selanjutnya, misalkan radio menyala tetapi kemudian tidak ada koneksi ... bagaimanapun jawaban di atas benar-benar tidak memberi tahu kami apakah mode pesawat secara khusus aktif atau nonaktif, hanya jika perangkat memiliki koneksi. Dua hal berbeda.
logray