네트워크 상태 읽기

Android에서는 앱이 연결의 동적 변경사항을 학습할 수 있습니다. 다음 클래스를 사용하여 연결 변경사항을 추적하고 적절히 대응하세요.

  • ConnectivityManager는 앱에 시스템의 연결 상태를 알립니다.
  • Network 클래스는 기기가 연결된 네트워크 중 하나를 나타냅니다. Network 객체를 키로 사용하여 ConnectivityManager와 함께 네트워크 정보를 수집하거나 네트워크에서 소켓을 결합할 수 있습니다. 네트워크 연결이 끊어지면 Network 객체의 사용이 중지됩니다. 나중에 기기가 동일한 어플라이언스에 다시 연결되더라도 새 Network 객체는 새 네트워크를 나타냅니다.
  • LinkProperties 객체에는 네트워크에 설치된 DNS 서버, 로컬 IP 주소, 네트워크 경로 목록 등의 네트워크 연결 정보가 포함됩니다.
  • NetworkCapabilities 객체에는 전송(Wi-Fi, 모바일, 블루투스) 및 네트워크에서 사용할 수 있는 기능과 같은 네트워크 속성 정보가 포함됩니다. 예를 들어 객체를 쿼리하여 네트워크가 MMS를 전송할 수 있는지, 종속 포털을 지원하는지 또는 데이터 전송량 제한이 있는지 확인할 수 있습니다.

어느 때든 즉각적인 연결 상태를 알고자 하는 앱은 ConnectivityManager 메서드를 호출하여 사용할 수 있는 네트워크 종류를 확인할 수 있습니다. 이러한 메서드는 디버깅하는 데 도움이 되고, 어느 때든 사용 가능한 연결의 개요를 이따금 검토하는 데 유용합니다.

하지만 동기식 ConnectivityManager 메서드는 호출 후 발생하는 일에 관해 앱에 알리지 않으므로 UI를 업데이트할 수 없습니다. 또한 네트워크 연결 끊김이나 네트워크 기능 변경에 따라 앱 동작을 조정할 수도 없습니다.

연결은 언제든지 변경될 수 있으며 대부분의 앱은 기기의 네트워킹 상태 뷰를 항상 최신 상태로 유지해야 합니다. 앱은 ConnectivityManager에 콜백을 등록하여 앱에서 중요한 변경사항에 관해 알림을 받을 수 있습니다. 콜백을 사용하면 빠른 업데이트를 놓칠 수 있는 값비싼 폴링에 의존하지 않고 앱에서 연결의 관련 변경사항에 즉시 반응할 수 있습니다.

NetworkCallback 및 기기의 연결 상태를 파악하는 다른 방법을 사용하는 경우에는 특별한 권한이 필요하지 않습니다. 그러나 일부 네트워크에는 특정 권한이 적용됩니다. 예를 들어 앱에서 사용할 수 없는 제한된 네트워크가 있을 수 있습니다. 백그라운드 네트워크에 바인딩하려면 CHANGE_NETWORK_STATE 권한이 있어야 합니다. 일부 호출은 실행하려면 특정 권한이 필요할 수도 있습니다. 자세한 내용은 호출별 문서를 참고하세요.

순간적인 상태 가져오기

Android 지원 기기는 여러 연결을 동시에 유지할 수 있습니다. 현재 네트워크 상태에 관한 정보를 가져오려면 먼저 ConnectivityManager의 인스턴스를 가져옵니다.

Kotlin

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

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

이 인스턴스를 사용하여 앱의 현재 기본 네트워크에 관한 참조를 가져옵니다.

Kotlin

val currentNetwork = connectivityManager.getActiveNetwork()

Java

Network currentNetwork = connectivityManager.getActiveNetwork();

앱은 네트워크 참조를 사용하여 네트워크 정보를 요청할 수 있습니다.

Kotlin

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

Java

NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(currentNetwork);
LinkProperties linkProperties = connectivityManager.getLinkProperties(currentNetwork);

더 유용한 기능을 이용하려면 NetworkCallback을 등록하세요. 네트워크 콜백 등록에 관한 자세한 내용은 네트워크 이벤트 수신 대기를 참고하세요.

NetworkCapabilities 및 LinkProperties

NetworkCapabilitiesLinkProperties 객체는 네트워크에 관해 시스템이 알고 있는 모든 속성 정보를 제공합니다.

