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

สแกนเครือข่าย WiFi ใน Android ด้วยโค้ดโปรแกรม (Programmatically)

บทความนี้สาธิตการสแกนเครือข่าย WiFi แบบโปรแกรมมาติก (Programmatic Scan) ใช้ WifiManager และ BroadcastReceiver รับผลลัพธ์ แสดงใน ListView

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

Android Studio → New Project → Empty Activity

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

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp">

    <ListView
        android:id="@+id/wifiList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/scanBtn" />

    <Button
        android:id="@+id/scanBtn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_margin="15dp"
        android:text="สแกน WiFi" />
</RelativeLayout>

ขั้นตอนที่ 3: MainActivity.java

public class MainActivity extends AppCompatActivity {

    private ListView wifiList;
    private WifiManager wifiManager;
    private WifiReceiver receiverWifi;
    private static final int PERMISSION_REQUEST_CODE = 1;

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

        wifiList = findViewById(R.id.wifiList);
        Button scanBtn = findViewById(R.id.scanBtn);
        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        // เปิด WiFi ถ้าปิดอยู่
        if (wifiManager != null && !wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }

        scanBtn.setOnClickListener(v -> requestPermissionAndScan());
    }

    private void requestPermissionAndScan() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        PERMISSION_REQUEST_CODE);
            } else {
                startScan();
            }
        } else {
            startScan();
        }
    }

    private void startScan() {
        if (wifiManager != null) {
            boolean success = wifiManager.startScan();
            if (!success) {
                Toast.makeText(this, "สแกนล้มเหลว ลองใหม่อีกครั้ง", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        receiverWifi = new WifiReceiver(wifiManager, wifiList);
        IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        registerReceiver(receiverWifi, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (receiverWifi != null) {
            unregisterReceiver(receiverWifi);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startScan();
            } else {
                Toast.makeText(this, "ต้องอนุญาตสิทธิ์ตำแหน่งเพื่อสแกน WiFi", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

ขั้นตอนที่ 4: WifiReceiver.java

class WifiReceiver extends BroadcastReceiver {

    private final WifiManager wifiManager;
    private final ListView listView;

    public WifiReceiver(WifiManager wifiManager, ListView listView) {
        this.wifiManager = wifiManager;
        this.listView = listView;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
            List<ScanResult> results = wifiManager.getScanResults();
            List<String> items = new ArrayList<>();

            for (ScanResult result : results) {
                // กรอง SSID ว่าง
                if (result.SSID != null && !result.SSID.isEmpty()) {
                    String security = getSecurityType(result.capabilities);
                    items.add(result.SSID + " (" + security + ") - " + result.level + " dBm");
                }
            }

            ArrayAdapter<String> adapter = new ArrayAdapter<>(
                    context, android.R.layout.simple_list_item_1, items);
            listView.setAdapter(adapter);
        }
    }

    private String getSecurityType(String capabilities) {
        if (capabilities == null) return "Open";
        if (capabilities.contains("WPA2")) return "WPA2";
        if (capabilities.contains("WPA")) return "WPA";
        if (capabilities.contains("WEP")) return "WEP";
        return "Open";
    }
}

ขั้นตอนที่ 5: Manifest (Permissions)

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- Android 10+ อาจต้องการ -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

⚠️ ข้อจำกัดใน Android เวอร์ชันใหม่

Android Version API Level ข้อจำกัด
6.0 - 9.0 23 - 28 ต้อง ACCESS_COARSE_LOCATION
10 (Q) 29 startScan() ต้องเป็น System App หรือมี ACCESS_FINE_LOCATION + Location เปิดอยู่
11 (R) 30 เพิ่มข้อจำกัด Non-SDK Interface ใช้ WifiScanner API แทน
12+ (S) 31+ แนะนำใช้ WifiManager.startScan() ร่วมกับ WifiScanner API ใหม่

🔧 แนวทางทันสมัย (Modern Approach) Android 10+

// ใช้ WifiScanner API (Android 10+)
WifiManager wifiManager = getSystemService(WifiManager.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    WifiScanner scanner = wifiManager.startScan(new WifiScanner.ScanSettings.Builder().build());
    // รับผลผ่าน Listener/Callback แทน BroadcastReceiver
}

การทดสอบ

ติดตั้งบนอุปกรณ์จริง (ไม่ใช่ Emulator) ให้สิทธิ์ Location แล้วกดสแกน จะเห็นรายการ WiFi พร้อมระดับสัญญาณและประเภทความปลอดภัย