숨참고 개발다이브

[안드로이드/kotlin] 인터넷 연결 상태 확인하기 본문

개발/Android

[안드로이드/kotlin] 인터넷 연결 상태 확인하기

사라 Sarah 2022. 6. 8. 16:06
728x90

종종 UnknownHostException이라는 오류를 만날 수 있는데, 인터넷 연결 Permission을 사용하지 않았거나, 인터넷 통신 상태때문에 발생한다.

 

퍼미션 문제라면 아래 코드를 AndroidManifes.xml에 넣어주면 된다.

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

 

 

인터넷 연결 문제라면 통신 상태를 체크해 인터넷에 연결되지 않도록 막아준다.

인터넷 상태를 확인하기 위해 기본적인 객체들을 생성해주어야한다.

 

val connectivityManager = getSystemService(ConnectivityManager::class.java)

ConnectivityManager는 연결 상태를 알려준다.

 

val currentNetwork = connectivityManager.getActiveNetwork()

connectivityManager를 통해 Network 객체를 가져온다. 

 

val caps = connectivityManager.getNetworkCapabilities(currentNetwork)
val linkProperties = connectivityManager.getLinkProperties(currentNetwork)

NetworkCapabilities 객체는 Wifi, 셀룰러 등의 네트워크 속성 정보가 들어있다.

LinkProperties 객체에는 네트워크에 설치된 DNS서버, 로컬 IP주소 등의 정보가 포함되어있다.

 

지금은 연결 정보가 필요하기 때문에 NetworkCapabilities만 사용하였다.

 

 

if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
    val currentNetwork = connectivityManager.activeNetwork ?: return TYPE_NOT_CONNECTED
    val caps = connectivityManager.getNetworkCapabilities(currentNetwork) ?: return TYPE_NOT_CONNECTED

    return when {
        caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return TYPE_WIFI
        caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return TYPE_MOBILE
        else -> return TYPE_NOT_CONNECTED
    }
}
else {
    connectivityManager.run {
        connectivityManager.activeNetworkInfo?.run {

            return when (type) {
                ConnectivityManager.TYPE_WIFI -> return TYPE_WIFI
                ConnectivityManager.TYPE_MOBILE -> return TYPE_MOBILE
                else -> return TYPE_NOT_CONNECTED
            }

        }
    }
}

getActiveNetworkInfo() 는 API 레벨 29 에 deprecated되고, ConnectivityManager.TYPE_ 은 28 레벨에 deprecated 된다고 한다. (애매하게...) 그래서 if문으로 버전별 동작을 나누어주었다.

이더넷 연결 상태도 확인 가능하나 유선랜으로 사용하는 사람은 없기때문에 따로 넣지는 않았다.

 

이더넷 상태 코드

// API 28 이상
caps.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)

// 그 이하
ConnectivityManager.TYPE_ETHERNET

 

 

코드 전체

class NetworkStatus {

    companion object {
        const val TYPE_WIFI = 1
        const val TYPE_MOBILE = 2
        const val TYPE_NOT_CONNECTED = 3


        fun getConnectivityStatus(context: Context): Int {
            val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
                val currentNetwork = connectivityManager.activeNetwork ?: return TYPE_NOT_CONNECTED
                val caps = connectivityManager.getNetworkCapabilities(currentNetwork) ?: return TYPE_NOT_CONNECTED

                return when {
                    caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return TYPE_WIFI
                    caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return TYPE_MOBILE
                    else -> return TYPE_NOT_CONNECTED
                }
            }
            else {
                connectivityManager.run {
                    connectivityManager.activeNetworkInfo?.run {

                        return when (type) {
                            ConnectivityManager.TYPE_WIFI -> return TYPE_WIFI
                            ConnectivityManager.TYPE_MOBILE -> return TYPE_MOBILE
                            else -> return TYPE_NOT_CONNECTED
                        }

                    }
                }
            }

            return TYPE_NOT_CONNECTED
        }

    }

}

 

사용

if ( NetworkStatus.getConnectivityStatus( context ) == NetworkStatus.TYPE_NOT_CONNECTED ) {
    // 네트워크가 연결 상태가 아닐 때
}

 

300x250
Comments