Event channel to listen Broadcast receiver’s event

Ravi Sevta
Cashify Engineering
3 min readApr 14, 2021
flutter event channel with BroadcastReceiver

In flutter application, we need to communicate with native platforms to write platform specific code. and we do it by platform channels(Method channel and Event channel).

Method channel: A named channel for communicating with platform plugins using asynchronous method calls.

Event Channel: A named channel for communicating with platform plugins using event streams.

And here we will implement Event Channel for special case in our existing app and that special case is that in Cashify we have added flutter module as a flutter fragment in an existing app, and that flutter fragment render city information and that city information is updated on Native side, whenever user select different city.

Passing data from android to flutter by event channel

This diagram is describing how flutter fragment(added in Activity) requests city change and rendering changed city in it’s own view.

So to handle this special case on flutter side we have added a city change provider which listen stream events coming from android side on city change.

class CityProvider extends ChangeNotifier {
CityInfo cityInfo;

CityProvider() {
_handleCityChanges();
}

void _handleCityChanges() {
const EventChannel _stream = EventChannel('channel/city_change');
_stream.receiveBroadcastStream().listen(
(data) {
cityInfo = CityInfo.fromJson(jsonDecode(data));
notifyListeners();
},
);
}
}

And in android side we have also registered Event channel on same channel id(‘plugins/event_channel/city_change’)

class EventChannelHandler(val context: Context) {
private lateinit var eventChannel: EventChannel

fun startListening(messenger: BinaryMessenger?) {

eventChannel = EventChannel(messenger, "channel/city_change");

eventChannel.setStreamHandler(
object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, eventSink:EventSink) {

}

override fun onCancel(p0: Any) {
}
}
)
}
}

So far we have configured the event channel on both sides and started listening events on the Flutter side.

But now the challenge is how event channel on the android side observe city change and pass data to the event stream.

In our existing android/iOS app we are storing selected city info to shared preferences, but now we have to add some code to broadcast city on selection so that event stream on android side receive that data by broadcast receiver and push to flutter side.

fun onCitySelect(cityInfo: CityInfo, context: Context) {

// save to shared preference

Intent().also { intent ->
intent.action = "action.CITY_CHANGE"
intent.putExtra("cityInfo", cityInfo)
context.sendBroadcast(intent)
}
}

And now we need a Broadcast receiver to receive that city info.

abstract class CityChangeListener {
abstract fun onCityChange(cityInfo: CityInfo?);
}

class CityChangeBroadcastReceiver : BroadcastReceiver() {

private lateinit var callback: CityChangeListener

fun setListener(callback: CityChangeListener) {
this.callback = callback;
}

override fun onReceive(context: Context?, intent: Intent?) {

if (intent != null && intent.action=="action.CITY_CHANGE") {
val info = intent.getParcelableExtra<CityInfo>("cityInfo")
callback.onCityChange(info)
}
}
}

And to get events from Receiver we have to register it in our onListen method of the Event Channel.

override fun onListen(arguments: Any?, eventSink: EventSink) {

val receiver = CityChangeBroadcastReceiver()

receiver.setListener(object : CityChangeListener() {

override fun onCityChange(cityInfo: CityInfo?) {
val json: String=GsonBuilder().create().toJson(cityInfo)
eventSink.success(json)
}
})

val filter = IntentFilter("action.CITY_CHANGE")
context.registerReceiver(receiver, filter)
}

eventSink.success(json) is adding event to existing channel stream, and CityProvider on flutter side is listening all these incoming events, decode that json data, update model and notifier to all dependent widgets.

Below is a complete flow diagram describing how flutter and native platform invoke city change activity and then EventChannel on android side receiving broadcasted city info and sending encoded data of city to flutter part.

Native to flutter communication using kotlin and dart.

--

--