Created
March 12, 2020 03:11
-
-
Save GokhanArik/b5c9ad58ce39218d722069d6cde34702 to your computer and use it in GitHub Desktop.
Check Internet Connection in Android 21+
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
@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.
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
@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 ?