บทความนี้สาธิตการสแกนเครือข่าย 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 พร้อมระดับสัญญาณและประเภทความปลอดภัย