Android SDK 4.35.0
Get Code: Using Maven
<dependency>
<groupId>com.pubnub</groupId>
<artifactId>pubnub-gson</artifactId>
<version>4.35.0</version>
</dependency>
Get Code: Using Gradle (Including Android Studio)
compile group: 'com.pubnub', name: 'pubnub-gson', version: '4.35.0'
Get Code: jar file
To use Pubnub, simply copy the Pubnub-4.35.0 jar file into your project's libs directory.
Get Code: Source
https://github.com/pubnub/java/
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.** { *; }
Hello World
Add PubNub to your project using one of the procedures defined under How to Get It
Note
Put these permission outside the <application>
tag, preferable before the tag in the AndroidManifest.xml
.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Note
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. Not setting the UUID
can significantly impact your billing if your account uses the Monthly Active Users (MAUs) based pricing model, and can also lead to unexpected behavior if you have Presence enabled.
public static void main(String[] args) {
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("demo");
pnConfiguration.setPublishKey("demo");
pnConfiguration.setUuid("myUniqueUUID");
PubNub pubnub = new PubNub(pnConfiguration);
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 messsage 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();
}
Copy and paste examples
In addition to the Hello World sample code, we also provide some copy and paste snippets of common API functions:
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 PAM administrative operations from this Android V4 instance.
Important
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
Note
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. Not setting the UUID
can significantly impact your billing if your account uses the Monthly Active Users (MAUs) based pricing model, and can also lead to unexpected behavior if you have Presence enabled.
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("SubscribeKey");
pnConfiguration.setPublishKey("PublishKey");
pnConfiguration.setSecure(false);
pnConfiguration.setUuid("myUniqueUUID");
PubNub pubnub = new PubNub(pnConfiguration);
Listeners
Adding 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:
// PAM 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.
// For more information on how to configure heartbeat notifications through the status
// PNObjectEventListener callback, refer to
// /docs/sdks/java/android/api-reference/configuration#configuration_basic_usage
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 actions
@Override
public void messageAction(PubNub pubnub, PNMessageActionResult pnActionResult) {
PNMessageAction pnMessageAction = pnActionResult.getAction();
System.out.println("Message action type: " + pnMessageAction.getType());
System.out.println("Message action value: " + pnMessageAction.getValue());
System.out.println("Message action uuid: " + pnMessageAction.getUuid());
System.out.println("Message action actionTimetoken: " + pnMessageAction.getActionTimetoken());
System.out.println("Message action messageTimetoken: " + pnMessageAction.getMessageTimetoken());]
System.out.println("Message action subscription: " + pnActionResult.getSubscription());
System.out.println("Message action channel: " + pnActionResult.getChannel());
System.out.println("Message action 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.getFile().getId());
System.out.println("File file.name: " + pnFileEventResult.getFile().getName());
System.out.println("File file.url: " + pnFileEventResult.getFile().getUrl());
}
});
Removing 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);
Handling Disconnects
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);
Listener status events
Category | Description |
---|---|
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 the PubNub Data Stream Network. |
PNNetworkIssuesCategory | A subscribe event experienced an exception when running. The SDK isn't able to reach the PubNub Data Stream Network. 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 | PAM 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. |
Time
Call time()
to verify the client connectivity to the origin:
pubnub.time().async(new PNCallback<PNTimeResult>() {
@Override
public void onResponse(PNTimeResult result, PNStatus status) {
// handle time result.
}
});
Subscribe
Subscribe (listen on) a channel:
pubnub.subscribe()
.channels(Arrays.asList("my_channel")) // subscribe to channels
.execute();
Note
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:
Note
Requires you to enable the Presence
add-on for your key. Refer to the How do I enable add-on features for my keys? knowledge base article for details on enabling features.
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());
}
}
}
});
Presence
Subscribe to realtime Presence events, such as join
, leave
, and timeout
, by UUID. Setting the presence attribute to a callback will subscribe to presents events on my_channel
:
Note
Requires you to enable the Presence
add-on for your key. Refer to the How do I enable add-on features for my keys? knowledge base article for details on enabling features.
pubnub.subscribe()
.channels(Arrays.asList("my_channel")) // subscribe to channels
.withPresence() // also subscribe to related presence information
.execute();
Note
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:
Note
Requires that the Storage and Playback
add-on is enabled for your key. How do I enable add-on features for my keys? - see https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-
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();
Note
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();