Skip to content

Instantly share code, notes, and snippets.

@GokhanArik
Created March 12, 2020 03:11
Show Gist options
  • Save GokhanArik/b5c9ad58ce39218d722069d6cde34702 to your computer and use it in GitHub Desktop.
Save GokhanArik/b5c9ad58ce39218d722069d6cde34702 to your computer and use it in GitHub Desktop.
Check Internet Connection in Android 21+
package manager
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import android.util.Log
import com.jakewharton.rxrelay2.BehaviorRelay
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class NetworkStateManager @Inject constructor(context: Context) {
private var isOnline = false
private var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private var callback = ConnectionStatusCallback()
var connectionStatusEvent = BehaviorRelay.create<Boolean>()
init {
isOnline = getInitialConnectionStatus()
sendEvent(isOnline)
try {
connectivityManager.unregisterNetworkCallback(callback)
} catch (e: Exception) {
Log.w(this.javaClass.name, "NetworkCallback for Wi-fi was not registered or already unregistered")
}
connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), callback)
}
private fun getInitialConnectionStatus(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
} else {
val activeNetwork = connectivityManager.getActiveNetworkInfo() // Deprecated in 29
activeNetwork != null && activeNetwork.isConnectedOrConnecting // // Deprecated in 28
}
}
private fun sendEvent(status: Boolean) {
connectionStatusEvent.accept(status)
}
inner class ConnectionStatusCallback : ConnectivityManager.NetworkCallback() {
private val activeNetworks: MutableList<Network> = mutableListOf()
override fun onLost(network: Network) {
super.onLost(network)
activeNetworks.removeAll { activeNetwork -> activeNetwork == network }
isOnline = activeNetworks.isNotEmpty()
sendEvent(isOnline)
}
override fun onAvailable(network: Network) {
super.onAvailable(network)
if (activeNetworks.none { activeNetwork -> activeNetwork == network }) {
activeNetworks.add(network)
}
isOnline = activeNetworks.isNotEmpty()
sendEvent(isOnline)
}
}
}
@Murtowski
Copy link

Murtowski commented Dec 18, 2020

@GokhanArik do You unregistering callback only in init ?
Shouldn't You also unregister it in Application.onTerminate() ?
Have You tested it together with background services - does isOnline is still working correctly then ?

@goyalish
Copy link

goyalish commented May 6, 2021

@GitHubMurt public void onTerminate ()
This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.

do You unregistering callback only in init ? -> That look like a preventive measure to unregister an already registered callback.
I have not tested this code though. I just read your comment and answered your questioned by looking at the code.

@anmichai
Copy link

anmichai commented Jun 21, 2021

If u have VPN enabled and cellular or/and wifi networks disabled this line will return true:
capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment