> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quickblox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# User Presence

> Learn how to track user presence updates and check user status using ping.

## Before you begin

1. Register a [QuickBlox account](https://admin.quickblox.com/signin). This is a matter of a few minutes and you will be able to use this account to build your apps.
2. Configure QuickBlox SDK for your app. Check out [Setup](/sdks/android-setup) page for more details.
3. Create a user session to be able to use QuickBlox functionality. See [Authentication](/sdks/android-authentication) page to learn how to do it.
4. Connect to the Chat server. See [Connection](/sdks/android-chat-connection) page to learn how to do it.

Visit [Key Concepts](/docs/key-concepts) page to learn the most important QuickBlox concepts.

## Subscribe to contact presence updates

You can listen to the contact presence updates in real-time using the `QBRosterListener`. However, you can listen to the presence of only those users who have been added to the contact list. See [this section](/sdks/android-chat-contact-list) to learn how to implement the Contact List.

<Tabs>
  <Tab title="Java">
    ```Java theme={null}
    // you should do this after login (connect) to the Chat
    final QBRoster contactsRoster = QBChatService.getInstance().getRoster();

    QBRosterListener rosterListener = new QBRosterListener() {
        @Override
        public void entriesDeleted(Collection<Integer> userIds) {

        }

        @Override
        public void entriesAdded(Collection<Integer> userIds) {

        }

        @Override
        public void entriesUpdated(Collection<Integer> userIds) {

        }

        @Override
        public void presenceChanged(QBPresence presence) {
            if (presence == null) {
                // no user in your contact list
                return;
            }
            // if a user uses several devices, you need to do additional check for presence
            QBPresence qbPresence = contactsRoster.getPresence(presence.getUserId());

            if (qbPresence.getType() == QBPresence.Type.online) {
                // user is online
            } else {
                // user is offline
            }
        }
    };

    contactsRoster.setSubscriptionMode(QBRoster.SubscriptionMode.mutual);
    contactsRoster.addRosterListener(rosterListener);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```Kotlin theme={null}
    // you should do this after login (connect) to the Chat
    val contactsRoster = QBChatService.getInstance().roster

    val rosterListener: QBRosterListener = object : QBRosterListener {
        override fun entriesDeleted(userIds: Collection<Int>) {

        }

        override fun entriesAdded(userIds: Collection<Int>) {

        }

        override fun entriesUpdated(userIds: Collection<Int>) {

        }

        override fun presenceChanged(presence: QBPresence) {
            if (presence == null) {
                // no user in your contact list
                return
            }
            // if a user uses several devices, you need to do additional check for presence
            val qbPresence = contactsRoster.getPresence(presence.userId)

            if (qbPresence.type == QBPresence.Type.online) {
                // user is online
            } else {
                // user is offline
            }
        }
    }

    contactsRoster.subscriptionMode = QBRoster.SubscriptionMode.mutual
    contactsRoster.addRosterListener(rosterListener)
    ```
  </Tab>
</Tabs>

## Ping user

QuickBlox SDK can send application-level pings to a user. As a result, you can check if the user is connected to the Chat server.

<Tabs>
  <Tab title="Java">
    ```Java theme={null}
    QBPingManager pingManager = QBChatService.getInstance().getPingManager();
    Integer userId = 6453;

    pingManager.pingUser(userId, new QBEntityCallback<Void>() {
        @Override
        public void onSuccess(Void aVoid, Bundle bundle) {

        }

        @Override
        public void onError(QBResponseException exception) {

        }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```Kotlin theme={null}
    val pingManager = QBChatService.getInstance().pingManager
    val userId = 6453

    pingManager.pingUser(userId, object : QBEntityCallback<Void> {
        override fun onSuccess(aVoid: Void, bundle: Bundle) {

        }

        override fun onError(exception: QBResponseException) {

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

| Argument | Required | Description     |
| -------- | -------- | --------------- |
| userID   | yes      | ID of the user. |

## Ping server

QuickBlox SDK can send application-level pings to a server. As a result, you can check if there is a connection with the Chat server.

<Tabs>
  <Tab title="Java">
    ```Java theme={null}
    QBPingManager pingManager = QBChatService.getInstance().getPingManager();

    pingManager.pingServer(new QBEntityCallback<Void>() {
        @Override
        public void onSuccess(Void aVoid, Bundle bundle) {

        }

        @Override
        public void onError(QBResponseException exception) {

        }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```Kotlin theme={null}
    val pingManager = QBChatService.getInstance().pingManager

    pingManager.pingServer(object : QBEntityCallback<Void> {
        override fun onSuccess(aVoid: Void, bundle: Bundle) {

        }

        override fun onError(exception: QBResponseException) {

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

## Add ping listener

Your pings can be unsuccessful. To handle unsuccessful pings, use the `PingFailedListener`. It enables your app to listen to failed ping attempts.

<Tabs>
  <Tab title="Java">
    ```Java theme={null}
    QBPingManager pingManager = QBChatService.getInstance().getPingManager();

    PingFailedListener pingFailedListener = new PingFailedListener() {
        @Override
        public void pingFailed() {

        }
    };

    // add PingManager when you need it
    pingManager.addPingFailedListener(pingFailedListener);

    // remove PingManager when you no longer need it
    pingManager.removePingFailedListener(pingFailedListener);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```Kotlin theme={null}
    val pingManager = QBChatService.getInstance().pingManager

    val pingFailedListener = PingFailedListener {

    }

    // Add PingManager when you need it
    pingManager.addPingFailedListener(pingFailedListener)

    // Remove PingManager when you no longer need it
    pingManager.removePingFailedListener(pingFailedListener)
    ```
  </Tab>
</Tabs>
