Skip to content

Instantly share code, notes, and snippets.

@PatilShreyas
Created August 16, 2020 12:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PatilShreyas/a7750b3ebd1bac6ac54c8ecef8805762 to your computer and use it in GitHub Desktop.
Save PatilShreyas/a7750b3ebd1bac6ac54c8ecef8805762 to your computer and use it in GitHub Desktop.
package com.shreyaspatil.callbackflownetwork
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
@ExperimentalCoroutinesApi
fun Context.connectivityFlow() = callbackFlow {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// Create Callback
val callback = NetworkCallback { connectionState ->
offer(connectionState)
}
// Register Callback
connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), callback)
// Set current state
val currentState = getCurrentConnectivityState(connectivityManager)
offer(currentState)
// Remove callback when not used
awaitClose {
// Remove listeners
connectivityManager.unregisterNetworkCallback(callback)
}
}
@ExperimentalCoroutinesApi
fun Context.connectivityStateFlow(): StateFlow<ConnectionState> {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val currentState = getCurrentConnectivityState(connectivityManager)
val connectivityStateFlow = MutableStateFlow(currentState)
val callback = NetworkCallback { connectionState ->
connectivityStateFlow.value = connectionState
}
connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), callback)
return connectivityStateFlow
}
private fun getCurrentConnectivityState(connectivityManager: ConnectivityManager): ConnectionState {
var currentState = ConnectionState.NOT_CONNECTED
// Retrieve current status of connectivity
connectivityManager.allNetworks.forEach { network ->
val networkCapability = connectivityManager.getNetworkCapabilities(network)
networkCapability?.let {
if (it.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
currentState = ConnectionState.CONNECTED
return@forEach
}
}
}
return currentState
}
@Suppress("FunctionName")
fun NetworkCallback(callback: (ConnectionState) -> Unit): ConnectivityManager.NetworkCallback {
return object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
callback(ConnectionState.CONNECTED)
}
override fun onLost(network: Network) {
callback(ConnectionState.NOT_CONNECTED)
}
}
}
enum class ConnectionState {
CONNECTED, NOT_CONNECTED
}
package com.shreyaspatil.callbackflownetwork
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope
import com.shreyaspatil.callbackflownetwork.databinding.ActivityMainBinding
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@ExperimentalCoroutinesApi
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
observeUsingCallbackFlow()
// observeUsingStateFlow()
}
private fun observeUsingCallbackFlow() {
lifecycleScope.launch {
connectivityFlow().collect { connectionState ->
val colorResId = when (connectionState) {
ConnectionState.CONNECTED -> R.color.colorConnected
ConnectionState.NOT_CONNECTED -> R.color.colorNotConnected
}
val color = ActivityCompat.getColor(this@MainActivity, colorResId)
binding.root.setBackgroundColor(color)
}
}
}
private fun observeUsingStateFlow() {
lifecycleScope.launch {
connectivityStateFlow().collect { connectionState ->
val colorResId = when (connectionState) {
ConnectionState.CONNECTED -> R.color.colorConnected
ConnectionState.NOT_CONNECTED -> R.color.colorNotConnected
}
val color = ActivityCompat.getColor(this@MainActivity, colorResId)
binding.root.setBackgroundColor(color)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment