Reactions - Android
During a livestream, one way to increase interaction between viewers and speakers is to show each viewer's reactions to everyone. You might have seen emojis flying around during livestreams on Instagram.
Let's create a similar flying emoji by using the VideoSDK PubSub mechanism.
Step 1: Creating a button to send reaction
When btnReaction is clicked we will send the emoji name to all the participants using the VideoSDK PubSub mechanism and also show the emoji to the local participant.
A reaction does not need to be stored, so it is published without PubSubPublishOptions: it reaches everyone subscribed right now and is not kept. publish() is a suspend function, so call it from a coroutine. It returns once the server has the message, and throws a VideoSDKException when the room is not joined, is RECONNECTING, or the message could not be sent.
class ILSViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
findViewById<View>(R.id.btnReaction).setOnClickListener { v: View? ->
showEmoji(resources.getDrawable(R.drawable.love_eyes_emoji))
lifecycleScope.launch {
try {
room!!.pubSub.publish("REACTION", "love_eyes")
} catch (e: VideoSDKException) {
// Room is not joined yet, is reconnecting, or the message could not be sent
Log.d("VideoSDK", "publish failed: ${e.code} ${e.message}")
}
}
}
}
private fun showEmoji(drawable: Drawable?) {
// we will implement this method in step 2
}
}
Step 2: Displaying the Reactions to all the users
Here we will listen to the onMessageReceived event of PubSubMessageListener to know when someone sends a reaction, and show the flying emoji whenever it is triggered.
Your own reactions also arrive on onMessageReceived(). They are already on screen from step 1, so the listener skips them. Subscribe to the topic from onRoomJoined(): called before the join completes, subscribe() throws a VideoSDKException with code 3035. subscribe() is a suspend function, so the listener launches a coroutine for it.
To display the flying emoji, we are using DirectionGenerator class to specify direction and ZeroGravityAnimation class to give animation to the flyingEmoji.
Copy DirectionGenerator and ZeroGravityAnimation classes, and the OverTheTopLayer class that ZeroGravityAnimation uses, from our code sample.
class ILSViewActivity : AppCompatActivity() {
private val emojiListener = object : PubSubMessageListener {
override fun onMessageReceived(message: PubSubMessage) {
// Skip your own reaction: it was shown when you tapped the button
if (message.senderId == room?.localParticipant?.id) return
when (message.message) {
"love_eyes" -> showEmoji(resources.getDrawable(R.drawable.love_eyes_emoji))
}
}
}
private val roomEventListener = object : RoomEventListener() {
override fun onRoomJoined(switchRoomId: String?) {
//Subscribing to the PubSub topic REACTION to receive other participants' reactions.
lifecycleScope.launch {
try {
room!!.pubSub.subscribe("REACTION", emojiListener)
} catch (e: VideoSDKException) {
// 3073 here means this listener is already subscribed, for example after a reconnect
Log.d("VideoSDK", "subscribe failed: ${e.code} ${e.message}")
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
// Add the listener before the viewer joins the room
room!!.addEventListener(roomEventListener)
}
}
private fun showEmoji(drawable: Drawable?) {
// You can change the number of emojis that will be flying on screen
for (i in 0..4) {
flyObject(
drawable,
3000,
DirectionGenerator.Direction.BOTTOM,
DirectionGenerator.Direction.TOP,
1f
)
}
}
private fun flyObject(
drawable: Drawable?,
duration: Int,
from: DirectionGenerator.Direction?,
to: DirectionGenerator.Direction?,
scale: Float
) {
val animation = ZeroGravityAnimation()
animation.setCount(1)
animation.setScalingFactor(scale)
animation.setOriginationDirection((from)!!)
animation.setDestinationDirection((to)!!)
animation.setImage(drawable)
animation.setDuration(duration)
animation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
override fun onAnimationEnd(animation: Animation) {}
override fun onAnimationRepeat(animation: Animation) {}
})
viewerEmojiHolder!!.bringToFront()
animation.play(mActivity, viewerEmojiHolder)
}
Here viewerEmojiHolder is a FrameLayout. You can change it according to your requirement.


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