LinkProperties 객체는 경로, 링크 주소, 인터페이스 이름, 프록시 정보(있는 경우), DNS 서버에 관해 알고 있습니다. LinkProperties 객체의 관련 메서드를 호출하여 필요한 정보를 얻을 수 있습니다.

NetworkCapabilities 객체는 네트워크 전송 및 관련 기능 정보를 캡슐화합니다.

전송은 네트워크가 작동하는 실제 매체의 추상화입니다. 전송의 일반적인 예로는 이더넷, Wi-Fi, 모바일이 있습니다. VPN 및 P2P Wi-Fi도 포함될 수 있습니다. Android에서는 한 네트워크가 동시에 여러 개의 전송을 사용할 수 있습니다. 이러한 예로 Wi-Fi와 모바일 네트워크에서 모두 작동하는 VPN이 있습니다. VPN에는 Wi-Fi, 모바일, VPN 전송이 있습니다. 네트워크에 특정 전송이 있는지 확인하려면 NetworkCapabilities.TRANSPORT_* 상수 중 하나와 함께 NetworkCapabilities.hasTransport(int) 메서드를 사용합니다.

기능은 네트워크 속성을 설명합니다. 기능의 예로 MMS, NOT_METERED, INTERNET을 들 수 있습니다. MMS 기능이 있는 네트워크는 멀티미디어 메시지 서비스의 메시지를 송수신할 수 있지만, 이 기능이 없는 네트워크는 할 수 없습니다. NOT_METERED 기능이 있는 네트워크는 사용자에게 데이터 요금을 청구하지 않습니다. 앱에서는 NetworkCapabilities.NET_CAPABILITY_* 상수 중 하나와 함께 NetworkCapabilities.hasCapability(int) 메서드를 사용하여 적절한 기능을 확인할 수 있습니다.

가장 유용한 NET_CAPABILITY_* 상수는 다음과 같습니다.

  • NET_CAPABILITY_INTERNET: 네트워크가 인터넷에 액세스하도록 설정되었음을 나타냅니다. 이는 공개 서버에 도달할 수 있는 실제 기능이 아니라 설정에 관한 것입니다. 예를 들어, 네트워크는 인터넷에 액세스하도록 설정할 수 있지만, 종속 포털의 영향을 받을 수 있습니다.

    일반적으로 이동통신사의 모바일 네트워크에는 INTERNET 기능이 있지만, 로컬 P2P Wi-Fi 네트워크에는 없습니다. 실제 연결은 NET_CAPABILITY_VALIDATED를 참고하세요.

  • NET_CAPABILITY_NOT_METERED: 네트워크가 데이터 전송량 제한이 없음을 나타냅니다. 사용자가 금전적 비용, 데이터 한도 또는 배터리 성능 문제로 인해 이 연결의 과도한 데이터 사용량에 민감한 경우 네트워크는 데이터 전송량 제한 있음으로 분류됩니다.

  • NET_CAPABILITY_NOT_VPN: 네트워크가 가상 사설망(VPN)이 아님을 나타냅니다.

  • NET_CAPABILITY_VALIDATED: 프로브 시 네트워크가 공개 인터넷에 대한 실제 액세스 권한을 제공함을 나타냅니다. 종속 포털 뒤에 있는 네트워크나 도메인 이름 확인을 제공하지 않는 네트워크에는 이 기능이 없습니다. 이 시스템은 실제로 액세스를 제공하는 네트워크에 관해 알려줄 수 있는 가장 근접한 시스템이지만, 확인된 네트워크는 원칙적으로 여전히 IP 기반 필터링 또는 약한 신호와 같은 문제로 인해 갑자기 연결 손실이 발생할 수 있습니다.

  • NET_CAPABILITY_CAPTIVE_PORTAL: 프로브 시 네트워크에 종속 포털이 있음을 나타냅니다.

좀 더 전문화된 앱에서 관심을 가질만한 다른 기능도 있습니다. 자세한 내용은 NetworkCapabilities.hasCapability(int)의 매개변수 정의를 참고하세요.

네트워크의 기능은 언제든지 변경될 수 있습니다. 시스템에서 종속 포털을 감지하면 사용자가 로그인하도록 초대하는 알림을 표시합니다. 이 작업이 실행되는 동안 네트워크에 NET_CAPABILITY_INTERNETNET_CAPABILITY_CAPTIVE_PORTAL 기능은 있지만, NET_CAPABILITY_VALIDATED 기능은 없습니다.

