---
source_url: https://www.pubnub.com/docs/sdks/android/api-reference/presence
title: Presence API for Android SDK
updated_at: 2026-06-12T11:24:21.626Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Presence API for Android SDK

:::warning Unsupported docs
PubNub no longer maintains Android SDK docs, but our [Java SDK](https://www.pubnub.com/docs/sdks/java) or [Kotlin SDK](https://www.pubnub.com/docs/sdks/kotlin) are fully compatible with the Android platform and you can use them to build mobile apps, ensuring stable software development.
:::

Presence lets you track who is online or offline and store custom state information. Presence shows:

* When a user has joined or left a channel
* Who, and how many, users are subscribed to a particular channel
* Which channels an individual user is subscribed to
* Presence state associated with these users

Learn more about our Presence feature in the [Presence overview](https://www.pubnub.com/docs/general/presence/overview).

## Here now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/).
:::

This method returns information about the current state of a channel, including a list of unique user IDs (universally unique identifiers, UUIDs) currently subscribed to the channel and the total occupancy count of the channel.

:::note Cache
This method has a 3-second response cache time.
:::

### Method(s)

Use the following method in the Android SDK:

```java
this.pubnub.hereNow()
    .channels(Array)
    .channelGroups(Arrays)
    .includeState(true)
    .includeUUIDs(true)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| channels | Array | Optional |  | Channels to query for Here now details. |
| channelGroups | Arrays | Optional |  | Channel groups to query for Here now details. |
| includeState | Boolean | Optional | `false` | Whether to include presence state for users on channels and channel groups. |
| includeUUIDs | Boolean | Optional | `true` | Whether to include the UUIDs of connected clients. |
| async | PNCallback | Yes |  | `PNCallback` of type `PNHereNowResult` |

### Sample code

#### Get a list of UUIDs subscribed to channel

```java
pubnub.hereNow()
    // tailor the next two lines to example
    .channels(Arrays.asList("coolChannel", "coolChannel2"))
    .includeUUIDs(true)
    .async(new PNCallback<PNHereNowResult>() {
        @Override
        public void onResponse(PNHereNowResult result, PNStatus status) {
            if (status.isError()) {
                // handle error
                return;
            }

            for (PNHereNowChannelData channelData : result.getChannels().values()) {
                System.out.println("---");
                System.out.println("channel:" + channelData.getChannelName());
                System.out.println("occupancy: " + channelData.getOccupancy());
                System.out.println("occupants:");
                for (PNHereNowOccupantData occupant : channelData.getOccupants()) {
                    System.out.println("uuid: " + occupant.getUuid() + " state: " + occupant.getState());
                }
            }
        }
    });
```

### Returns

The `hereNow()` operation returns a `PNHereNowResult` which contains the following operations:

| Method | Description |
| --- | --- |
| `getTotalChannels()`Type: Int | Total `Channels`. |
| `getTotalOccupancy()`Type: Int | Total `Occupancy`. |
| `getChannels()`Type: Map`<String, PNHereNowChannelData>` | A map with values of `PNHereNowChannelData` for each `channel`. See [PNHereNowChannelData](#pnherenowchanneldata) for more details. |

#### PNHereNowChannelData

| Method | Description |
| --- | --- |
| `getChannelName()`Type: String | `Channel` name. |
| `getOccupancy()`Type: Int | `Occupancy` of the `channel`. |
| `getOccupants()`Type: List`<PNHereNowOccupantData>` | A list of `PNHereNowOccupantData`, see [PNHereNowOccupantData](#pnherenowoccupantdata) for more details. |

#### PNHereNowOccupantData

| Method | Description |
| --- | --- |
| `getUuid()`Type: String | `UUIDs` of the user. |
| `getState()`Type: Object | `State` of the user. |

### Other examples

#### Returning state

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/).
:::

```java
pubnub.hereNow()
    .channels(Arrays.asList("my_channel")) // who is present on those channels?
    .includeState(true) // include state with request (false by default)
    .includeUUIDs(true) // if false, only shows occupancy count
    .async(new PNCallback<PNHereNowResult>() {
        @Override
        public void onResponse(PNHereNowResult result, PNStatus status) {

        }
    });
```

##### Example response

```java
if (!status.isError()) {
    for (PNHereNowChannelData channelData : result.getChannels().values()) {
            channelData.getOccupancy(); // 3
            channelData.getChannelName(); // my_channel
            channelData.getOccupants(); // members of a channel
            for (PNHereNowOccupantData occupant : channelData.getOccupants()) {
                occupant.getUuid(); // some_uuid;
                occupant.getState(); // channel member state, if applicable
            }
    }
} else {
    // an error occurred
    status.getErrorData().getInformation();
    status.getErrorData().getThrowable().printStackTrace();
}
```

#### Return occupancy only

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/).
:::

To return only `occupancy` for a channel, set `includeUUIDs` and `includeState` to `false`:

```java
pubnub.hereNow()
    .channels(Arrays.asList("my_channel")) // who is present on those channels?
    .includeState(false) // include state with request (false by default)
    .includeUUIDs(false) // if false, only shows occupancy count
    .async(new PNCallback<PNHereNowResult>() {
        @Override
        public void onResponse(PNHereNowResult result, PNStatus status) {

        }
    });
```

##### Example response

```java
if (!status.isError()) {
    for (PNHereNowChannelData channelData: result.getChannels().values()) {
        channelData.getOccupancy(); // 3
        channelData.getChannelName(); // my_channel
    }
} else {
    // an error occurred
    status.getErrorData().getInformation();
    status.getErrorData().getThrowable().printStackTrace();
}
```

#### Here now for channel groups

```java
pubnub.hereNow()
    .channelGroups(Arrays.asList("cg1", "cg2", "cg3")) // who is present on channel groups?
    .includeState(true) // include state with request (false by default)
    .includeUUIDs(true) // if false, only shows occupancy count
    .async(new PNCallback<PNHereNowResult>() {
        @Override
        public void onResponse(PNHereNowResult result, PNStatus status) {

        }
    });
```

##### Example response

```java
if (!status.isError()) {
    result.getTotalOccupancy(); // 12
} else {
    // an error occurred
    status.getErrorData().getInformation();
    status.getErrorData().getThrowable().printStackTrace();
}
```

## Where now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/).
:::

This method returns the list of channels a UUID is subscribed to.

:::note Timeout events
If the app restarts (or the page refreshes) within the heartbeat window, no timeout event is generated.
:::

### Method(s)

Use the following method in the Android SDK:

```java
pubnub.whereNow()
    .uuid(String)
```

| Parameter | Description |
| --- | --- |
| `uuid`Type: String | `Uuid` of the user to query. |
| `async` *Type: Command | Execute as `async`. |

### Sample code

```java
pubnub.whereNow()
    .async(new PNCallback<PNWhereNowResult>() {
        @Override
        public void onResponse(PNWhereNowResult result, PNStatus status) {
            // returns a pojo with channels // channel groups which I am part of.
        }
    });
```

### Returns

The `whereNow()` operation returns a `PNWhereNowResult` which contains the following operations:

| Method | Description |
| --- | --- |
| `getChannels()`Type: List`<String>` | The list of `channels` where the `UUID` is present. |

### Other examples

#### Obtain information about the current list of channels of some other UUID

```java
pubnub.whereNow()
    .uuid("some-other-uuid") // uuid of the user we want to spy on.
    .async(new PNCallback<PNWhereNowResult>() {
        @Override
        public void onResponse(PNWhereNowResult result, PNStatus status) {
            // returns a pojo with channels // channel groups which "some-other-uuid" part of.
        }
    });
```

## User state

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/).
:::

Clients can set a dynamic custom state (score, game state, location) for their users on one or more channels and store it on a channel as long as the user stays subscribed.

The state is not persisted, and when the client disconnects, the state data is lost. For more information, refer to [Presence State](https://www.pubnub.com/docs/general/presence/presence-state).

:::note Presence state format
Presence state must be expressed as a JsonObject. When calling `setState`, be sure to supply an initialized JsonObject or POJO which can be serialized to a JsonObject.
:::

### Method(s)

#### Set state

```java
this.pubnub.setPresenceState()
    .channels(Array)
    .channelGroups(Array)
    .state(HashMap)
    .uuid(String)
```

| Parameter | Description |
| --- | --- |
| `channels`Type: Array | `Channels` to set `state`. |
| `channelGroups`Type: Array | `ChannelGroups` to set `state`. |
| `state`Type: HashMap | `State` to set. |
| `uuid`Type: String | Set `state` for specific `UUID`. |
| `async` *Type: PNCallback | `PNCallback` of type `PNSetStateResult`. |

#### Get state

```java
this.pubnub.getPresenceState()
    .channels(Arrays)
    .channelGroups(Arrays)
    .uuid(String)
```

| Parameter | Description |
| --- | --- |
| `channels`Type: Arrays | `Channel` name to fetch the `state`. |
| `channelGroups`Type: Arrays | `ChannelGroups` name to fetch the `state`. |
| `uuid`Type: String | `UUID` |
| `async` *Type: PNCallback | `PNCallback` of type `PNGetStateResult`. |

### Sample code

#### Set state

```java
JsonObject state = new JsonObject();
state.addProperty("is_typing", isTyping);

pubnub.setPresenceState()
    .channels(Arrays.asList(channel))
    .state(state)
    .async(new PNCallback<PNSetStateResult>() {
        @Override
        public void onResponse(final PNSetStateResult result, PNStatus status) {
        }
    });
```

#### Get state

```java
pubnub.getPresenceState()
    .channels(Arrays.asList("ch1", "ch2", "ch3")) // channels to fetch state for
    .channelGroups(Arrays.asList("cg1", "cg2", "cg3")) // channel groups to fetch state for
    .uuid("suchUUID") // uuid of user to fetch, or for own uuid
    .async(new PNCallback<PNGetStateResult>() {
        @Override
        public void onResponse(PNGetStateResult result, PNStatus status) {
            // handle response
        }
    });
```

### Returns

The `setPresenceState()` operation returns a `PNSetStateResult` which contains the following operations:

| Method | Description |
| --- | --- |
| `getState()`Type: Map`<String, Object>` | Map of `UUIDs` and the user states. |

The `getPresenceState()` operation returns a `PNGetStateResult` which contains the following operations:

| Method | Description |
| --- | --- |
| `getStateByUUID()`Type: Map`<String, Object>` | Map of `UUIDs` and the user states. |

### Other examples

#### Set state for channels in channel group

```java
JsonObject state = new JsonObject();
state.addProperty("is_typing", isTyping);

pubnub.setPresenceState()
    .channelGroups(Arrays.asList("cg1", "cg2", "cg3")) // apply on those channel groups
    .channels(Arrays.asList("ch1", "ch2", "ch3")) // apply on those channels
    .state(state) // the new state
    .async(new PNCallback<PNSetStateResult>() {
        @Override
        public void onResponse(final PNSetStateResult result, PNStatus status) {
            // on new state for those channels
        }
    });
```

The above code would return the following response to the client:

```java
if (presence.getEvent().equals("state-change")) {
        boolean is_typing = presence.getState()
                            .getAsJsonObject()
                            .get("is_typing")
                            .getAsBoolean();
    }
```