Android API & SDK Docs 6.4.5

Unsupported docs

PubNub no longer maintains Android SDK docs, but our Java SDK or Kotlin SDK are fully compatible with the Android platform and you can use them to build mobile apps, ensuring stable software development.

The PubNub Android SDK is part of the PubNub ecosystem, which includes a variety of SDKs and APIs designed to provide real-time communication, data streaming, and connectivity across multiple platforms.

The architecture of the PubNub Android SDK is built to allow high-performance, low-latency communication for mobile applications. It works by connecting your app to PubNub's global data stream network using publish-subscribe protocols. This ensures that messages are sent and received in near real-time, enabling functionalities like live chat, push notifications, and real-time analytics.

When using the PubNub Android SDK, be aware of usage limits relevant for all PubNub SDKs. PubNub offers scalable solutions with tiered service levels, each providing varying degrees of message throughput and concurrent connections. For most applications, the base tier is sufficient, but high-volume apps may need to upgrade to handle additional traffic.

Chat applications

If you want to create a mobile chat application on Android with PubNub, refer to Kotlin Chat SDK for details on all available chat features.

Get code: using Maven

<dependency>
<groupId>com.pubnub</groupId>
<artifactId>pubnub-gson</artifactId>
<version>6.4.5</version>
</dependency>

Get code: using Gradle (including Android Studio)

compile group: 'com.pubnub', name: 'pubnub-gson', version: '6.4.5'

Get code: jar file

To use PubNub, copy the PubNub-6.4.5 JAR file into your project's libs directory.

https://github.com/pubnub/java/releases/tag/6.4.5

Get code: source

https://github.com/pubnub/java/

View Supported Platforms

Configuration: ProGuard

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

-keepattributes Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, *Annotation*, EnclosingMethod

-keep class com.google.android.gms.ads.identifier.** { *; }

# Joda-Time
-dontwarn org.joda.time.**
-keep class org.joda.time.** { *; }

# Gson
-dontwarn sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# OkHttp3
-dontwarn okhttp3.**
-dontwarn org.codehaus.mojo.animal_sniffer.*
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

# Okio
-dontwarn okio.**

# Retrofit 2.X
-dontwarn retrofit2.**
-dontwarn javax.annotation.**
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}

# Logback and slf4j-api
-dontwarn ch.qos.logback.core.net.*
-dontwarn org.slf4j.**
-keep class ch.qos.** { *; }
-keep class org.slf4j.** { *; }

# PubNub
-dontwarn com.pubnub.**
-keep class com.pubnub.** { *; }
show all 65 lines

Hello World

Add PubNub to your project using one of the procedures defined under How to Get It using PubNub API.

Permissions

Put these permissions outside the <application> tag, preferably before the tag in the AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Required UUID

Always set the UUID to uniquely identify the user or device that connects to PubNub. This UUID should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the UUID, you won't be able to connect to PubNub.

public static void main(String[] args) {
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("yourUserId"), "yourSubscribeKey");
// publishKey from Admin Portal (only required if publishing)
configBuilder.publishKey("PublishKey");
PubNub pubnub = PubNub.create(configBuilder.build());

String channelName = "awesomeChannel";

// create message payload using Gson
JsonObject messageJsonObject = new JsonObject();
messageJsonObject.addProperty("msg", "hello");

System.out.println("Message to send: " + messageJsonObject.toString());

pubnub.addListener(new SubscribeCallback() {
@Override
public void status(PubNub pubnub, PNStatus status) {

if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) {
// This event happens when radio / connectivity is lost
}

else if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {

// Connect event. You can do stuff like publish, and know you'll get it.
// Or just use the connected event to confirm you are subscribed for
// UI / internal notifications, etc

if (status.getCategory() == PNStatusCategory.PNConnectedCategory){
pubnub.publish().channel(channelName).message(messageJsonObject).async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
// Check whether request successfully completed or not.
if (!status.isError()) {

// Message successfully published to specified channel.
}
// Request processing failed.
else {

// Handle message publish error. Check 'category' property to find out possible issue
// because of which request did fail.
//
// Request can be resent using: [status retry];
}
}
});
}
}
else if (status.getCategory() == PNStatusCategory.PNReconnectedCategory) {

// Happens as part of our regular operation. This event happens when
// radio / connectivity is lost, then regained.
}
else if (status.getCategory() == PNStatusCategory.PNDecryptionErrorCategory) {

// Handle message decryption error. Probably client configured to
// encrypt messages and on live data feed it received plain text.
}
}