사용자가 작업을 실행하고 종속 포털 페이지에 로그인하면 기기는 공개 인터넷에 액세스할 수 있고 네트워크는 NET_CAPABILITY_CAPTIVE_PORTAL 기능 대신 NET_CAPABILITY_VALIDATED 기능을 사용합니다.

마찬가지로, 네트워크 전송은 동적으로 변경될 수 있습니다. 예를 들어, VPN은 모바일에서 Wi-Fi로 기본 네트워크를 전환하는 등 방금 인식된 더 빠른 네트워크를 사용하도록 자체적으로 재구성할 수 있습니다. 이 경우 네트워크는 TRANSPORT_CELLULAR 전송 대신 TRANSPORT_WIFI 전송을 사용하지만, TRANSPORT_VPN 전송은 유지합니다.

네트워크 이벤트 수신 대기

네트워크 이벤트를 알아보려면 NetworkCallback 클래스를 ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback)ConnectivityManager.registerNetworkCallback(NetworkCallback)과 함께 사용합니다. 이 두 가지 메서드는 서로 다른 용도로 사용됩니다.

모든 Android 앱에는 시스템에서 결정하는 기본 네트워크가 있습니다. 시스템은 일반적으로 데이터 전송량 제한이 있는 네트워크보다 무제한 네트워크를, 느린 네트워크보다 빠른 네트워크를 선호합니다.

앱에서 네트워크 요청이 발생하면(예: HttpsURLConnection) 시스템은 기본 네트워크를 사용하여 이 요청을 처리합니다. 앱은 다른 네트워크에서도 트래픽을 전송할 수 있습니다. 자세한 내용은 추가 네트워크 섹션을 참고하세요.

기본 네트워크로 설정된 네트워크는 앱의 전체 기간 중 언제든지 변경될 수 있습니다. 일반적인 예로는 활성화되고 무제한이며 모바일보다 빠르다고 알려진 Wi-Fi 액세스 포인트의 범위 내에 있는 기기를 들 수 있습니다. 기기는 이 액세스 포인트에 연결하고 모든 앱의 기본 네트워크를 새 Wi-Fi 네트워크로 전환합니다.

새로운 네트워크가 기본값이 되면 앱이 여는 새 연결은 모두 이 네트워크를 사용합니다. 어느 시점이 지나면, 이전의 기본 네트워크에 남아있는 모든 연결이 강제 종료됩니다. 앱에서 기본 네트워크가 변경되는 시점을 알려면, 다음과 같이 기본 네트워크 콜백을 등록합니다.

Kotlin

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)
    }
})

Java

connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        Log.e(TAG, "The default network is now: " + network);
    }

    @Override
    public void onLost(Network network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network);
    }

    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities);
    }

    @Override
    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties);
    }
});

새 네트워크가 기본값이 되면 앱에서 새 네트워크의 onAvailable(Network) 호출을 수신합니다. onCapabilitiesChanged(Network,NetworkCapabilities), onLinkPropertiesChanged(Network,LinkProperties) 또는 둘 다 구현하여 연결의 변경사항에 적절하게 반응해야 합니다.

registerDefaultNetworkCallback()에 등록된 콜백의 경우 onLost()는 네트워크가 기본 네트워크로 설정된 상태를 상실했다는 의미입니다. 연결이 해제되었을 수 있습니다.

NetworkCapabilities.hasTransport(int)를 쿼리하여 기본 네트워크가 사용 중인 전송 방법을 알아볼 수 있지만, 이는 네트워크 대역폭 또는 한도 측정을 위한 프록시로 적합하지 않습니다. 앱은 Wi-Fi가 항상 무제한이고 모바일보다 더 나은 대역폭을 제공한다고 가정할 수 없습니다.

대신, NetworkCapabilities.getLinkDownstreamBandwidthKbps()를 사용하여 대역폭을 측정하고 NET_CAPABILITY_NOT_METERED 인수로 NetworkCapabilites.hasCapability(int)를 호출하여 데이터 전송량에 제한이 있는지 확인해야 합니다. 자세한 내용은 NetworkCapabilities 및 LinkProperties 섹션을 참고하세요.

기본적으로 콜백 메서드는 ConnectivityManager에서 사용하는 별도의 스레드인 앱의 연결 스레드에서 호출됩니다. 콜백 구현에서 더 많은 작업을 해야 한다면 ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler)의 변형을 사용하여 별도의 작업자 스레드에서 콜백을 호출합니다.

