-
-
Save GokhanArik/b5c9ad58ce39218d722069d6cde34702 to your computer and use it in GitHub Desktop.
| 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) | |
| } | |
| } | |
| } |
@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 ?
@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)
Nice solution. Thanks a lot.