[안드로이드 - 코틀린] Internet Connect Check 인터넷 연결 실시간 확인

2023. 3. 28. 15:03Android

프로젝트를 진행하다 실시간 인터넷 연결확인하는 작업이 필요해 찾아보다 

딱 알맞은 코드를 발견하였다 https://onlyfor-me-blog.tistory.com/654   해당 링크에 있는 코드를 참고해  만들어봤다.

 

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

 

build.gradle
def lifecycle_version = "2.6.1"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

implementation 'androidx.activity:activity-ktx:1.7.0'

 

xml

테스트 용이여서 xml은 해당 블로그 글에 있는걸 그대로 가져왔다.

ImageView에 있는 이미지는 drawable -> New -> Vector Asset  wifi 검색후 생성

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        tools:context=".networkstate.NetworkStateTestActivity">

        <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/baseline_wifi_off_24"/>

            <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/baseline_wifi_24"/>

            <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_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 >

</layout>

 

MainActivity

 

class MainActivity : AppCompatActivity() {

    private val viewModel: NetworkViewModel by viewModels()
    private lateinit var layoutDisconnected: LinearLayout
    private lateinit var layoutConnected: LinearLayout

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

        layoutDisconnected = findViewById(R.id.layoutDisconnected)
        layoutConnected = findViewById(R.id.layoutConnected)

//        viewModel = ViewModelProvider(this).get(NetworkViewModel::class.java)

        viewModel.checkNetworkConnection()

        viewModel.isConnected.observe(this) { isConnected ->
            // 인터넷 연결 상태에 따른 동작 수행
            if (isConnected) {
                // 인터넷이 연결된 상태
                layoutDisconnected.visibility = View.GONE
                layoutConnected.visibility = View.VISIBLE
            } else {
                // 인터넷이 연결되지 않은 상태
                layoutDisconnected.visibility = View.VISIBLE
                layoutConnected.visibility = View.GONE
            }
        }
    }
}

 

NetworkViewModel

ViewModel에서 Activity 나 context 등을 참조하게 된다면 Actvitiy가 생성 소멸을 반복할 때마다 메모리에 ViewModel을 참조하게 되므로 applicationContext을 참조해 쓸데없는 메모리를 참조하지 않게 Memory Leak을 방지해줘야된다. 때문에 ViewModel 자체도 AndroidViewModel을 이용하였다.

class NetworkViewModel(application: Application) : AndroidViewModel(application) {

//    인터넷 연결을 확인하기 위한 boolean 객체 생성 // LiveData 에서 제공하는 _~~ 들은 읽기 전용 객체
//    isConnected 는 _isConnected 를 읽기 전용으로 제공하는 livedata 객체입니다
//    livedata 객체는 관찰 가능한 데이터를 가지며 View 클래스에서 관찰할 수 있다

    private val _isConnected = MutableLiveData<Boolean>()

    val isConnected: LiveData<Boolean>
        get() = _isConnected

//    connectivityManager 는 시스템의 ConnectivityManager 객체 생성 변수

    private val connectivityManager = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

//    init 은 NetworkCallback 객체를 생성해 Network 상태를 수신해 _isConnected 객체 값들을 변경한다

    init {
        val networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                _isConnected.postValue(true)
            }

            override fun onLost(network: Network) {
                _isConnected.postValue(false)
            }
        }
        connectivityManager.registerDefaultNetworkCallback(networkCallback)
    }

//    디바이스 Network 상태를 확인하는 함수
    fun checkNetworkConnection() {
//    네트워크 상태를 체크한다 -> 연결 여부
        val network = connectivityManager.activeNetwork
//    네트워크 기능을 체크한다
        val capabilities = connectivityManager.getNetworkCapabilities(network)
        val isInternet = capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
        _isConnected.postValue(isInternet)
    }
}