Android - 네트워크(WIFI) 연결 상태 확인 및 변경 감지

JS · 04 May 2020

이전에는 ConnectivityManager.CONNECTIVITY_ACTION 인텐트를 받아서 네트워크 연결 상태 정보를 받을 수 있었습니다. 하지만, Android 7.0(API 24) 이상의 버전을 타겟팅하는 앱은 이 인텐트를 받을 수 없습니다.

이제는 브로드캐스트 리시버로 네트워크(WIFI) 연결 정보를 받을 수 없고, registerNetworkCallback() API로 리스너를 등록하여 받을 수 있도록 변경되었습니다. (성능 문제로 Broadcast 방식에서 Listener 방식으로 변경한 것 같습니다.)

예제 코드는 모두 kotlin으로 작성되었습니다.

네트워크(WIFI) 연결 상태 정보 받기

먼저 AndroidManifest.xml에 다음과 같이 퍼미션을 요청해야 합니다.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

다음은 callback 객체를 생성하여 리스너를 등록, 해지하는 코드입니다.

private val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        Log.d("Test", "wifi available")
    }

    override fun onLost(network: Network?) {
        Log.d("Test", "wifi unavailable")
    }
}

private fun registerNetworkCallback() {
    val cm = getSystemService(ConnectivityManager::class.java)
    val wifiNetworkRequest = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .build()
    cm.registerNetworkCallback(wifiNetworkRequest, networkCallback)
}

private fun unregisterNetworkCallback() {
    val cm = getSystemService(ConnectivityManager::class.java)
    cm.unregisterNetworkCallback(networkCallback)
}
  • onAvailable() : WIFI가 연결될 때 호출됩니다. WIFI가 연결된 상태에서 리스너가 등록되도 호출됩니다.
  • onLost() : WIFI 연결이 끊길 때 호출됩니다. WIFI가 연결되지 않은 상태에서 리스너가 등록되도 호출되지 않습니다.

그리고 다음과 같이 onResume()에서 리스너를 등록하고 onStop()에서 리스너를 해지하면 됩니다.

override fun onResume() {
    super.onResume()
    registerNetworkCallback()
}

override fun onStop() {
    super.onStop()
    unregisterNetworkCallback()
}

네트워크(WIFI) 연결 정보 가져오기

WIFI가 연결되지 않은 상태에서 리스너가 등록되도 onLost()는 호출되지 않습니다.

다음은 리스너를 등록하지 않고 WIFI 연결 상태를 가져오는 코드입니다.

fun isWIFIConnected(context: Context): Boolean {
    var result = false
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE)
            as ConnectivityManager
    val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
    if (capabilities != null) {
        if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
            result = true
        } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
            result = false
        }
    }
    return result
}

참고