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

# Typing Indicators

> Send and receive real-time typing indicators in conversations using the CometChat Android SDK.

<Accordion title="AI Integration Quick Reference">
  ```kotlin theme={null}
  // Start typing indicator
  val typingIndicator = TypingIndicator("UID", CometChatConstants.RECEIVER_TYPE_USER)
  CometChat.startTyping(typingIndicator)

  // Stop typing indicator
  CometChat.endTyping(typingIndicator)

  // Listen for typing events
  CometChat.addMessageListener("LISTENER_ID", object : MessageListener() {
      override fun onTypingStarted(indicator: TypingIndicator) { }
      override fun onTypingEnded(indicator: TypingIndicator) { }
  })
  ```
</Accordion>

## Send a Typing Indicator

### Start Typing

Use `startTyping()` with a [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) object to notify the receiver that you're typing.

<Tabs>
  <Tab title="Java (User)">
    ```java theme={null}
    TypingIndicator typingIndicator = new TypingIndicator(UID, CometChatConstants.RECEIVER_TYPE_USER);

    CometChat.startTyping(typingIndicator);
    ```
  </Tab>

  <Tab title="Kotlin (User)">
    ```kotlin theme={null}
    val typingIndicator =TypingIndicator(UID,CometChatConstants.RECEIVER_TYPE_USER)

    CometChat.startTyping(typingIndicator)  
    ```
  </Tab>

  <Tab title="Java (Group)">
    ```java theme={null}
    TypingIndicator typingIndicator = new TypingIndicator(GUID, CometChatConstants.RECEIVER_TYPE_GROUP);

    CometChat.startTyping(typingIndicator);
    ```
  </Tab>

  <Tab title="Kotlin (Group)">
    ```kotlin theme={null}
    val typingIndicator = TypingIndicator(GUID,CometChatConstants.RECEIVER_TYPE_GROUP)

    CometChat.startTyping(typingIndicator)
    ```
  </Tab>
</Tabs>

### Stop Typing

Use `endTyping()` to notify the receiver that you've stopped typing.

<Tabs>
  <Tab title="Java (User)">
    ```java theme={null}
    TypingIndicator typingIndicator = new TypingIndicator(UID, CometChatConstants.RECEIVER_TYPE_USER);

    CometChat.endTyping(typingIndicator);
    ```
  </Tab>

  <Tab title="Kotlin (User)">
    ```kotlin theme={null}
    val typingIndicator = TypingIndicator(UID,CometChatConstants.RECEIVER_TYPE_USER)
       
    CometChat.endTyping(typingIndicator)
    ```
  </Tab>

  <Tab title="Java (Group)">
    ```java theme={null}
    TypingIndicator typingIndicator = new TypingIndicator(GUID, CometChatConstants.RECEIVER_TYPE_GROUP);

    CometChat.endTyping(typingIndicator);
    ```
  </Tab>

  <Tab title="Kotlin (Group)">
    ```kotlin theme={null}
    val typingIndicator = TypingIndicator(GUID,CometChatConstants.RECEIVER_TYPE_GROUP)

    CometChat.endTyping(typingIndicator)
    ```
  </Tab>
</Tabs>

<Note>
  Use `setMetadata()` on `TypingIndicator` to pass additional custom data. Retrieve it with `getMetadata()` on the receiver side.
</Note>

## Real-time Typing Indicators

