Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีตรวจจับการเปลี่ยนแปลง Airplane Mode ใน Android

ภาพรวม

ตัวอย่างนี้สาธิตวิงการใช้ BroadcastReceiver เพื่อฟัง Event Intent.ACTION_AIRPLANE_MODE_CHANGED ซึ่งจะ Trigger ทุกครั้งที่ผู้ใช้เปิด/ปิดโหมดเครื่องบิน

ขั้นตอนการสร้างโปรเจกต์

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project → Empty Activity

ขั้นตอนที่ 2: Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30sp"
        android:gravity="center"
        android:padding="16dp"
        android:text="รอการเปลี่ยนแปลง Airplane Mode..." />

</LinearLayout>

ขั้นตอนที่ 3: โค้ดหลัก (src/MainActivity.java)

package com.example.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    TextView textView;
    private BroadcastReceiver airplaneModeChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.text);
        
        // แสดงสถานะปัจจุบันตอนเริ่มต้น
        updateStatus();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // ลงทะเบียน Receiver เมื่อ Activity Resume
        registerReceiver();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // ยกเลิก Receiver เมื่อ Activity Pause (ป้องกัน Leak)
        unregisterReceiver();
    }

    private void registerReceiver() {
        if (airplaneModeChangeReceiver == null) {
            airplaneModeChangeReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
                        // อ่านสถานะใหม่จาก Intent Extra
                        boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);
                        
                        String message = isAirplaneModeOn 
                            ? "✈️ Airplane Mode เปิดแล้ว" 
                            : "📱 Airplane Mode ปิดแล้ว";
                        
                        textView.setText(message);
                        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
                        
                        // อัปเดตสถานะล่าสุดจาก Settings (Double-check)
                        updateStatus();
                    }
                }
            };
        }
        
        IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        registerReceiver(airplaneModeChangeReceiver, filter);
    }

    private void unregisterReceiver() {
        if (airplaneModeChangeReceiver != null) {
            try {
                unregisterReceiver(airplaneModeChangeReceiver);
            } catch (IllegalArgumentException e) {
                // Receiver not registered - ignore
            }
            airplaneModeChangeReceiver = null;
        }
    }

    private void updateStatus() {
        boolean isAirplaneModeOn = Settings.Global.getInt(
            getContentResolver(), 
            Settings.Global.AIRPLANE_MODE_ON, 
            0
        ) == 1;
        
        String status = isAirplaneModeOn ? "เปิด (ON)" : "ปิด (OFF)";
        textView.setText("สถานะปัจจุบัน: Airplane Mode " + status);
    }
}

ความแตกต่าง: ACTION_AIRPLANE_MODE vs ACTION_AIRPLANE_MODE_CHANGED

Intent.ACTION_AIRPLANE_MODE
ActionTrigger เมื่อExtra "state"
Boot completed, Airplane mode changedมี (API 17+)
Intent.ACTION_AIRPLANE_MODE_CHANGEDAirplane mode changed โดยผู้ใช้มี (Always)

แนะนำใช้ ACTION_AIRPLANE_MODE_CHANGED เพราะเฉพาะเจาะจงกว่า และมี Extra state เสมอ

Manifest Declaration (Optional - สำหรับ System-wide Listener)

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

วิธีนี้ Receiver จะทำงานแม้แอปจะไม่ได้รัน (แต่ต้องจัดการเองใน onReceive)

กรณีการใช้งานจริง

  • Offline-first Apps: Sync ข้อมูลเมื่อกลับมาออนไลน์ (Airplane mode ปิด)
  • Messaging Apps: แจ้งเตือนผู้ใช้ว่าอยู่ในโหมดออฟไลน์
  • Navigation Apps: หยุดดาวน์โหลดแผนที่/อัปเดตตำแหน่งเมื่อ Airplane mode เปิด
  • IoT/Remote Control: แจ้งว่าอุปกรณ์ควบคุมไม่อาจเชื่อมต่อได้
  • Battery Saver: ปิด Background sync เมื่อ Airplane mode เปิด

ข้อควรระวัง

  • Broadcast นี้เป็น Sticky Broadcast - ได้รับค่าล่าสุดทันทีเมื่อ Register
  • ต้อง Unregister ใน onPause/onDestroy เพื่อป้องกัน Memory Leak
  • ไม่สามารถป้องกัน/บล็อกการเปลี่ยน Airplane Mode ได้ (System-level)
  • บาง OEM อาจส่ง Broadcast ซ้ำ หรือไม่ส่ง (Test บนอุปกรณ์จริง)
  • Android 10+ จำกัด Broadcast บางประเภท แต่นี้ยังทำงานปกติ

ตัวอย่าง: จัดการ Offline/Online State

public class NetworkStateManager {
    private boolean isAirplaneModeOn = false;
    private boolean hasNetworkConnection = false;
    
    public void onAirplaneModeChanged(boolean enabled) {
        isAirplaneModeOn = enabled;
        updateAppBehavior();
    }
    
    public void onNetworkChanged(boolean connected) {
        hasNetworkConnection = connected;
        updateAppBehavior();
    }
    
    private void updateAppBehavior() {
        if (isAirplaneModeOn || !hasNetworkConnection) {
            // Offline mode: ใช้ Cache, Queue requests, Disable sync
            enableOfflineMode();
        } else {
            // Online mode: Sync data, Enable real-time features
            enableOnlineMode();
        }
    }
}