Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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