-
Connectivity 가 변경되었을 때 받을 수 있는 broadcast 는 ConnectivityManager.CONNECTIVITY_ACTION 가 있었다.
그러나 이 녀석은 API 28 (POS) 부터 deprecated 되었다.
-
사실 이 녀석은 이미 deprecated 의 징조를 띄고 있었다.
targetSdk 24 (NOS) 부터 static receiver 로 받을 수 없게 되었고,
targetSdk 26 (OOS) 부터는 background restriction 정책으로 이 녀석을 포함한 다른 녀석들도 static receiver 로 받을 수 없게 되었다.
그리고 결국 API 28 (POS) 부터는 deprecated 된 것이다.
deprecated 가 되었기 때문에 사실 targetSdk 28 (POS) 부터는 못 받아도 할 말이 없는 녀석이긴 한데..
QOS 부터는 이 녀석들이 targetSdk 상관없이 동작을 확 변경되므로, 미리 대비해 두는 것이 좋아보인다.
-
ConnectivityManager.CONNECTIVITY_ACTION broadcast 을 대신해 사용할 수 있는 API 는 다음과 같다.
requestNetwork(NetworkRequest, PendingInent)
registerNetworkCallback(NetworkRequest, PendingIntent)
registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback)
위 API 들을 통해서 더 빠르게, 관심있는 network 에 대한 더 디테일한 정보를 받을 수 있다.
ConnectivityManager.requestNetwork(NetworkRequest, PendingIntent) - Link
-
API 22(LOS MR1) 에 소개된 API 이다.
NetworkCapabilities 를 충족하는 network 를 요청한다.
이 녀석은 networkCallback 을 전달하는 API 와 동일한데, 대신 PendingIntent 를 사용하기 때문에 life time 이 더 길다고 볼 수 있다.
-
PendingIntent 는 broadcast intent 이다.
여기는 두개의 extra 가 들어가는데, EXTRA_NETWORK 에 Network 객체가, 그리고 EXTRA_NETWORK_REQUEST 에 NetworkRequest 객체(요청한 녀석과 동일)가 들어있다.
-
동일한 NetworkRequest 가 등록되면, 기존것을 대체한다.
-
releaseNetwork(PendingIntent) 를 통해 request 가 release 될 수 있다.
-
NetworkCapabilities.NET_CAPABILITY_VALIDATED 나 NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL 에 대한 network request 는 현재 지원되지 않는다.
이 capabilities 는 특정 network 에서 절대 발생하지 않고, network 에서 미리 알 수 없는 상태이기 때문이다.
-
이 함수를 호출하려면
Manifest.permission.CHANGE_NETWORK_STATE permission 을 갖거나,
시스템에 등록되어 Settings.System.canWrite(Context) 호출시 true 가 return 되어야 한다.
registerNetworkCallback(NetworkRequest, ConnectivityManager.NetworkCallback) - Link
-
API 21 (LOS) 에 소개된 API 다.
주어진 NetworkRequest 조건에 맞는 network 에 대한 notification 을 받도록 callback 을 등록하는 함수이다.
unregisterNetworkCallback(NetworkCallback) 이 불리기 전까지 계속 불린다.
Manifest.permission.ACCESS_NETWORK_STATE 의 권한이 요구된다.
registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) - Link
-
API 24 (NOS) 에 소개된 API 이다.
이는 System default network 에 대한 change 를 notification 으로 받는다.
unregisterNetworkCallback(NetworkCallback) 이 불릴때까지 계속 불린다.
Manifest.permission.ACCESS_NETWORK_STATE 권한이 요구된다.
API 살펴봤으니 NetworkCallback 에 대해서도 알아본다. - Link
public static class NetworkCallback { // 여기 명시되지 않은 hide 된 몇몇 함수들도 있다. public void onAvailable(Network network) {} public void onLosing(Network network, int maxMsToLive) {} public void onLost(Network network) {} public void onUnavailable() {} public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {} public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {} }
테스트를 통한 동작 확인
registerNetworkCallback Test
-
WIFI 가 연결되어 있는 상태에서 다음과 같이 callback 을 등록하면..
val cm = getSystemService(ConnectivityManager::class.java) val wifiNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build() val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { Log.e("cklee", "MMMM network : $network") } override fun onLost(network: Network?) { Log.e("cklee", "MMMM lost network : $network") } } cm.registerNetworkCallback(wifiNetworkRequest, callback)
이 상태에서 와이파이 연결을 해제 -> 바로 onLost 함수가 불림.
와이파이가 연결되어 있지 않은 상태 -> register -> onLost 가 불리지는 않음.
함수명에 맞게 잘 동작한다. onLost 는 실제 연결이 끊어졌을때만 불린다. ( Available 은 가능성을 보는 것이기 때문에 바로 불리는 것이 reasonable 하다.)
이 상태에서 와이파이 연결 -> 바로 onAvailable 함수 불림.
-
Network 객체의 toString 은 hashCode 를 print 하도록 되어 있음.
매 onAvailable 시마다 hash 값이 달라지므로 다른 Network 객체가 생성되어 들어온다고 볼 수 있다.
registerDefaultNetworkCallback Test
위와 같은 방식으로 테스트하는데, 등록 API 만 registerDefaultNetworkCallback 로 바꾼다.
default 의 의미를 이해하기 위해 Wifi 와 data 를 껐다 켰다를 반복해보았다.
-
data 와 wifi 두 가지 network 모두 붙여놓은 상태 -> register -> onAvailable callback 이 1회 불림.
이 상태에서 data off -> onLost 불리지 않음. 메인(default)가 network 가 Wifi 이기 때문인 듯 하다.
이 상태에서 wifi off -> onLost 가 불린다. ( onAvailable 당시 hash 값과 동일한 녀석이 lost 된다. )
-
register 상태 & 두 network 모두 off 상태 -> wifi on -> onAvailable callback 불림
이 상태에서 data on -> onAvailable 불리지 않음.
역시나 메인(default) network 는 wifi 이기 때문이라고 이해하면 이해가 된다.
-
wifi 가 우선순위를 갖고 메인(default) network 가 되기 때문에 data 를 위주로 추가 테스트 해보았다.
register & 두 network 모두 on -> wifi off -> onAvailable 불림.
이 때 hash 는 처음 register 당시의 hash 가 아님, 즉 data network 의 hash 로 해석되며, data network 가 available 하다고 callback 이 불린 것이다.
이 상태에서 wifi on -> onAvailable 불림.
data network 가 lost 된 것이 아니라 onLost 는 불리지 않고, default 가 바뀌었기 때문에 wifi 에 대한 onAvailable callback 이 불린다.
이 상태에서 wifi off -> onAvailable 불림.
위의 wifi off 시 onAvailable 에 전달된 hash 와 다른 것으로 보아, onAvailable 이 불릴 때마다 객체 재활용 없이 새로운 녀석이 온다고 보면 될 것 같다.
참고사항이지만 중요한 정보
-
callback 은 ConnectivityThread 라는 HandlerThread 에서 호출된다.
참고 사이트
https://proandroiddev.com/connectivity-network-internet-state-change-on-android-10-and-above-311fb761925 (API Level Compat 하게 만드는 방법)
끝
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] concurrent document에 대해 알아본다. (0) | 2019.04.25 |
---|---|
[android] QUOTED-PRINTABLE 의 예외처리 =\r\n (0) | 2019.04.10 |
[Effective Unit Testing] Appendix B. JUnit 확장하기 (0) | 2019.03.29 |
[Effective Unit Testing] Appendix A. JUnit 기초 (0) | 2019.03.20 |
[Effective Unit Testing] Chap9. 테스트 속도 개선 (0) | 2019.03.19 |
댓글