@Override
public void message(PubNub pubnub, PNMessageResult message) {
// Handle new message stored in message.message
if (message.getChannel() != null) {
// Message has been received on channel group stored in
// message.getChannel()
}
else {
// Message has been received on channel stored in
// message.getSubscription()
}

JsonElement receivedMessageObject = message.getMessage();
System.out.println("Received message content: " + receivedMessageObject.toString());
// extract desired parts of the payload, using Gson
String msg = message.getMessage().getAsJsonObject().get("msg").getAsString();
System.out.println("msg content: " + msg);

/*
log the following items with your favorite logger
- message.getMessage()
- message.getSubscription()
- message.getTimetoken()
*/
}

@Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {

}
});

pubnub.subscribe().channels(Arrays.asList(channelName)).execute();
}
show all 95 lines

Copy and paste examples

In addition to the Hello World sample code, we also provide some copy and paste snippets of common API functions that can streamline your software integration process:

Init

Instantiate a new Pubnub instance. Only the subscribeKey is mandatory. Also include publishKey if you intend to publish from this instance, and the secretKey if you wish to perform Access Manager administrative operations from this Android instance.

Secure your secretKey

For security reasons, you should only include the secret key on a highly secured server. The secret key is only required for granting rights using our Access Manager.

When you init with secretKey, you get root permissions for the Access Manager. With this feature you don't have to grant access to your servers to access channel data. The servers get all access on all channels.

Initializing the client

Required User ID

Always set the UserId to uniquely identify the user or device that connects to PubNub. This UserId should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the UserId, you won't be able to connect to PubNub.

PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("yourUserId"), "yourSubscribeKey");
// publishKey from Admin Portal (only required if publishing)
configBuilder.publishKey("PublishKey");
configBuilder.secure(true);
PubNub pubNub = PubNub.create(configBuilder.build());

Listeners

Add listeners

