본문 바로가기
안드로이드

[Android] Wifi 스캔하기

by 코딩히어로 2022. 9. 20.
728x90

1


기존 구글에 나와있는 Wifi 스캔 예제 소스들은 여러 가지 참조하여해 봤지만

모두 동작을 하지 않거나 스캔에서 fail이 발생했습니다

더 이상의 구글이나 다른 블로그 소스 참조가 무의미하여

Android sample에서 공식적으로 지원하는 Wifi스캔 쪽을 참조하여 다시 제작하였습니다

//manifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-feature android:name="android.hardware.wifi.rtt"/>

먼저 기존 블로그들에서는 ACCESS_COARSE_LOCATION과 android.hardware.wifi만을 강조하고 있는데

실질적으로 Android sample에서는 android.hardware.wifi.rtt와 ACCESS_FINE_LOCAION을 사용합니다

즉 ACCESS_COARESE_LOCATION은 퍼미션 등록을 하지 않아도 동작합니다.

 

퍼미션 등록을 했다면 해당 퍼미션을 사용하기 위해 App 사용자에게 권한을 요청하는 부분이 있어야 합니다

// MainActivity.java

private String[] permission = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};

private boolean checkPermission(){
    int result;
    List<String> listPermission = new ArrayList<>();
    for(String p : permission){
        result = ContextCompat.checkSelfPermission(MainActivity.this,p);
        if (result != PackageManager.PERMISSION_GRANTED){
            listPermission.add(p);
        }
    }
    if(!listPermission.isEmpty()){
        ActivityCompat.requestPermissions(MainActivity.this,listPermission.toArray(new String[listPermission.size()]),0);
        return false;
    }
    return true;
}

ACCESS_FINE_LOCATION을 체크해서 권한이 없을 시 사용자에게 요청하도록

checkPermission 함수를 만들고 내부에서 checkSelfPermission을 통해 확인합니다

마지막으로 onCreate에서 checkPermission을 호출해주기만 하면 권한에 대한 부분은 준비가 되었습니다

 

다음으로는 Wifi구문에 대한 소스코드인데 먼저 Wifi가 스캔 동작 후 스캔된 데이터가 있을 시

호출될 Receiver를 만들어 주어야 합니다

// MainActivity.java

private class WifiScanReceiver extends BroadcastReceiver {

    // This is checked via mLocationPermissionApproved boolean
    @SuppressLint("MissingPermission")
    public void onReceive(Context context, Intent intent) {
        List<ScanResult> scanResults = mWifiManager.getScanResults();
        for(ScanResult s : scanResults) {
            Log.i("디버깅", "확인 = " + s.SSID+"/"+s.BSSID);
        }
    }
}

WifiScanReceiver를 통해 SSID와 BSSID를 출력하는 간단한 리시버를 만들었습니다

해당 Log.i부분에 리스트를 화면에 출력하거나 처리하는 구문을 넣을 수 있습니다

 

다음으로는 WifiScanReceiver를 IntentFilter에 등록하여 SCAN_RESULTS를 받을 수 있게 설정합니다

// MainActivity.java

private WifiScanReceiver mWifiScanReceiver;
private WifiManager mWifiManager;
private boolean mLocationPermissionApproved = false;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWifiScanReceiver = new WifiScanReceiver();
        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        registerReceiver(
                mWifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    }

이제 리시버도 등록했고 스캔 동작을 통한 결괏값을 확인만 하면 됩니다

제 경우에는 스캔 버튼을 클릭하면 스캔 시작이 되도록 했습니다

// MainActivity.java

private WifiScanReceiver mWifiScanReceiver;
private WifiManager mWifiManager;
private boolean mLocationPermissionApproved = false;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWifiScanReceiver = new WifiScanReceiver();
        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        registerReceiver(
                mWifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
                
        mainBinding.scanBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mLocationPermissionApproved =
                        ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
                                == PackageManager.PERMISSION_GRANTED;

                if (mLocationPermissionApproved) {
                    mWifiManager.startScan();
                }
            }
        });
    }

버튼을 클릭하면 ACCESS_FINE_LOCATION 권한을 확인한 뒤

권한이 승인되어 있다면 WifiManager를 통해 startScan을 호출합니다

Scan이 완료되면 IntentFilter에 등록한 WifiReceiver 쪽으로 결괏값이 호출됩니다

728x90
반응형

댓글