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
'개발 > Android' 카테고리의 다른 글
[안드로이드/kotlin] scale 애니메이션을 통한 버튼 클릭 효과 추가하기(android scale animation bounce effect) (0) | 2022.06.27 |
---|---|
[안드로이드/kotlin] 카카오톡 채널 연결하기(채널 추가하기, 채널 채팅하기) (0) | 2022.06.07 |
[안드로이드/오류] API 통신 시 발생하는 SocketTimeoutException (0) | 2022.06.06 |
[안드로이드/오류] 푸시 FirebaseMessagingService IllegalArgumentException 오류 (0) | 2022.06.06 |
[안드로이드/kotlin] 특정 날짜까지 남은 시간 타이머 만들기(CountDownTimer) (0) | 2022.05.31 |