Use `onTypingStarted` and `onTypingEnded` in `MessageListener` to receive typing events.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    CometChat.addMessageListener("Listener 1", new CometChat.MessageListener() {
    @Override
    public void onTypingStarted(TypingIndicator typingIndicator) {
      Log.d(TAG, " Typing Started : " + typingIndicator.toString());
    }

    @Override
    public void onTypingEnded(TypingIndicator typingIndicator) {
      Log.d(TAG, " Typing Ended : " + typingIndicator.toString());
    }

    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    CometChat.addMessageListener("Listener 1",object :CometChat.MessageListener(){
    override fun onTypingEnded(typingIndicator: TypingIndicator?) {
      Log.d(TAG,"onTypingEnded: ${typingIndicator.toString()}")
    }

    override fun onTypingStarted(typingIndicator: TypingIndicator?) {
      Log.d(TAG,"onTypingStarted: ${typingIndicator.toString()}")
    }

    })
    ```
  </Tab>
</Tabs>

The [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) class consists of the below parameters:

| Parameter      | Information                                                                                                                                                                                          |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sender`       | An object of the [`User`](/sdk/reference/entities#user) class holding all the information related to the sender of the typing indicator.                                                             |
| `receiverId`   | `UID` of the receiver. This is the ID of the group or the user the typing indicator is being sent to.                                                                                                |
| `receiverType` | This parameter indicates if the typing indicator is to be sent to a user or a group. The possible values are: 1. `CometChatConstants.RECEIVER_TYPE_USER` 2. `CometChatConstants.RECEIVER_TYPE_GROUP` |
| `metadata`     | A JSONObject to provider additional data                                                                                                                                                             |

## TypingIndicator Payload Structure

<Accordion title="TypingIndicator Object">
  The `TypingIndicator` object contains information about typing status:

  | Parameter       | Type                        | Description                                   |
  | --------------- | --------------------------- | --------------------------------------------- |
  | `sender`        | [User](#user-object-typing) | User who is typing                            |
  | `receiverId`    | String                      | ID of the receiver (user UID or group GUID)   |
  | `receiverType`  | String                      | Type of receiver. Values: `"user"`, `"group"` |
  | `metadata`      | JSONObject                  | Custom typing metadata                        |
  | `lastTimestamp` | long                        | Unix timestamp of last typing event           |
  | `typingStatus`  | String                      | Typing status. Values: `"started"`, `"ended"` |

  **Sample TypingIndicator Object:**

  ```json theme={null}
  {
    "sender": {
      "uid": "user_123",
      "name": "John Doe",
      "avatar": "https://example.com/avatar.png",
      "status": "online",
      "role": "default"
    },
    "receiverId": "user_456",
    "receiverType": "user",
    "metadata": {},
    "lastTimestamp": 1699900000,
    "typingStatus": "started"
  }
  ```
</Accordion>

<Accordion title="User Object (Typing)">
  The nested `User` object in `sender` contains:

  | Parameter       | Type           | Description                                            |
  | --------------- | -------------- | ------------------------------------------------------ |
  | `uid`           | String         | Unique identifier of the user                          |
  | `name`          | String         | Display name of the user                               |
  | `avatar`        | String         | URL to user's profile picture                          |
  | `link`          | String         | URL to user's profile page                             |
  | `role`          | String         | User role for access control                           |
  | `metadata`      | JSONObject     | Custom data set by developer                           |
  | `status`        | String         | User online status. Values: `"online"`, `"offline"`    |
  | `statusMessage` | String         | Custom status message                                  |
  | `lastActiveAt`  | long           | Unix timestamp of last activity                        |
  | `hasBlockedMe`  | boolean        | Whether this user has blocked the logged-in user       |
  | `blockedByMe`   | boolean        | Whether the logged-in user has blocked this user       |
  | `tags`          | Array\<String> | List of tags for user identification                   |
  | `deactivatedAt` | long           | Unix timestamp when user was deactivated (0 if active) |
</Accordion>

<Warning>
  Always remove message listeners when they're no longer needed (e.g., in `onDestroy()` or when navigating away). Failing to remove listeners can cause memory leaks and duplicate event handling.
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Delivery & Read Receipts" icon="check-double" href="/sdk/android/delivery-read-receipts">
    Track message delivery and read status
  </Card>

  <Card title="Receive Messages" icon="envelope" href="/sdk/android/receive-messages">
    Handle incoming messages with listeners
  </Card>

  <Card title="Retrieve Conversations" icon="list" href="/sdk/android/retrieve-conversations">
    Fetch conversation list
  </Card>

  <Card title="Real-Time Listeners" icon="bell" href="/sdk/android/real-time-listeners">
    Learn more about event listeners
  </Card>
</CardGroup>
