본문 바로가기
안드로이드 코틀린

[Kotlin][Android] 네트워크 연결 상태 확인

by teamnova 2021. 7. 23.

이번 포스팅에선 스틱코드를 써서 모바일 네트워크 연결 상태를 확인하는 앱을 만들어 보겠습니다.

이 글에서 사용된 모든 코드는 아래의 스틱코드 링크에서 확인할 수 있습니다.

https://stickode.com/detail.html?no=2227 

 

스틱코드

 

stickode.com

 

앱을 만들면서 LiveData라는 것을 사용할 것입니다.

LiveData란 액티비티와 프래그먼트 등의 생명주기를 인식하고 그에 따라 활성 생명주기(START 또는 RESUME)인 상태일 때만 데이터를 최신으로 업데이트해주는 클래스입니다.

그래서 LiveData를 사용하면 내가 별다른 처리를 하지 않더라도 데이터와 UI를 일치시킬 수 있다는 장점이 있습니다.

 

 

먼저 인터넷 연결 상태를 확인해야 하기 때문에 매니페스트에 아래의 권한을 추가합니다.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

 

그리고 네트워크 연결을 확인하는 메서드를 만들기 위해 아래의 클래스를 만들겠습니다.

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkInfo
import android.os.Build
import androidx.lifecycle.LiveData

class NetworkConnection(private val context: Context) : LiveData<Boolean>()
{
    private var connectivityManager: ConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    private lateinit var networkCallback: ConnectivityManager.NetworkCallback

    override fun onActive()
    {
        super.onActive()
        updateConnection()

        when
        {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ->
            {
                connectivityManager.registerDefaultNetworkCallback(connectivityManagerCallback())
            }
            else ->
            {
                context.registerReceiver(
                    networkReceiver,
                    IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
                )
            }
        }
    }

    override fun onInactive()
    {
        super.onInactive()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            connectivityManager.unregisterNetworkCallback(connectivityManagerCallback())
        } else
        {
            context.unregisterReceiver(networkReceiver)
        }
    }

    private fun connectivityManagerCallback(): ConnectivityManager.NetworkCallback
    {
        networkCallback = object : ConnectivityManager.NetworkCallback()
        {
            override fun onLost(network: Network)
            {
                super.onLost(network)
                postValue(false)
            }

            override fun onAvailable(network: Network)
            {
                super.onAvailable(network)
                postValue(true)
            }
        }
        return networkCallback
    }

    private val networkReceiver = object : BroadcastReceiver()
    {
        override fun onReceive(context: Context?, intent: Intent?)
        {
            updateConnection()
        }
    }

    private fun updateConnection()
    {
        val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
        postValue(activeNetwork?.isConnected == true)
    }

}

이제 네트워크 연결 상태를 확인하기 위한 화면을 만들겠습니다.

연결됨, 연결 안 됨 상태를 표시하기 위한 레이아웃과 그 안의 뷰들을 각각 만들어줍니다.

와이파이 연결 상태를 나타내는 이미지의 경우 원하는 것을 사용하면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    tools:context=".SecondActivity">

    <LinearLayout
        android:id="@+id/layoutDisconnected"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:src="@drawable/wifi_no"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="DISCONNECTED"
            android:textAllCaps="true"
            android:textColor="@android:color/holo_red_dark"
            android:textSize="24sp"
            android:textStyle="bold"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="40dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="40dp"
            android:gravity="center"
            android:text="인터넷에 연결되어 있지 않습니다"
            android:textSize="18sp"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layoutConnected"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="gone"
        android:gravity="center">

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:src="@drawable/wifi_ok"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="CONNECTED"
            android:textAllCaps="true"
            android:textColor="@android:color/holo_green_dark"
            android:textSize="24sp"
            android:textStyle="bold"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="40dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="40dp"
            android:gravity="center"
            android:text="인터넷에 연결되어 있습니다"
            android:textSize="18sp"/>

    </LinearLayout>

</FrameLayout>

 

그리고 코틀린 파일도 만들어 줍니다.

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity()
{
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val connection = NetworkConnection(applicationContext)
        connection.observe(this, Observer { isConnected ->
            if (isConnected)
            {
                layoutDisconnected.visibility = View.GONE
                layoutConnected.visibility = View.VISIBLE
            }
            else
            {
                layoutConnected.visibility = View.GONE
                layoutDisconnected.visibility = View.VISIBLE
            }
        })
    }
}

 

여기까지 완료하고 앱을 빌드하면 아래와 같은 화면을 보실 수 있습니다.

인터넷을 연결하고 해제할 때마다 화면의 글자가 DISCONNECTED와 CONNECTED로 바뀌고, 그 밑의 글자도 실시간으로 바뀌는 걸 볼 수 있습니다.

만약 특정 버전에서 실행되지 않도록 하려면 VERSION_CODES를 확인해서 특정 버전일 경우에만 작동하지 않도록 하면 됩니다.