Skip to main content
Version: 2.x.x

Audience Polls during Live Stream - Android

Interactive polls are a great way to increase engagement during livestreams. Using VideoSDK’s PubSub mechanism, you can easily implement real-time audience polling, where viewers can vote and the host can see live results instantly.

This guide walks you through how to create, send, and visualize poll results during a livestream.

Step 1: Creating and Publishing a Poll

To initiate a poll, use the PubSub class with a POLL topic. The poll structure should include a question and multiple options. This message will be published to all participants.

class CreatePollDialog() {

companion object {
const val POLL_TOPIC = "POLL"
}

fun show() {
// ... UI setup code ...

dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
// Validate inputs

// Create poll object
val options = mutableListOf(option1, option2)
if (option3.isNotEmpty()) options.add(option3)
if (option4.isNotEmpty()) options.add(option4)

val poll = SimplePoll(question, options)

// Publish poll to all participants
val pubSubPublishOptions = PubSubPublishOptions()
pubSubPublishOptions.isPersist = true
liveStream.pubSub.publish(POLL_TOPIC, poll.toJsonString(), pubSubPublishOptions)

// Show results dialog to host
PollResultsDialog(context, liveStream).show(poll)

dialog.dismiss()
}
}
}

Step 2: Subscribing to Polls and Displaying Options

Participants can listen to the POLL topic and render voting options dynamically based on the incoming data. The senderId of the received poll message identifies the host. Publish the vote with sendOnly set to that id, so only the host receives it and other participants can't see who voted for what.

class PollVotingDialog() {

companion object {
const val POLL_RESPONSE_TOPIC = "POLL_RESPONSE"
}

// hostId is the senderId of the received POLL message (message.senderId)
fun show(poll: SimplePoll, hostId: String) {
// ... UI setup code ...

// Create option buttons dynamically
poll.options.forEach { option ->
val button = Button(context)
button.text = option
button.setOnClickListener {
// Submit vote
val response = SimplePollResponse(
pollId = poll.id,
option = option,
participantId = liveStream.localParticipant.id,
participantName = liveStream.localParticipant.displayName
)

val publishOptions = PubSubPublishOptions()
val sendOnly: Array<String> = arrayOf(hostId)
publishOptions.setSendOnly(sendOnly)
liveStream.pubSub.publish(POLL_RESPONSE_TOPIC, response.toJsonString(), publishOptions)

// Disable all buttons after voting
for (i in 0 until optionsContainer.childCount) {
optionsContainer.getChildAt(i).isEnabled = false
}
}

optionsContainer.addView(button)
}
}
}

Step 3: Aggregating and Displaying Poll Results

The host can subscribe to the POLL_RESPONSE topic to collect responses and render the result in real-time.

class PollResultsDialog() {

private val pollResults = ConcurrentHashMap<String, Int>()
private var totalVotes = 0

companion object {
const val POLL_RESPONSE_TOPIC = "POLL_RESPONSE"
}

fun show(poll: SimplePoll) {
// ... UI setup code ...

// Initialize results map with 0 votes for each option
poll.options.forEach { option ->
pollResults[option] = 0
}

// Create initial result bars
updateResultBars()

// Listen for poll responses
responsesListener = object : PubSubMessageListener {
override fun onMessageReceived(pubSubMessage: PubSubMessage) {
try {
val response = SimplePollResponse.fromJsonString(pubSubMessage.message)
val option = response.option

// Update vote count
pollResults[option] = (pollResults[option] ?: 0) + 1
totalVotes++

// Update UI on main thread
(context as? android.app.Activity)?.runOnUiThread {
updateResultBars()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onOldMessagesReceived(messages: List<PubSubMessage>) {
// Persisted message list
Log.d("VideoSDK", "messages: $messages")
}
}

// Subscribe to poll responses
liveStream.pubSub.subscribe(POLL_RESPONSE_TOPIC, responsesListener)
}

private fun updateResultBars() {
// Clear previous results
optionsContainer?.removeAllViews()

// Create result bars for each option
pollResults.forEach { (option, votes) ->
val percentage = if (totalVotes > 0) (votes * 100) / totalVotes else 0

// Create progress bar UI showing percentage
// ... UI code to display results ...
}
}
}

API Reference

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord