43

I tried the answer from this (the accepted answer). I can use the "PING" method but the UI went black since it says it will block the UI Thread. It didn't look good and was disturbing so I tried to use the second method "Connect to a Socket on the Internet" but I don't know how to use the class in Kotlin.

This is the result of converted Java to kotlin by android studio

package com.mockie.daikokuten.helpers

import android.os.AsyncTask.execute
import android.os.AsyncTask
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Socket


internal class InternetCheck(private val mConsumer: Consumer) : AsyncTask<Void, Void, Boolean>() {
interface Consumer {
    fun accept(internet: Boolean?)
}

init {
    execute()
}

override fun doInBackground(vararg voids: Void): Boolean? {
    try {
        val sock = Socket()
        sock.connect(InetSocketAddress("8.8.8.8", 53), 1500)
        sock.close()
        return true
    } catch (e: IOException) {
        return false
    }

}

override fun onPostExecute(internet: Boolean?) {
    mConsumer.accept(internet)
}
}

but I DONT KNOW HOW TO USE IT. I tried this way:

InternetCheck{ internet-> Log.d("test", "asdasdas") }

It didnt work and results in an error. It says I have to pass "Consumer".

My question is How to use that class?

Kakashi
  • 3,037
  • 3
  • 21
  • 37

10 Answers10

62

Update: Since Android 10 the use of the NetWorkInfo class and its methods are obsolete, now you must use the ConectivityManager class and getNetworkCapabilities () method from NetworkCapabilities Class.

How to check connectivity in Android?

Kotlin :

fun isOnline(context: Context): Boolean {
    val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (connectivityManager != null) {
        val capabilities =
            connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                return true
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                return true
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                return true
            }
        }
    }
    return false
}

Java:

public static boolean isOnline(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR");
                return true;
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI");
                return true;
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET");
                return true;
            }
        }
    }
    
    return false;
}

both methods require the permissions:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
Jorgesys
  • 119,885
  • 23
  • 317
  • 256
28

Check internet connectivity in android kotlin

fun isNetworkAvailable(context: Context?): Boolean {
    if (context == null) return false
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            when {
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                    return true
                }
            }
        }
    } else {
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
            return true
        }
    }
    return false
}
Aftab Alam
  • 1,673
  • 14
  • 15
  • 4
    >= Build.VERSION_CODES.Q isn't Build.VERSION_CODES.M? This is what linter said in AndroidStudio – ejdrian313 Jul 06 '20 at 06:46
  • 1
    @ejdrian313 this means that your current Buildversion (M = Marshmallow, Android 5) is below Q (Android 10), which is required to run the code within the if-statement. – pentexnyx Aug 14 '20 at 22:14
14

Call the AsyncTask this way, it should work. You don't need to change anything in your InternetCheck AsyncTask. Basically you need to pass in an object that implements the Consumer interface that's defined in the InternetCheck class.

InternetCheck(object : InternetCheck.Consumer {
    override fun accept(internet: Boolean?) {
        Log.d("test", "asdasdas")
    }
})
Vishnu M.
  • 931
  • 1
  • 10
  • 18
12
 fun verifyAvailableNetwork(activity:AppCompatActivity):Boolean{
      val connectivityManager=activity.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
      val networkInfo=connectivityManager.activeNetworkInfo
      return  networkInfo!=null && networkInfo.isConnected
}
IramML
  • 188
  • 1
  • 6
9

Add these permission on top in Manifest

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

and this function should do the trick. It will return boolean based on its connectivity

fun isOnline(context: Context): Boolean {
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val n = cm.activeNetwork
        if (n != null) {
            val nc = cm.getNetworkCapabilities(n)
    //It will check for both wifi and cellular network
            return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        }
        return false
    } else {
        val netInfo = cm.activeNetworkInfo
        return netInfo != null && netInfo.isConnectedOrConnecting
    }
}

It has a deprecated method as well as a latest one based on your api version.

Syed Afeef
  • 108
  • 1
  • 7
5

Try this utility method to check for the availability of internet.

fun isNetworkAvailable(context: Context): Boolean {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        var activeNetworkInfo: NetworkInfo? = null
        activeNetworkInfo = cm.activeNetworkInfo
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
    }

Hope this helps.

Naveen T P
  • 6,547
  • 2
  • 20
  • 28
5

Shortest version