더 이상 콜백을 사용하지 않는다면 ConnectivityManager.unregisterNetworkCallback(NetworkCallback)을 호출하여 콜백을 등록 취소하세요. 기본 활동의 onPause()는 이를 처리하기 좋은 장소이며, 특히 onResume()에 콜백을 등록한 경우 더 그렇습니다.

추가 네트워크

기본 네트워크가 대부분의 앱과 관련된 유일한 네트워크이지만, 일부 앱은 사용 가능한 다른 네트워크에 관심이 있을 수 있습니다. 이러한 네트워크를 찾기 위해 앱은 요구사항에 맞는 NetworkRequest를 빌드하고 ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback)을 호출합니다.

프로세스는 기본 네트워크를 수신하는 것과 유사합니다. 그러나 특정 시점에 앱에 적용되는 기본 네트워크는 하나만 있을 수 있지만 이 버전을 사용하면 앱이 사용 가능한 모든 네트워크를 동시에 볼 수 있으므로 onLost(Network) 호출은 네트워크가 더 이상 기본 네트워크가 아니라는 것이 아니라 영구적으로 연결 해제되었다는 의미입니다.

앱은 NetworkRequest를 빌드하여 수신 대기하려는 네트워크의 종류를 ConnectivityManager에 알립니다. 다음 예에서는 무제한 인터넷 연결에만 관심이 있는 앱의 NetworkRequest를 빌드하는 방법을 보여줍니다.

Kotlin

val request = NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build()

connectivityManager.registerNetworkCallback(request, myNetworkCallback)

Java

NetworkRequest request = new NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build();

connectivityManager.registerNetworkCallback(request, myNetworkCallback);

즉, 앱이 시스템의 무제한 네트워크와 관련된 모든 변경사항을 수신합니다.

기본 네트워크 콜백의 경우 Handler를 허용하는 registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) 버전이 있으므로 앱의 Connectivity 스레드가 로드되지 않습니다.

콜백이 더 이상 관련이 없는 경우 ConnectivityManager.unregisterNetworkCallback(NetworkCallback)을 호출합니다. 앱은 동시에 여러 네트워크 콜백을 등록할 수 있습니다.

편의를 위해 NetworkRequest 객체에는 다음을 포함하여 대부분의 앱에서 필요한 공통 기능이 포함되어 있습니다.

앱을 작성할 때 기본값을 검토하여 사용 사례와 일치하는지 확인하고 이러한 기능이 없는 네트워크에 관한 알림을 앱이 받도록 하려면 기본값을 삭제하세요. 반면 앱이 상호작용하지 않는 네트워크의 연결 변경에 관해 호출되지 않도록 기능을 추가합니다.

예를 들어 앱에서 MMS 메시지를 보내야 하는 경우 NetworkRequestNET_CAPABILITY_MMS를 추가하여 MMS 메시지를 보낼 수 없는 모든 네트워크에 관해 알림을 받지 않도록 합니다. 앱이 P2P Wi-Fi 연결에만 관심이 있으면 TRANSPORT_WIFI_AWARE를 추가합니다. NET_CAPABILITY_INTERNETNET_CAPABILITY_VALIDATED는 인터넷상의 서버로 데이터를 전송하는 기능에 관심이 있는 경우에 유용합니다.

샘플 콜백 시퀀스

이 섹션에서는 앱이 기본 콜백과 일반 콜백 모두 모바일 연결이 있는 기기에 등록할 때 앱이 얻을 수 있는 콜백 시퀀스를 설명합니다. 이 예에서는 기기가 양호한 Wi-Fi 액세스 포인트에 연결한 다음 연결 해제합니다. 또한, 이 예에서는 기기가 모바일 데이터 상시 사용이 설정되어 있다고 가정합니다.

