> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-v6-beta2-flutter-uikit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Participant Event Listener

Monitor participant activities with `ParticipantEventListener`. This listener provides callbacks for participant join/leave events, audio/video state changes, hand raise actions, screen sharing, recording, and more.

## Prerequisites

* An active [call session](/calls/android/join-session)
* Access to the `CallSession` instance

## Register Listener

Register a `ParticipantEventListener` to receive participant event callbacks:

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    val callSession = CallSession.getInstance()

    callSession.addParticipantEventListener(this, object : ParticipantEventListener() {
        override fun onParticipantJoined(participant: Participant) {
            Log.d(TAG, "${participant.name} joined the call")
        }

        override fun onParticipantLeft(participant: Participant) {
            Log.d(TAG, "${participant.name} left the call")
        }

        override fun onParticipantListChanged(participants: List<Participant>) {
            Log.d(TAG, "Participant list updated: ${participants.size} participants")
        }

        // Additional callbacks...
    })
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    CallSession callSession = CallSession.getInstance();

    callSession.addParticipantEventListener(this, new ParticipantEventListener() {
        @Override
        public void onParticipantJoined(Participant participant) {
            Log.d(TAG, participant.getName() + " joined the call");
        }

        @Override
        public void onParticipantLeft(Participant participant) {
            Log.d(TAG, participant.getName() + " left the call");
        }

        @Override
        public void onParticipantListChanged(List<Participant> participants) {
            Log.d(TAG, "Participant list updated: " + participants.size() + " participants");
        }

        // Additional callbacks...
    });
    ```
  </Tab>
</Tabs>

<Note>
  The listener is automatically removed when the `LifecycleOwner` (Activity/Fragment) is destroyed, preventing memory leaks.
</Note>

***

## Participant Object

The `Participant` object contains information about a call participant:

| Property          | Type      | Description                          |
| ----------------- | --------- | ------------------------------------ |
| `uid`             | `String`  | Unique identifier of the participant |
| `name`            | `String`  | Display name of the participant      |
| `avatar`          | `String`  | Avatar URL of the participant        |
| `isAudioMuted`    | `Boolean` | Whether audio is muted               |
| `isVideoPaused`   | `Boolean` | Whether video is paused              |
| `isHandRaised`    | `Boolean` | Whether hand is raised               |
| `isScreenSharing` | `Boolean` | Whether screen is being shared       |

***

## Callbacks

### onParticipantJoined

Triggered when a new participant joins the call.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantJoined(participant: Participant) {
        Log.d(TAG, "${participant.name} joined the call")
        // Show join notification
        // Update participant grid
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantJoined(Participant participant) {
        Log.d(TAG, participant.getName() + " joined the call");
        // Show join notification
        // Update participant grid
    }
    ```
  </Tab>
</Tabs>

**Use Cases:**

* Display join notification/toast
* Update participant count
* Play join sound

***

### onParticipantLeft