val Context.isConnected: Boolean
    get() {
        return (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
           .activeNetworkInfo?.isConnected == true
    }
Vlad
  • 6,741
  • 2
  • 48
  • 42
  • 1
    This only checks if we have network, not if we're "online" i.e. connected to the internet. – Lalle Jun 11 '19 at 15:21
3

I modified your class to this

internal class InternetCheck(private val onInternetChecked: (Boolean) -> Unit) : 
AsyncTask<Void, Void, Boolean>() {
 init {
     execute()
 }

 override fun doInBackground(vararg voids: Void): Boolean {
     return try {
         val sock = Socket()
         sock.connect(InetSocketAddress("8.8.8.8", 53), 1500)
         sock.close()
         true
     } catch (e: IOException) {
         false
     }

 }

 override fun onPostExecute(internet: Boolean) {
     onInternetChecked(internet)
 }
}

So you could use lambda function and you also dont have to deal with null check in there:

InternetCheck{ internet-> Log.d("Connection", "Is connection enabled? "+internet) }
Radim Janda
  • 157
  • 9
  • I was required to add StrictMode in the MainActivity ```StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);``` Source: https://stackoverflow.com/a/22395546/2215337 – Wesley Abbenhuis Mar 03 '19 at 21:47
2

You can use it like this:

   InternetCheck(object : InternetCheck.Consumer {
      override fun accept(internet: Boolean?) {
         Log.d("test", "asdasdas")
      }
   })

For more infos you can see this thread: https://youtrack.jetbrains.com/issue/KT-7770

Renan Arceno
  • 570
  • 3
  • 12
2

Monitoring Internet Connection in Realtime using LiveData - Kotlin

I came across this amazing tutorial on YouTube. We simply need to add a utility file which extends LiveData and can observe it in our Activity or Fragment.

Usage

    private lateinit var connectionLiveData: ConnectionLiveData

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityInternetConnectionTestBinding.inflate(layoutInflater)
        setContentView(binding.root)

        connectionLiveData = ConnectionLiveData(this)
        connectionLiveData.observe(this) { isNetworkAvailable ->
            isNetworkAvailable?.let {
                updateUI(it)
            }
        }
    }

Utility File

const val TAG = "MyTagConnectionManager"

class ConnectionLiveData(context: Context) : LiveData<Boolean>() {

    private lateinit var networkCallback: ConnectivityManager.NetworkCallback
    private val connectivityManager =
        context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    private val validNetworks: MutableSet<Network> = HashSet()

    private fun checkValidNetworks() {
        postValue(validNetworks.size > 0)
    }

    override fun onActive() {
        networkCallback = createNetworkCallback()
        val networkRequest = NetworkRequest.Builder()
            .addCapability(NET_CAPABILITY_INTERNET)
            .build()
        connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
    }

    override fun onInactive() {
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }

    private fun createNetworkCallback() = object : ConnectivityManager.NetworkCallback() {

        override fun onAvailable(network: Network) {
            Log.d(TAG, "onAvailable: $network")
            val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
            val hasInternetCapability = networkCapabilities?.hasCapability(NET_CAPABILITY_INTERNET)
            Log.d(TAG, "onAvailable: ${network}, $hasInternetCapability")

            if (hasInternetCapability == true) {
                // Check if this network actually has internet
                CoroutineScope(Dispatchers.IO).launch {
                    val hasInternet = DoesNetworkHaveInternet.execute(network.socketFactory)
                    if (hasInternet) {
                        withContext(Dispatchers.Main) {
                            Log.d(TAG, "onAvailable: adding network. $network")
                            validNetworks.add(network)
                            checkValidNetworks()
                        }
                    }
                }
            }
        }

        override fun onLost(network: Network) {
            Log.d(TAG, "onLost: $network")
            validNetworks.remove(network)
            checkValidNetworks()
        }
    }

    object DoesNetworkHaveInternet {

        fun execute(socketFactory: SocketFactory): Boolean {
            // Make sure to execute this on a background thread.
            return try {
                Log.d(TAG, "PINGING Google...")
                val socket = socketFactory.createSocket() ?: throw IOException("Socket is null.")
                socket.connect(InetSocketAddress("8.8.8.8", 53), 1500)
                socket.close()
                Log.d(TAG, "PING success.")
                true
            } catch (e: IOException) {
                Log.e(TAG, "No Internet Connection. $e")
                false
            }
        }
    }
}

Shahzad Ansari
  • 117
  • 1
  • 7