pubnub.addListener(new SubscribeCallback() {
// PubNub status
@Override
public void status(PubNub pubnub, PNStatus status) {
switch (status.getOperation()) {
// combine unsubscribe and subscribe handling for ease of use
case PNSubscribeOperation:
case PNUnsubscribeOperation:
// Note: subscribe statuses never have traditional errors,
// just categories to represent different issues or successes
// that occur as part of subscribe
switch (status.getCategory()) {
case PNConnectedCategory:
// No error or issue whatsoever.
case PNReconnectedCategory:
// Subscribe temporarily failed but reconnected.
// There is no longer any issue.
case PNDisconnectedCategory:
// No error in unsubscribing from everything.
case PNUnexpectedDisconnectCategory:
// Usually an issue with the internet connection.
// This is an error: handle appropriately.
case PNAccessDeniedCategory:
// Access Manager does not allow this client to subscribe to this
// channel and channel group configuration. This is
// another explicit error.
default:
// You can directly specify more errors by creating
// explicit cases for other error categories of
// `PNStatusCategory` such as `PNTimeoutCategory` or
// `PNMalformedFilterExpressionCategory` or
// `PNDecryptionErrorCategory`.
}

case PNHeartbeatOperation:
// Heartbeat operations can in fact have errors, so it's important to check first for an error.
if (status.isError()) {
// There was an error with the heartbeat operation, handle here
} else {
// heartbeat operation was successful
}
default: {
// Encountered unknown status type
}
}
}

// Messages
@Override
public void message(PubNub pubnub, PNMessageResult message) {
String messagePublisher = message.getPublisher();
System.out.println("Message publisher: " + messagePublisher);
System.out.println("Message Payload: " + message.getMessage());
System.out.println("Message Subscription: " + message.getSubscription());
System.out.println("Message Channel: " + message.getChannel());
System.out.println("Message timetoken: " + message.getTimetoken());
}

// Presence
@Override
public void presence(@NotNull PubNub pubnub, @NotNull PNPresenceEventResult presence) {
System.out.println("Presence Event: " + presence.getEvent());
// Can be join, leave, state-change or timeout

System.out.println("Presence Channel: " + presence.getChannel());
// The channel to which the message was published

System.out.println("Presence Occupancy: " + presence.getOccupancy());
// Number of users subscribed to the channel

System.out.println("Presence State: " + presence.getState());
// User state

System.out.println("Presence UUID: " + presence.getUuid());
// UUID to which this event is related

presence.getJoin();
// List of users that have joined the channel (if event is 'interval')

presence.getLeave();
// List of users that have left the channel (if event is 'interval')

presence.getTimeout();
// List of users that have timed-out off the channel (if event is 'interval')

presence.getHereNowRefresh();
// Indicates to the client that it should call 'hereNow()' to get the
// complete list of users present in the channel.
}

// Signals
@Override
public void signal(PubNub pubnub, PNSignalResult pnSignalResult) {
System.out.println("Signal publisher: " + signal.getPublisher());
System.out.println("Signal payload: " + signal.getMessage());
System.out.println("Signal subscription: " + signal.getSubscription());
System.out.println("Signal channel: " + signal.getChannel());
System.out.println("Signal timetoken: " + signal.getTimetoken());
}

// Message reactions
@Override
public void messageAction(PubNub pubnub, PNMessageActionResult pnActionResult) {
PNMessageAction pnMessageAction = pnActionResult.getAction();
System.out.println("Message reaction type: " + pnMessageAction.getType());
System.out.println("Message reaction value: " + pnMessageAction.getValue());
System.out.println("Message reaction uuid: " + pnMessageAction.getUuid());
System.out.println("Message reaction actionTimetoken: " + pnMessageAction.getActionTimetoken());
System.out.println("Message reaction messageTimetoken: " + pnMessageAction.getMessageTimetoken());
System.out.println("Message reaction subscription: " + pnActionResult.getSubscription());
System.out.println("Message reaction channel: " + pnActionResult.getChannel());
System.out.println("Message reaction timetoken: " + pnActionResult.getTimetoken());
}

// files
@Override
public void file(PubNub pubnub, PNFileEventResult pnFileEventResult) {
System.out.println("File channel: " + pnFileEventResult.getChannel());
System.out.println("File publisher: " + pnFileEventResult.getPublisher());
System.out.println("File message: " + pnFileEventResult.getMessage());
System.out.println("File timetoken: " + pnFileEventResult.getTimetoken());
System.out.println("File file.id: " + pnFileEventResult.downloadFile().getId());
System.out.println("File file.name: " + pnFileEventResult.downloadFile().getName());
System.out.println("File file.url: " + pnFileEventResult.downloadFile().getUrl());
}
});
show all 126 lines

Remove listeners

SubscribeCallback subscribeCallback = new SubscribeCallback() {
@Override
public void status(PubNub pubnub, PNStatus status) {

}

@Override
public void message(PubNub pubnub, PNMessageResult message) {

}

@Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {

}

@Override
public void signal(PubNub pubnub, PNSignalResult pnSignalResult) {

}

@Override
public void messageAction(PubNub pubnub, PNMessageActionResult pnActionResult) {

}

@Override
public void user(PubNub pubnub, PNUserResult pnUserResult) {

}

@Override
public void space(PubNub pubnub, PNSpaceResult pnSpaceResult) {

}

@Override
public void membership(PubNub pubnub, PNMembershipResult pnMembershipResult) {

}

@Override
public void file(PubNub pubnub, PNFileEventResult pnFileEventResult) {

}

};