Triggered when a participant leaves the call.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantLeft(participant: Participant) {
        Log.d(TAG, "${participant.name} left the call")
        // Show leave notification
        // Update participant grid
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantLeft(Participant participant) {
        Log.d(TAG, participant.getName() + " left the call");
        // Show leave notification
        // Update participant grid
    }
    ```
  </Tab>
</Tabs>

**Use Cases:**

* Display leave notification
* Update participant count
* Play leave sound

***

### onParticipantListChanged

Triggered when the participant list changes (join, leave, or any update).

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantListChanged(participants: List<Participant>) {
        Log.d(TAG, "Participants: ${participants.size}")
        // Update participant list UI
        updateParticipantGrid(participants)
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantListChanged(List<Participant> participants) {
        Log.d(TAG, "Participants: " + participants.size());
        // Update participant list UI
        updateParticipantGrid(participants);
    }
    ```
  </Tab>
</Tabs>

**Use Cases:**

* Refresh participant list/grid
* Update participant count badge
* Sync local state with server

***

### onParticipantAudioMuted

Triggered when a participant mutes their audio.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantAudioMuted(participant: Participant) {
        Log.d(TAG, "${participant.name} muted their audio")
        // Show muted indicator on participant tile
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantAudioMuted(Participant participant) {
        Log.d(TAG, participant.getName() + " muted their audio");
        // Show muted indicator on participant tile
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantAudioUnmuted

Triggered when a participant unmutes their audio.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantAudioUnmuted(participant: Participant) {
        Log.d(TAG, "${participant.name} unmuted their audio")
        // Hide muted indicator on participant tile
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantAudioUnmuted(Participant participant) {
        Log.d(TAG, participant.getName() + " unmuted their audio");
        // Hide muted indicator on participant tile
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantVideoPaused

Triggered when a participant pauses their video.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantVideoPaused(participant: Participant) {
        Log.d(TAG, "${participant.name} paused their video")
        // Show avatar or placeholder instead of video
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantVideoPaused(Participant participant) {
        Log.d(TAG, participant.getName() + " paused their video");
        // Show avatar or placeholder instead of video
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantVideoResumed

Triggered when a participant resumes their video.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantVideoResumed(participant: Participant) {
        Log.d(TAG, "${participant.name} resumed their video")
        // Show video stream
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantVideoResumed(Participant participant) {
        Log.d(TAG, participant.getName() + " resumed their video");
        // Show video stream
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantHandRaised

Triggered when a participant raises their hand.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantHandRaised(participant: Participant) {
        Log.d(TAG, "${participant.name} raised their hand")
        // Show hand raised indicator
        // Optionally play notification sound
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantHandRaised(Participant participant) {
        Log.d(TAG, participant.getName() + " raised their hand");
        // Show hand raised indicator
        // Optionally play notification sound
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantHandLowered

Triggered when a participant lowers their hand.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantHandLowered(participant: Participant) {
        Log.d(TAG, "${participant.name} lowered their hand")
        // Hide hand raised indicator
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantHandLowered(Participant participant) {
        Log.d(TAG, participant.getName() + " lowered their hand");
        // Hide hand raised indicator
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantStartedScreenShare

Triggered when a participant starts sharing their screen.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantStartedScreenShare(participant: Participant) {
        Log.d(TAG, "${participant.name} started screen sharing")
        // Switch to screen share view
        // Show screen share indicator
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantStartedScreenShare(Participant participant) {
        Log.d(TAG, participant.getName() + " started screen sharing");
        // Switch to screen share view
        // Show screen share indicator
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantStoppedScreenShare

Triggered when a participant stops sharing their screen.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantStoppedScreenShare(participant: Participant) {
        Log.d(TAG, "${participant.name} stopped screen sharing")
        // Switch back to normal view
        // Hide screen share indicator
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantStoppedScreenShare(Participant participant) {
        Log.d(TAG, participant.getName() + " stopped screen sharing");
        // Switch back to normal view
        // Hide screen share indicator
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantStartedRecording

Triggered when a participant starts recording the session.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantStartedRecording(participant: Participant) {
        Log.d(TAG, "${participant.name} started recording")
        // Show recording indicator
        // Notify other participants
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantStartedRecording(Participant participant) {
        Log.d(TAG, participant.getName() + " started recording");
        // Show recording indicator
        // Notify other participants
    }
    ```
  </Tab>
</Tabs>

***

### onParticipantStoppedRecording

Triggered when a participant stops recording the session.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onParticipantStoppedRecording(participant: Participant) {
        Log.d(TAG, "${participant.name} stopped recording")
        // Hide recording indicator
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onParticipantStoppedRecording(Participant participant) {
        Log.d(TAG, participant.getName() + " stopped recording");
        // Hide recording indicator
    }
    ```
  </Tab>
</Tabs>

***

### onDominantSpeakerChanged

Triggered when the dominant speaker changes (the participant currently speaking the loudest).

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    override fun onDominantSpeakerChanged(participant: Participant) {
        Log.d(TAG, "${participant.name} is now the dominant speaker")
        // Highlight the dominant speaker's tile
        // Auto-focus on dominant speaker in spotlight mode
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    @Override
    public void onDominantSpeakerChanged(Participant participant) {
        Log.d(TAG, participant.getName() + " is now the dominant speaker");
        // Highlight the dominant speaker's tile
        // Auto-focus on dominant speaker in spotlight mode
    }
    ```
  </Tab>
</Tabs>

**Use Cases:**

* Highlight active speaker in UI
* Auto-switch spotlight to dominant speaker
* Show speaking indicator animation

***

## Complete Example

Here's a complete example handling all participant events:

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    class CallActivity : AppCompatActivity() {
        private lateinit var callSession: CallSession

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_call)

            callSession = CallSession.getInstance()
            setupParticipantEventListener()
        }

        private fun setupParticipantEventListener() {
            callSession.addParticipantEventListener(this, object : ParticipantEventListener() {
                override fun onParticipantJoined(participant: Participant) {
                    runOnUiThread {
                        showToast("${participant.name} joined")
                    }
                }

                override fun onParticipantLeft(participant: Participant) {
                    runOnUiThread {
                        showToast("${participant.name} left")
                    }
                }

                override fun onParticipantListChanged(participants: List<Participant>) {
                    runOnUiThread {
                        updateParticipantCount(participants.size)
                    }
                }

                override fun onParticipantAudioMuted(participant: Participant) {
                    runOnUiThread {
                        updateParticipantAudioState(participant.uid, isMuted = true)
                    }
                }

                override fun onParticipantAudioUnmuted(participant: Participant) {
                    runOnUiThread {
                        updateParticipantAudioState(participant.uid, isMuted = false)
                    }
                }

                override fun onParticipantVideoPaused(participant: Participant) {
                    runOnUiThread {
                        updateParticipantVideoState(participant.uid, isPaused = true)
                    }
                }

                override fun onParticipantVideoResumed(participant: Participant) {
                    runOnUiThread {
                        updateParticipantVideoState(participant.uid, isPaused = false)
                    }
                }

                override fun onParticipantHandRaised(participant: Participant) {
                    runOnUiThread {
                        showHandRaisedIndicator(participant.uid, isRaised = true)
                    }
                }

                override fun onParticipantHandLowered(participant: Participant) {
                    runOnUiThread {
                        showHandRaisedIndicator(participant.uid, isRaised = false)
                    }
                }

                override fun onParticipantStartedScreenShare(participant: Participant) {
                    runOnUiThread {
                        showScreenShareView(participant)
                    }
                }

                override fun onParticipantStoppedScreenShare(participant: Participant) {
                    runOnUiThread {
                        hideScreenShareView()
                    }
                }

                override fun onParticipantStartedRecording(participant: Participant) {
                    runOnUiThread {
                        showRecordingIndicator(true)
                    }
                }

                override fun onParticipantStoppedRecording(participant: Participant) {
                    runOnUiThread {
                        showRecordingIndicator(false)
                    }
                }

                override fun onDominantSpeakerChanged(participant: Participant) {
                    runOnUiThread {
                        highlightDominantSpeaker(participant.uid)
                    }
                }
            })
        }

        // UI helper methods
        private fun showToast(message: String) {
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
        }

        private fun updateParticipantCount(count: Int) { /* ... */ }
        private fun updateParticipantAudioState(uid: String, isMuted: Boolean) { /* ... */ }
        private fun updateParticipantVideoState(uid: String, isPaused: Boolean) { /* ... */ }
        private fun showHandRaisedIndicator(uid: String, isRaised: Boolean) { /* ... */ }
        private fun showScreenShareView(participant: Participant) { /* ... */ }
        private fun hideScreenShareView() { /* ... */ }
        private fun showRecordingIndicator(show: Boolean) { /* ... */ }
        private fun highlightDominantSpeaker(uid: String) { /* ... */ }

        companion object {
            private const val TAG = "CallActivity"
        }
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    public class CallActivity extends AppCompatActivity {
        private static final String TAG = "CallActivity";
        private CallSession callSession;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_call);

            callSession = CallSession.getInstance();
            setupParticipantEventListener();
        }

        private void setupParticipantEventListener() {
            callSession.addParticipantEventListener(this, new ParticipantEventListener() {
                @Override
                public void onParticipantJoined(Participant participant) {
                    runOnUiThread(() -> showToast(participant.getName() + " joined"));
                }

                @Override
                public void onParticipantLeft(Participant participant) {
                    runOnUiThread(() -> showToast(participant.getName() + " left"));
                }

                @Override
                public void onParticipantListChanged(List<Participant> participants) {
                    runOnUiThread(() -> updateParticipantCount(participants.size()));
                }

                @Override
                public void onParticipantAudioMuted(Participant participant) {
                    runOnUiThread(() -> 
                        updateParticipantAudioState(participant.getUid(), true));
                }

                @Override
                public void onParticipantAudioUnmuted(Participant participant) {
                    runOnUiThread(() -> 
                        updateParticipantAudioState(participant.getUid(), false));
                }

                @Override
                public void onParticipantVideoPaused(Participant participant) {
                    runOnUiThread(() -> 
                        updateParticipantVideoState(participant.getUid(), true));
                }

                @Override
                public void onParticipantVideoResumed(Participant participant) {
                    runOnUiThread(() -> 
                        updateParticipantVideoState(participant.getUid(), false));
                }

                @Override
                public void onParticipantHandRaised(Participant participant) {
                    runOnUiThread(() -> 
                        showHandRaisedIndicator(participant.getUid(), true));
                }

                @Override
                public void onParticipantHandLowered(Participant participant) {
                    runOnUiThread(() -> 
                        showHandRaisedIndicator(participant.getUid(), false));
                }

                @Override
                public void onParticipantStartedScreenShare(Participant participant) {
                    runOnUiThread(() -> showScreenShareView(participant));
                }

                @Override
                public void onParticipantStoppedScreenShare(Participant participant) {
                    runOnUiThread(() -> hideScreenShareView());
                }

                @Override
                public void onParticipantStartedRecording(Participant participant) {
                    runOnUiThread(() -> showRecordingIndicator(true));
                }

                @Override
                public void onParticipantStoppedRecording(Participant participant) {
                    runOnUiThread(() -> showRecordingIndicator(false));
                }

                @Override
                public void onDominantSpeakerChanged(Participant participant) {
                    runOnUiThread(() -> highlightDominantSpeaker(participant.getUid()));
                }
            });
        }

        // UI helper methods
        private void showToast(String message) {
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        }

        private void updateParticipantCount(int count) { /* ... */ }
        private void updateParticipantAudioState(String uid, boolean isMuted) { /* ... */ }
        private void updateParticipantVideoState(String uid, boolean isPaused) { /* ... */ }
        private void showHandRaisedIndicator(String uid, boolean isRaised) { /* ... */ }
        private void showScreenShareView(Participant participant) { /* ... */ }
        private void hideScreenShareView() { /* ... */ }
        private void showRecordingIndicator(boolean show) { /* ... */ }
        private void highlightDominantSpeaker(String uid) { /* ... */ }
    }
    ```
  </Tab>
</Tabs>

***

## Callbacks Summary

| Callback                          | Parameter           | Description                          |
| --------------------------------- | ------------------- | ------------------------------------ |
| `onParticipantJoined`             | `Participant`       | A participant joined the call        |
| `onParticipantLeft`               | `Participant`       | A participant left the call          |
| `onParticipantListChanged`        | `List<Participant>` | Participant list was updated         |
| `onParticipantAudioMuted`         | `Participant`       | A participant muted their audio      |
| `onParticipantAudioUnmuted`       | `Participant`       | A participant unmuted their audio    |
| `onParticipantVideoPaused`        | `Participant`       | A participant paused their video     |
| `onParticipantVideoResumed`       | `Participant`       | A participant resumed their video    |
| `onParticipantHandRaised`         | `Participant`       | A participant raised their hand      |
| `onParticipantHandLowered`        | `Participant`       | A participant lowered their hand     |
| `onParticipantStartedScreenShare` | `Participant`       | A participant started screen sharing |
| `onParticipantStoppedScreenShare` | `Participant`       | A participant stopped screen sharing |
| `onParticipantStartedRecording`   | `Participant`       | A participant started recording      |
| `onParticipantStoppedRecording`   | `Participant`       | A participant stopped recording      |
| `onDominantSpeakerChanged`        | `Participant`       | The dominant speaker changed         |

## Next Steps

<CardGroup cols={2}>
  <Card title="Media Events Listener" icon="video" href="/calls/android/media-events-listener">
    Handle local media state changes
  </Card>

  <Card title="Participant Actions" icon="user-gear" href="/calls/android/participant-actions">
    Control other participants
  </Card>
</CardGroup>
