Notify Attendees in Realtime - Android
During a livestream, you may want to broadcast a message to all the viewers at once.
Let's see how to use PubSub to implement this. If you are not familiar with the PubSub mechanism, you can follow this guide.
Notifying Attendees
- Publish the message that the sender typed in the
EditTextfield to the topicNOTIFY_ATTENDEES.publish()is asuspendfunction, so call it from a coroutine. It throws aVideoSDKExceptionwhen the room is not joined, isRECONNECTING, or the message could not be sent, so wrap it intry/catch.
class SpeakerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
findViewById<View>(R.id.btnSend).setOnClickListener { sendMessage() }
}
private fun sendMessage() {
// get message from EditText
val message: String = etmessage.getText().toString()
if (!TextUtils.isEmpty(message)) {
val publishOptions = PubSubPublishOptions(persist = true)
lifecycleScope.launch {
try {
// Sending the Message using the publish method
room!!.pubSub.publish("NOTIFY_ATTENDEES", message, publishOptions)
// Clearing the message input
etmessage.setText("")
} catch (e: VideoSDKException) {
// Room is not joined yet, is reconnecting, or the message could not be sent
Toast.makeText(
this@SpeakerActivity, "Can't send right now, please try again",
Toast.LENGTH_SHORT
).show()
}
}
} else {
Toast.makeText(
this@SpeakerActivity, "Please Enter Message",
Toast.LENGTH_SHORT
).show()
}
}
}
- Now let us show an alert to all the viewers displaying the message posted by the speaker. Subscribe to the topic from
onRoomJoined(), so the subscription is made once the viewer has joined the room.subscribe()is asuspendfunction, so launch a coroutine for it.
subscribe() requires a joined room. Called before the join completes, for example directly in onCreate() of the activity that joins the room, it throws a VideoSDKException with code 3035 (ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED).
class ViewerActivity : AppCompatActivity() {
// PubSubMessageListener
val pubSubMessageListener = object : PubSubMessageListener {
override fun onMessageReceived(message: PubSubMessage) {
Log.d("VideoSDK", "NOTIFY_ATTENDEE: ${message.message}")
}
override fun onOldMessagesReceived(messages: List<PubSubMessage>, info: PubSubHistoryInfo) {
// Persisted message list, delivered in batches
Log.d("VideoSDK", "NOTIFY_ATTENDEES: $messages")
}
}
private val roomEventListener = object : RoomEventListener() {
override fun onRoomJoined(switchRoomId: String?) {
// Subscribe for 'NOTIFY_ATTENDEES' topic once the room is joined
lifecycleScope.launch {
try {
room!!.pubSub.subscribe("NOTIFY_ATTENDEES", pubSubMessageListener)
} catch (e: VideoSDKException) {
Log.d("VideoSDK", "subscribe failed: ${e.code} ${e.message}")
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
//...
// Add the listener before the viewer joins the room
room!!.addEventListener(roomEventListener)
}
}
onRoomJoined() also fires after a reconnect that needed a fresh join, and after switchTo(). The subscription is kept in both cases, so subscribing again with the same listener throws 3073 (ERROR_INVALID_PARAMETER). The catch above handles it.
API Reference
The API references for all the methods and events utilised in this guide are provided below.
Got a Question? Ask us on discord