pubnub.addListener(subscribeCallback);

// some time later
pubnub.removeListener(subscribeCallback);
show all 52 lines

Handle disconnects

Ensure your software can handle network changes and integrate effective reconnection strategies:

SubscribeCallback subscribeCallback = new SubscribeCallback() {
@Override
public void status(PubNub pubnub, PNStatus status) {
if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) {
// internet got lost, do some magic and call reconnect when ready
pubnub.reconnect();
} else if (status.getCategory() == PNStatusCategory.PNTimeoutCategory) {
// do some magic and call reconnect when ready
pubnub.reconnect();
} else {
log.error(status);
}
}

@Override
public void message(PubNub pubnub, PNMessageResult message) {

}

@Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {

}
};

pubnub.addListener(subscribeCallback);
show all 26 lines

Listener status events

CategoryDescription
PNNetworkUpCategory
The SDK detected that the network is online.
PNNetworkDownCategory
The SDK announces this when a connection isn't available, or when the SDK isn't able to reach PubNub servers.
PNNetworkIssuesCategory
A subscribe event experienced an exception when running. The SDK isn't able to reach PubNub servers. This may be due to many reasons, such as: the machine or device isn't connected to the internet; the internet connection has been lost; your internet service provider is having trouble; or, perhaps the SDK is behind a proxy.
PNReconnectedCategory
The SDK was able to reconnect to PubNub.
PNConnectedCategory
SDK subscribed with a new mix of channels. This is fired every time the channel or channel group mix changes.
PNAccessDeniedCategory
Access Manager permission failure.
PNMalformedResponseCategory
JSON parsing crashed.
PNBadRequestCategory
The server responded with a bad response error because the request is malformed.
PNDecryptionErrorCategory
If using decryption strategies and the decryption fails.
PNTimeoutCategory
Failure to establish a connection to PubNub due to a timeout.
PNRequestMessageCountExceedCategory
The SDK announces this error if requestMessageCountThreshold is set, and the number of messages received from PubNub (in-memory cache messages) exceeds the threshold.
PNUnknownCategory
Returned when the subscriber gets a non-200 HTTP response code from the server.

Subscribe

Subscribe (listen on) a channel:

pubnub.subscribe()
.channels(Arrays.asList("my_channel")) // subscribe to channels
.execute();
Event listeners

The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.

Publish

Publish a message to a channel:

pubnub.publish()
.message(Arrays.asList("hello", "there"))
.channel("suchChannel")
.async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
// handle publish result, status always present, result if successful
// status.isError to see if error happened
}
});

Here now

Get occupancy of who's here now on the channel by UUID:

Requires Presence

This method requires that the Presence add-on is enabled for your key in the Admin Portal.

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());
}
}
}
});
show all 23 lines

Presence

Subscribe to real-time Presence events, such as join, leave, and timeout, by UUID. Setting the presence attribute to a callback will subscribe to presence events on my_channel:

Requires Presence

This method requires that the Presence add-on is enabled for your key in the Admin Portal.

pubnub.subscribe()
.channels(Arrays.asList("my_channel")) // subscribe to channels
.withPresence() // also subscribe to related presence information
.execute();
Event listeners

The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.

History

Retrieve published messages from archival storage:

Requires Message Persistence

This method requires that Message Persistence is enabled for your key in the Admin Portal.

pubnub.history()
.channel("history_channel") // where to fetch history from
.count(100) // how many items to fetch
.async(new PNCallback<PNHistoryResult>() {
@Override
public void onResponse(PNHistoryResult result, PNStatus status) {

}
});

Unsubscribe

Stop subscribing (listening) to a channel:

pubnub.unsubscribe()
.channels(Arrays.asList("my_channel"))
.execute();
Event listeners

The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.

Destroy

For more details, please see the Destroy section.

pubnub.destroy();
Last updated on