타임라인은 다음과 같습니다.

  1. 앱에서 registerNetworkCallback()을 호출하면 모바일 네트워크만 사용할 수 있으므로 콜백은 즉시 이 네트워크의 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged()에서 호출을 수신합니다. 다른 네트워크를 사용할 수 있는 경우 앱은 다른 네트워크의 콜백도 수신합니다.

    네트워크 콜백 이벤트 등록과 이벤트에서 트리거하는 콜백을 보여주는 상태 다이어그램
    그림 1. registerNetworkCallback() 호출 후 앱 상태

  2. 그런 다음 앱에서 registerDefaultNetworkCallback()을 호출합니다. 모바일 네트워크가 기본 네트워크이므로 기본 네트워크 콜백은 모바일 네트워크의 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged() 호출을 수신하기 시작합니다. 기본이 아닌 다른 네트워크가 작동 중이면 앱은 기본이 아닌 네트워크의 호출을 수신할 수 없습니다.

    기본 네트워크 콜백 이벤트 등록 및 이벤트에서 트리거하는 콜백을 보여주는 상태 다이어그램
    그림 2. 기본 네트워크를 등록한 후의 앱 상태

  3. 추후 기기가 (무제한) Wi-Fi 네트워크에 연결됩니다. 일반 네트워크 콜백은 Wi-Fi 네트워크의 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged() 호출을 수신합니다.

    앱이 새 네트워크에 연결될 때 트리거된 콜백을 보여주는 상태 다이어그램
    그림 3. 무제한 Wi-Fi 네트워크에 연결한 후의 앱 상태

  4. 이 시점에서 Wi-Fi 네트워크를 확인하는 데 시간이 걸릴 수 있습니다. 이 경우 일반 네트워크 콜백의 onNetworkCapabilitiesChanged() 호출에는 NET_CAPABILITY_VALIDATED 기능이 포함되지 않습니다. 잠시 후 onNetworkCapabilitiesChanged() 호출을 수신합니다. 여기서 새 기능에는 NET_CAPABILITY_VALIDATED가 포함됩니다. 대부분의 경우는 확인 작업이 빠르게 진행됩니다.

    Wi-Fi 네트워크는 주로 무제한이므로 시스템은 Wi-Fi 네트워크가 확인되면 모바일 네트워크보다 Wi-Fi를 선호합니다. Wi-Fi 네트워크가 기본 네트워크가 되므로 기본 네트워크 콜백은 Wi-Fi 네트워크의 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged() 호출을 수신합니다. 모바일 네트워크가 백그라운드로 이동하고 일반 네트워크 콜백은 모바일 네트워크의 onLosing() 호출을 수신합니다.

    이 예는 이 기기에서 모바일 데이터가 상시 사용 설정되어 있다고 가정하므로 모바일 네트워크는 연결 해제되지 않습니다. 설정을 사용 중지하면 잠시 후 모바일 네트워크가 연결 해제되고 일반 네트워크 콜백이 onLost() 호출을 수신합니다.

    Wi-Fi 네트워크 연결을 확인할 때 트리거된 콜백을 보여주는 상태 다이어그램
    그림 4. Wi-Fi 네트워크 확인 후 앱 상태

  5. 추후 기기가 범위를 벗어났으므로 기기는 갑자기 Wi-Fi에서 연결 해제됩니다. Wi-Fi 연결이 해제되므로 일반 네트워크 콜백은 Wi-Fi의 onLost() 호출을 수신합니다. 모바일이 새로운 기본 네트워크이므로 기본 네트워크 콜백은 모바일 네트워크의 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged() 호출을 수신합니다.

    Wi-Fi 네트워크 연결이 끊어졌을 때 트리거된 콜백을 보여주는 상태 다이어그램
    그림 5. Wi-Fi 네트워크에서 연결 해제된 후 앱 상태

모바일 데이터 상시 사용 설정이 사용 중지된 경우 Wi-Fi 연결이 해제되면 기기는 모바일 네트워크에 다시 연결하려고 시도합니다. 그림은 비슷하지만, onAvailable() 호출에 짧은 추가 지연이 있으며 일반 네트워크 콜백은 모바일을 사용할 수 있으므로 onAvailable(), onNetworkCapabilitiesChanged(), onLinkPropertiesChanged() 호출도 수신합니다.

데이터 전송 시 네트워크 사용 제한사항

네트워크 콜백으로 네트워크를 볼 수 있어도 앱에서 데이터 전송에 네트워크를 사용할 수 있는 것은 아닙니다. 일부 네트워크는 인터넷 연결을 제공하지 않으며 일부 네트워크는 권한이 있는 앱으로 제한될 수 있습니다. 인터넷 연결을 확인하려면 NET_CAPABILITY_INTERNETNET_CAPABILITY_VALIDATED를 참고하세요.

백그라운드 네트워크를 사용할 때도 권한 확인이 적용됩니다. 앱에서 백그라운드 네트워크를 사용하려면 CHANGE_NETWORK_STATE 권한이 필요합니다.

이 권한이 있는 앱은 기기가 Wi-Fi 네트워크에 연결되어 있을 때 모바일 네트워크와 같이 시스템이 작동하지 않는 네트워크를 불러올 수 있도록 허용합니다. 이러한 앱은 네트워크가 표시될 때 호출될 NetworkCallback과 함께 ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback)을 호출합니다.