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