Android BroadcastReceiver as Flow

We all been to a position where we want to show a real-time message to the user when his internet connection has dropped. If not, we all have seen it somewhere.

There is this popular article solving the same problem with LiveData https://medium.com/android-news/connection-detection-using-livedata-android-623bd02b0e30. I wanted to tackle the same problem using Kotlin Flow.

I decided to make an extension function for Context called networkBroadcastReceiverFlow with a return type of Flow<Boolean> .

fun Context.networkBroadcastReceiverFlow(): Flow<Boolean>

Moving on to the implementation, we need to define a callbackFlow that will be used to emit the updates of network changes.

return callbackFlow {

}

In the callbackFlow we want to register a BroadcastReceiver in order to get updates when the network state changes. So first, we need to create our BroadcastReceiver and register it to the system. The BroadcastReceiver should filter for the intended action, otherwise should do nothing and return.

val networkBroadcastReceiver = object : BroadcastReceiver() {

override fun onReceive(context: Context?, intent: Intent?) {
if (intent.action != ConnectivityManager.CONNECTIVITY_ACTION) return
}
}
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(networkBroadcastReceiver, filter)

Next step of the implementation is to actually check for an internet connection. From the intent parameter we can get the NetworkInfo object and emit connection status via the NetworkInfo.isConnected or NetworkInfo.isConnectedOrConnecting .

val activeNetwork = intent.extras?.get(ConnectivityManager.EXTRA_NETWORK_INFO) as NetworkInfo? ?: returnthis@callbackFlow.trySend(activeNetwork.isConnected)

I’m using the trySend method to avoid blocking. You can use the send method which suspends execution, and run the onReceive code in a runBlocking coroutine block.

After registering the receiver to the system, we need to find a way to unregister it so we don’t unnecessarily waste resources of the system. For this we can use the awaitClose extension-function provided by the callbackFlow .

awaitClose { this@networkBroadcastReceiverFlow.unregisterReceiver(networkBroadcastReceiver) }

And that’s pretty much it! Here’s the whole code described.

fun Context.networkBroadcastReceiverFlow(): Flow<Boolean> {
return callbackFlow {

val
networkBroadcastReceiver = object : BroadcastReceiver() {

override fun onReceive(context: Context?, intent: Intent) {
if (intent.action != ConnectivityManager.CONNECTIVITY_ACTION) return
val
activeNetwork = intent.extras?.get(ConnectivityManager.EXTRA_NETWORK_INFO) as NetworkInfo? ?: return
trySend(activeNetwork.isConnected)
}
}
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(networkBroadcastReceiver, filter)
awaitClose { this@networkBroadcastReceiverFlow.unregisterReceiver(networkBroadcastReceiver) }
}
}

At this point you have noticed all the deprecation warnings. Even though the APIs used are marked as deprecated they seem to work just fine even on Android 12. You can use any new APIs Google introduced for network information to achieve the same goal. Even if they don’t work, this article is meant to showcase how we can make a Flow out of a BroadcastReceiver . After all, BroadcastReceiver is a communication with the system using the callback pattern. ¯\_(ツ)_/¯

--

--

--

Android Engineer @Plum

Recommended from Medium

How to handle background push notifications in Flutter 🔔

MotionLayout — “Android Animations Revolutionized”

How can I build an apk for my flutter app and prepare it to release?

release of flutter application

2D Galaxy Shooter — Implementing a Thruster Speed Boost

Dagger for Android: A Beginner’s Guide to Multibindings

Lessons from my first multiplatform Kotlin project

Autofill Services Android Part-2

Rounded BottomSheet Dialog in Android ( Part 3)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
cpaleop

cpaleop

Android Engineer @Plum

More from Medium

Intermediate: Schedule Alarm in HMS Based Android App

Top 10 useful applications for students — Apk Tech Ltda Phone

Learn to perform Asynchronous operations in Android using RxJava in 10 mins

Hello World! With Android Studio