네트워크 설정 공식 레퍼런스
https://developer.android.com/training/basics/network-ops/reading-network-state?hl=ko
네트워크 상태 읽기 | Connectivity | Android Developers
네트워크 상태 읽기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Android에서는 앱이 연결의 동적 변경사항을 학습할 수 있습니다. 다음 클래스를 사용하여
developer.android.com
우리는 앱을 사용하다 보면 네트워크의 연결에 대한 알림을 주는 것을 많이 볼 수 있다.
네트워크 연결 상태를 관리하고 모니터링하여보다 사용자에게 편리함을 제공해주고자 이 부분에 대해서 공략을 해보고자 하였습니다.
네트워크 권한 설정부터 진행을 하도록 하겠습니다.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
- 이 권한은 앱이 인터넷을 사용할 수 있도록 허용합니다.
- 인터넷 권한이 필요한 경우, 앱은 네트워크를 통해 데이터를 다운로드하거나 업로드하고 웹 서비스와 통신할 수 있습니다.
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 이 권한은 앱이 네트워크 상태에 대한 정보에 접근할 수 있도록 허용합니다.
- 네트워크 상태를 확인할 때 사용되며, 예를 들어 현재 기기가 Wi-Fi에 연결되어 있는지, 데이터 네트워크를 사용할 수 있는지 등을 확인할 수 있습니다.
기본적인 이해 (네트워크 순간 상태 가져오기)
val connectivityManager = getSystemService(ConnectivityManager::class.java)
val currentNetwork = connectivityManager.getActiveNetwork()
val caps = connectivityManager.getNetworkCapabilities(currentNetwork)
val linkProperties = connectivityManager.getLinkProperties(currentNetwork)
기본 네트워크의 참조를 가져와 네트워크 정보를 요청하여 알아보려 합니다.
`NetworkCapabilities` 및 `LinkProperties` 객체는 네트워크에 관해 시스템이 알고 있는 모든 속성 정보를 제공합니다.
네트워크 이벤트 수신대기
connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network : Network) {
Log.e(TAG, "The default network is now: " + network)
}
override fun onLost(network : Network) {
Log.e(TAG, "The application no longer has a default network. The last default network was " + network)
}
override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) {
Log.e(TAG, "The default network changed capabilities: " + networkCapabilities)
}
override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) {
Log.e(TAG, "The default network changed link properties: " + linkProperties)
}
})
`onAvailable` : 네트워크가 이용이 가능해질 때 호출
`onLost` : 네트워크가 소실 되었을 때 호출 **(디바이스가 모든 네트워크 연결을 잃었을 때 호출)**
`onCapabilitiesChanged` : 네트워크 기능이 변경되었을 때 호출
`onLinkPropertiesChanged` : 기본 네트워크의 링크 속성이 변경되었을 때 호출
`onAvailable`과 `onLost`를 공식문서의 내용을 살펴보면
네트워크 이용이 가능할 때 와 네트워크가 모든 연결을 잃었을때! 라고 하였지만
네트워크 이슈(문제 사항)
연결을 하나 끊었을때나 연결이 되었을 때 호출이 되는 모습을 확인할 수 있었습니다.
그것에 대한 가설
- Wi-Fi 및 셀룰러 데이터 모두 켜져 있을 때
- onAvailable 콜백이 호출되어 Wi-Fi 및 셀룰러 데이터가 모두 이용 가능한 상태를 나타냄
- Wi-Fi 또는 셀룰러 데이터 중 하나를 끌 때
- 해당하는 onLost 콜백이 호출될 것. 기존 이용가능하던 네트워크가 소실
- Wi-Fi 및 셀룰러 데이터 둘 다 끌 때
- onLost 콜백이 호출되고 네트워크 전부 소실
- Wi-Fi 또는 셀룰러 데이터 중 하나를 다시 켤 때
- onAvailable 콜백이 호출되어 다시 이용 가능한 상태
즉, 어떤 연결이나 소실이 되었을때 무조건 available, lost가 호출이 된다!
위의 기본적인 내용을 토대로 **NetworkManager** 를 만들어 보았습니다.
class NetworkManager @Inject constructor(private val connectivityManager: ConnectivityManager) {
private val _isNetworkConnected = MutableStateFlow(isInternetOn())
val isNetworkConnected: StateFlow<Boolean> = _isNetworkConnected
private val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
private fun isInternetOn() : Boolean{
val network = connectivityManager.activeNetwork
val connection = connectivityManager.getNetworkCapabilities(network)
return connection != null &&(
connection.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
connection.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
}
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
_isNetworkConnected.value = isInternetOn()
}
override fun onLost(network: Network) {
_isNetworkConnected.value = isInternetOn()
}
}
fun startNetwork() {
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}
fun endNetwork() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
}
데이터와 와이파이에 대한 state를 동시에 관찰하여 진행을 해보면 어떨까? 라는 생각으로 inInternetOn() 을 만들어 진행해보았습니다.
그 결과 네트워크에 대한 관찰이 정상적으로 되는 모습을 확인할 수 있습니다!
하지만 최종문제
가끔씩 두가지 모두 state를 관찰하지만 두개가 연결되어있는 상황에 하나의 연결을 끊었을 때 아주 짧은 시간 사이에 네트워크가 변경이 되면서 두가지가 잠시 연결이 끊기는 현상이 발견됩니다.
이 부분에 대해서는 알아보니 금융앱같은 경우 심도있게 다루겠지만 그런게 정말! 중요한 앱이 아니라면 이정도 까지는 아니다가 저의 결론이지만 다음에 시간이나면 이어서 고찰해보는걸로..
'Android & Kotlin > Android' 카테고리의 다른 글
[Android Kotlin] 의존성 주입 Hilt, koin (1) | 2024.01.03 |
---|---|
[Android kotlin] 안드로이드 Flow vs LiveData (0) | 2024.01.02 |
[안드로이드 코틀린] 리사이클러뷰 뷰타입에 따른 설정 (실습 : 채팅방) (0) | 2023.05.13 |
[안드로이드 코틀린] 바텀네비게이션 프래그먼트 전환시 상태 유지 (0) | 2023.05.09 |
[코틀린] 안드로이드 리사이클러뷰 특정뷰(아이템) 클릭 (0) | 2022.12.29 |
댓글