개발새발 - IT 기술블로그
article thumbnail

안녕하세요. 이번 포스팅에서는 안드로이드의 WifiManager를 이용하여 연결 가능한 와이파이의 목록을 스캔하는 기능을 구현해보겠습니다. 가장 간단하게 목록만 출력하는 예제이니 연결이나 다른 기능들은 사용하지 않았습니다.

 

 


개요

해당 포스팅에서는 WiFi 목록을 호출하기 위한 권한 요청과 WifiManager 객체를 생성하여 스캔하고 결과를 리스트에 추가하는 예제입니다.

 

 

본문

 

권한 요청

 

먼저 AndroidManifest 파일에 권한을 사용하겠다고 명시해줍니다.

권한은 인터넷사용 + 현재위치 + 와이파이 접근 총 5가지입니다.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

 

 

다음으로 유저에게 민감정보인 위치권한을 직접 요청하는 코드를 작성합니다.

private fun requestPermission(activity: Activity) {
    if(ActivityCompat.checkSelfPermission(activity,
            android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        || ActivityCompat.checkSelfPermission(activity, 
            android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        val permissions = arrayOf(
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        )
        ActivityCompat.requestPermissions(activity, permissions, 1)
    }
}

 

 

 

WiFi 스캔하기

그 후, WifiManager를 생성하고 스캔 결과를 담을 변수를 ScanResult 타입의 리스트로 생성합니다.

val wifiManager = application.getSystemService(Context.WIFI_SERVICE) as WifiManager

val result: List<ScanResult> = wifiManager.scanResults

 

 

스캔을 시작할 버튼을 바인딩하고 스캔 결과를 로그를 통해 확인합니다.

val btnScan: Button = findViewById(R.id.btnScan)
btnScan.setOnClickListener {
    result.forEach {
        Log.i("WIFI_RESULT", "SSID : ${it.SSID} BSSID : ${it.BSSID}")
    }
}

 

 

결과를 확인하면 아래와 같이 연결 할 수 있는 와이파이에 대한 정보가 출력되는 것을 확인하실 수 있습니다.

 

 

유용한 정보 불러오기

 

※ 2024.03.20 추가

 

SSID와 MAC 주소 이외에 활용할만한 정보들이 어떤 것들이 있는지 알아보겠습니다.

 

 

 

 

1. Wifi Level

 

Wifi Level은 현재 와이파이의 신호 세기가 어느정도인지를 의미하는 값입니다.

 

result의 level 변수를 불러와서 사용하시면 되는데, 그냥 숫자만 적으면 체감이 잘 안될테니 값에 따라 이미지로 표현해보겠습니다.

 

private fun parseLevel(level: Int): Drawable? {
    return ResourcesCompat.getDrawable(
        context.resources,
        when {
            level >= -30 -> { R.drawable.level_wifi_4 }
            level in -30 downTo -60 -> { R.drawable.level_wifi_4 }
            level in -60 downTo -70 -> { R.drawable.level_wifi_3 }
            else -> { R.drawable.level_wifi_1 }
        }, null
    )
}

 

 

 

값의 경계를 설정한 기준은 찾아보니까 표준? 비슷한 값들이 있더라구요. 그래서 그 값을 사용했습니다. 결과를 확인해보시죠.

(Address 값은 너무 길어서 제외시켰습니다)

 

 

 

 

와이파이의 신호에 따라 총 4가지의 이미지로 분리하여 적용되었습니다.

 

솔직히 정렬이 안되어있는게 불편하군요...

 

 

level 값에 따라 내림차순 정렬하겠습니다.

val descendingList = result.sortedByDescending { it.level }

 

 

 

 

훨씬 보기 깔끔하네요 ㅎㅎㅎ

 

 

 

 

2. 보안 설정

 

이제 와이파이에 비밀번호가 걸려있는지를 확인해보겠습니다.

 

capability 변수를 불러와서 사용하시면 되는데요.

 

데이터 타입은 String인데 보안쪽의 지식이 깊지 않아서 각각의 값에 따라 세세하게 분류하진 않았고, 비밀번호가 걸려있는지 아닌지만 확인하였습니다.

 

fun isCapability(capabilities: String): Boolean {
    return capabilities.contains("WPA") || capabilities.contains("WPA2")
            || capabilities.contains("WEP")
}

 

 

 

전부 다 보안이 걸려있어서 케이스 별 확인이 안되긴 하는데..

capabilities=[WPA-PSK-CCMP][WPA2-PSK-CCMP][RSN-PSK-CCMP][ESS]
capabilities=[WPA2-PSK-CCMP][RSN-PSK-CCMP][ESS]
capabilities=[WPA2-PSK-CCMP][RSN-PSK-CCMP][ESS][WPS]

 

이런식으로 각기 다른 값들을 불러옵니다. 

 

 

 

3. 대역폭 변환

 

대역폭 변환은 frequency 변수를 통해 불러올 수 있습니다.

 

5G, 2.4G 같은 아이들이 대역폭에 해당하죠. 실제로 frequency는 Integer 값을 불러들어옵니다. 

 

2.4G는 2400에서 2484 사이를 의미하고, 5G는 5000이상을 의미하는데요. 우리가 흔히 알고있는 5G, 2.4G는 이 값들을 변환시킨 것이라고 보시면 됩니다.

private fun parseFrequency(frequency: Int): String {
    return if (frequency in 2400..2484) {
        "2.4G"
    } else if (frequency >= 5000) {
        "5G"
    } else {
        ""
    }
}

 

 

 

 

 

결론

 

이번 포스팅에서 현재 위치를 기반으로 연결 가능한 와이파이의 정보를 불러오는 WifiManager에 대해 알아보았는데요.

 

 

지속적인 스캔이나 특정 간격을 두고 스캔하여 변화를 확인하고 싶을 땐 BroadcastReceiver에 등록하고 startScan() 메서드를 호출하여 사용하실 수 있습니다. 감사합니다.

 

 

 

 

 

참고

https://developer.android.com/guide/topics/connectivity/wifi-scan?hl=ko 

 

Wi-Fi 검색 개요  |  Android 개발자  |  Android Developers

Wi-Fi 검색 개요 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. WifiManager API가 제공하는 Wi-Fi 검색 기능을 사용하여 기기에 보이는 Wi-Fi 액세스 포인트의 목록

developer.android.com

 

 

예제소스

https://github.com/tekken5953/WifiManagerExam

 

GitHub - tekken5953/WifiManagerExam

Contribute to tekken5953/WifiManagerExam development by creating an account on GitHub.

github.com