안드로이드 7.0부터 백그라운드 작업 최적화를 위해 몇 가지 브로드캐스트를 받을 수 없게 되었다. 이중에 네트워크 연결 상태 변경을 알리는 CONNECTIVITY_ACTION는 포함된다. 다만, (일명) AndroidManifest.xml에 미리 등록하여 PackageManager에서 관리하는 정적 브로드캐스트리시버에 한하며, Context.registerReceiver()에 등록하여 사용하는 동적 브로드캐스트리시버는 가능하다. 그럼, 정적 브로드캐스트리시버를 동적 브로드캐스트리시버로 바꾸면 될까?
CONNECTIVITY_ACTION은 네트워크 상태가 변경되었다는 사실만 알려주기 때문에, 현재 네트워크 상태가 WiFi이나 모바일인지, 국내 접속인지 로밍인지 등을 확인하려면 다시 ConnectivityManager 시스템 서비스를 이용해 추가적인 작업이 필요하다. 일회성 확인이라면 모르겠지만, 액션이 올 때마다 확인한다면 그리 효율적이지는 않다.
ConnectivityManager에서는 API 24부터 네트워크 상태에 대한 콜백을 달 수 있도록 지원한다. 어차피 이제 CONNECTIVITY_ACTION을 동적으로만 받을 수 있으니, 이왕이면 새로운 기능을 사용하자. 콜백을 등록할 때, 콜백이 호출되는 조건을 함께 전달할 수 있다. NetworkRequest.Builder 클래스를 이용해 조건을 만들면 된다.
기존 액션을 완전히 대체하는 수준으로만 사용할 수도 있다. 아래는, 네트워크가 연결/해제 되었을 때 콜백을 받는 간략한 예제다.
ConnectivityManager cm = (ConnectivityManager) getContext() .getSystemService( Context.CONNECTIVITY_SERVICE ); Builder builder = new NetworkRequest.Builder(); cm.registerNetworkCallback( builder.build(), new ConnectivityManager.NetworkCallback() { @Override public void onAvailable( Network network ) { //네트워크 연결됨 } @Override public void onLost( Network network ) { //네트워크 끊어짐 } } );
그 밖에
ConnectivityManager.unregisterNetworkCallback()을 이용해 등록한 콜백을 해제하는 것도 잊지 말자.
NetworkCallback()은 콜백을 보내기 위해 따로 생성된 HandlerThread에서 실행되니 UI를 바꾸고 싶다면, View.post(), Activity.runOnUiThread(), Handler() 등을 통해 메인 스레드로 전달하자.
참조