Android XMPP Chat Sample

Ask tech team
From QuickBlox Developers (API docs, code samples, SDK)
Jump to: navigation, search

Contents

Sources

Project homepage on GIT — https://github.com/QuickBlox/quickblox-android-sdk/tree/master/sample-chat

Download ZIP - https://github.com/QuickBlox/quickblox-android-sdk/archive/master.zip


Overview

This sample demonstrates how to work with QuickBlox Chat API.
It allows you to organise the group chat & chat 1 on 1

It gives examples of how to:

  1. Organize chat between 2 users
  2. Organise group chat

Setup

Android Studio IDE

Doesn't require additional configuration. Gradle does it for you.

Eclipse IDE

  1. File->Import->Android->Existing Android Code Into Workspace
  2. Browse sample-chat sample location and click Finish - see next screenshot
  3. Setup QuickBlox:
    1. Go to Project->Properties->Java Build Path->Libraries->Add External JARs, add <quickblox-android-sdk>/jars/quickblox-android-sdk-core-2.0.jar and <quickblox-android-sdk>/jars/quickblox-android-sdk-chat-2.0.jar
    2. Go to Project->Properties->Java Build Path->Libraries->Order&Export, check quickblox-android-sdk-core-2.0.jar and quickblox-android-sdk-chat-2.0.jar
  4. Setup AppCompat:
    1. Use next guide to add AppCompat in Eclipse
    2. Set the latest build target for AppCompat library project
  5. Setup PullToRefresh:
    1. File->Import sample-chat/libraries/pull-to-refresh
    2. Do same thing as for AppCompat
    3. Also add AppCompat as the library project to PullToRefresh
  6. Clean and rebuild project


Guide: Getting Started with Chat API

Getting a QuickBlox account

http://admin.quickblox.com/register

Creating applications in the Admin panel

http://admin.quickblox.com/apps/new

In addition, there is this helpful 5 minute guide.

Login to Chat

Note: In order to login to the chat please read the information about Chat login/password formation.

In order to use QuickBlox Chat APIs you must:

  • Create session & Sign In to QuickBlox OR just create session with user
  • Sign In to QuickBlox Chat


Please follow the lines below:

Create session with User & Sign In to QuickBlox Chat

// Initialise Chat service
QBChatService chatService;
if (!QBChatService.isInitialized()) {
    QBChatService.init(context);
    chatService = QBChatService.getInstance();
}
 
final QBUser user = new QBUser("garrysantos", "garrysantospass");
QBAuth.createSession(), new QBEntityCallbackImpl<QBSession>() {
    @Override
    public void onSuccess(QBSession session, Bundle params) {
        // success, login to chat
 
        user.setId(session.getUserId());
 
        chatService.login(qbUser, new QBEntityCallbackImpl() {
            @Override
            public void onSuccess() {
                // success
            }
 
            @Override
            public void onError(List errors) {
                // errror
            }
        });
    }
 
    @Override
    public void onError(List<String> errors) {
        // errors
    }
});

Keep in mind that the QuickBlox Chat is a standard XMPP chat and you need to send presence periodically to remain available. Just create a timer that will send presence each 60 seconds:

QBChatService.getInstance().startAutoSendPresence(60);

To handle different connection states use ConnectionListener:

ConnectionListener connectionListener = new ConnectionListener() {
    @Override
    public void connected(XMPPConnection connection) {
 
    }
 
    @Override
    public void authenticated(XMPPConnection connection) {
 
    }
 
    @Override
    public void connectionClosed() {
 
    }
 
    @Override
    public void connectionClosedOnError(Exception e) {
        // connection closed on error. It will be established soon
    }
 
    @Override
    public void reconnectingIn(int seconds) {
 
    }
 
    @Override
    public void reconnectionSuccessful() {
 
    }
 
    @Override
    public void reconnectionFailed(Exception e) {
 
    }
};
 
QBChatService.getInstance().addConnectionListener(connectionListener);


Logout from Chat

Next code does chat logout:

boolean isLoggedIn = chatService.isLoggedIn();
if(!isLoggedIn){
    return;
}
 
chatService.logout(new QBEntityCallbackImpl() {
 
    @Override
    public void onSuccess() {
        // success
 
        chatService.destroy();
    }
 
    @Override
    public void onError(final List list) {
 
    }
});

Dialogs

QuickBlox provides a way to organise a chat dialogs page where you can show all user's current chat dialogs.

Dialogs can have next types:

  • 1-1 private dialog - a chat dialog between 2 users
  • Group dialog - a chat dialog between many users
  • Open group dialog - open chat dialog, any user can join and chat here.

Retrieve list of dialogs

Here is how typical screen with all your chats looks like:

Chat2 dialogs android.png

Request Dialogs each time user logins to app:

QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
requestBuilder.setPagesLimit(100);
 
QBChatService.getChatDialogs(null, requestBuilder, new QBEntityCallbackImpl<ArrayList<QBDialog>>() {
    @Override
    public void onSuccess(ArrayList<QBDialog> dialogs, Bundle args) {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

Filters

There are some filters to get only chat dialogs you need, not just all:

Operator Applied fields Description Usage example
{field_name} all Search records with field which contains exactly specified value requestBuilder.addParameter("type", "2");
{field_name}[{search_operator}] all Search record with field which contains value according to specified value and operator.

Possible filters: lt (Less Than operator), lte (Less Than or Equal to operator), gt (Greater Than operator), gte (Greater Than or Equal to operator), ne (Not Equal to operator), in (Contained IN array operator), nin (Not contained IN array), all (ALL contained IN array), or (OR operator), ctn (Contains substring operator)
requestBuilder.in("type", "1", "2");
limit standalone operator Limit search results to N records. Useful for pagination. Default value - 100 requestBuilder.setPagesLimit(100);
skip standalone operator Skip N records in search results. Useful for pagination. Default (if not specified): 0 requestBuilder.setPagesSkip(50);
sort_desc/sort_asc type,last_message_date_sent Search results will be sorted by specified field in ascending/descending order requestBuilder.sortAsc("last_message_

date_sent");

Create new dialog

According to REST API, Create a dialog query, you don't need to create a dialog for 1-1(private) chat - it will be created automatically with 1st chat message. But you can create it anyway if you need this for your application.

Create new group chat dialog

When user would like to start a group chat - he must create a group chat dialog first.

Chat2 new dialog android.png

User should choose other users to add them to a new group dialog. Also he should choose a name for new group chat:

ArrayList<Integer> occupantIdsList = new ArrayList<Integer>();
occupantIdsList.add(34);
occupantIdsList.add(17);
 
QBDialog dialog = new QBDialog();
dialog.setName("Chat with Garry and John");
dialog.setPhoto("1786");
dialog.setType(QBDialogType.GROUP);
dialog.setOccupantsIds(occupantIdsList);
 
QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager();
groupChatManager.createDialog(dialog, new QBEntityCallbackImpl<QBDialog>() {
    @Override
    public void onSuccess(QBDialog dialog, Bundle args) {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

To notify all occupants that you created a group chat we use chat notifications - it's simple chat message with extra parameters inside. These parameters used to separate chat notifications from regular text chat messages:

public static QBChatMessage createChatNotificationForGroupChatCreation(QBDialog dialog) {
    String dialogId = String.valueOf(dialog.getDialogId());
    String roomJid = dialog.getRoomJid();
    String occupantsIds = TextUtils.join(",", dialog.getOccupants());
    String dialogName = dialog.getName();
    String dialogTypeCode = String.valueOf(dialog.getType().ordinal());
 
    QBChatMessage chatMessage = new QBChatMessage();
    chatMessage.setBody("optional text");
 
    // Add notification_type=1 to extra params when you created a group chat 
    //
    chatMessage.setProperty("notification_type", "1");
 
    chatMessage.setProperty("_id", dialogId);
    if (!TextUtils.isEmpty(roomJid)) {
        chatMessage.setProperty("room_jid", roomJid);
    }
    chatMessage.setProperty("occupants_ids", occupantsIds);
    if (!TextUtils.isEmpty(dialogName)) {
        chatMessage.setProperty("name", dialogName);
    }
    chatMessage.setProperty("type", dialogTypeCode);
 
    return chatMessage;
}
 
...
 
for (Integer userID : dialog.getOccupants()) {
 
    QBChatMessage chatMessage = createChatNotificationForGroupChatCreation(dialog);
 
    long time = DateUtils.getCurrentTime();
    chatMessage.setProperty("date_sent", time + "");
 
    QBPrivateChat chat = QBChatService.getInstance().getPrivateChatManager().getChat(userID);
    if (chat == null) {
        chat = chatService.getPrivateChatManager().createChat(userID, null);
    }
 
    try {
        chat.sendMessage(chatMessage);
    } catch (Exception e) {
        // error
    }
}


Set dialog's avatar

The Chat dialog contains a field photo. It's a string field, can contain any value:


For example, we use Content module to store the dialog's photo. Next snippets show how to upload a file to Content module and set it as a photo of a dialog:

File filePhoto = new File("dialog_avatar.png");
Boolean fileIsPublic = false;
QBContent.uploadFileTask(filePhoto, fileIsPublic, null, new QBEntityCallbackImpl<QBFile>() {
    @Override
    public void onSuccess(QBFile file, Bundle params) {        
        dialog.setPhoto(file.getId().toString);
    }
 
    @Override
    public void onError(List<String> errors) {
        // error
    }
});

Create new 1-1(private) chat dialog

If you would like to create a private chat dialog too - use next snippets:

QBPrivateChatManager privateChatManager = QBChatService.getInstance().getPrivateChatManager();
privateChatManager.createDialog(opponentId, new QBEntityCallbackImpl<QBDialog>() {
    @Override
    public void onSuccess(QBDialog dialog, Bundle args) {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

Update group dialog

User can update group chat dialog name, add new occupants or leave this group chat. To add more occupants use push operator. To leave group chat (remove yourself) - use pull all operator:

Chat2 update dialog android.png


QBRequestUpdateBuilder requestBuilder = new QBRequestUpdateBuilder();
requestBuilder.push("occupants_ids", 378); // add another users
// requestBuilder.pullAll("occupants_ids", 22); // Remove yourself (user with ID 22)
 
QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager();
groupChatManager.updateDialog("53aac645535c12bd3b008a40", "Team room", requestBuilder, new QBEntityCallbackImpl<QBDialog>() {
    @Override
    public void onSuccess(QBDialog dialog, Bundle args) {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

To notify all occupants that you updated a group chat we use chat notifications - it's simple chat message with extra parameters inside. These parameters used to separate chat notifications from regular text chat messages:

public static QBChatMessage createChatNotificationForGroupChatUpdate(QBDialog dialog) {
    String dialogId = String.valueOf(dialog.getDialogId());
    String roomJid = dialog.getRoomJid();
    String occupantsIds = TextUtils.join(",", dialog.getOccupants());
    String dialogName = dialog.getName();
    String dialogTypeCode = String.valueOf(dialog.getType().ordinal());
 
    QBChatMessage chatMessage = new QBChatMessage();
    chatMessage.setBody("optional text");
 
    // Add notification_type=2 to extra params when you updated a group chat 
    //
    chatMessage.setProperty("notification_type", "2");
 
    chatMessage.setProperty("_id", dialogId);
    if (!TextUtils.isEmpty(roomJid)) {
        chatMessage.setProperty("room_jid", roomJid);
    }
    chatMessage.setProperty("occupants_ids", occupantsIds);
    if (!TextUtils.isEmpty(dialogName)) {
        chatMessage.setProperty("name", dialogName);
    }
    chatMessage.setProperty("type", dialogTypeCode);
 
    return chatMessage;
}
 
...
 
for (Integer userID : dialog.getOccupants()) {
 
    QBChatMessage chatMessage = createChatNotificationForGroupChatUpdate(dialog);
 
    long time = DateUtils.getCurrentTime();
    chatMessage.setProperty("date_sent", time + "");
 
    QBPrivateChat chat = QBChatService.getInstance().getPrivateChatManager().getChat(userID);
    if (chat == null) {
        chat = chatService.getPrivateChatManager().createChat(userID, null);
    }
 
    try {
        chat.sendMessage(chatMessage);
    } catch (Exception e) {
        // error
    }
}

Delete dialog

To delete a dialog use next snippet:

QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager();
groupChatManager.deleteDialog(dialogID, new QBEntityCallbackImpl<Void>() {
    @Override
    public void onSuccess() {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

This request will remove this dialog for current user, but other users still will be able to chat there.

Chat in dialog

Chat in 1-1 private dialog

To send a message in 1-1 chat - choose opponent's user ID and create a body of chat message.

QBMessageListener<QBPrivateChat> privateChatMessageListener = new QBMessageListener<QBPrivateChat>() {
    @Override
    public void processMessage(QBPrivateChat privateChat, final QBChatMessage chatMessage) {
 
    }
 
    @Override
    public void processError(QBPrivateChat privateChat, QBChatException error, QBChatMessage originMessage){
 
    }
 
    @Override
    public void processMessageDelivered(QBPrivateChat privateChat, String messageID){
 
    }
 
    @Override
    public void processMessageRead(QBPrivateChat privateChat, String messageID){
    }
};
 
QBPrivateChatManagerListener privateChatManagerListener = new QBPrivateChatManagerListener() {
    @Override
    public void chatCreated(final QBPrivateChat privateChat, final boolean createdLocally) {
        if(!createdLocally){
            privateChat.addMessageListener(privateChatMessageListener);
        }
    }
};
QBChatService.getInstance().getPrivateChatManager().addPrivateChatManagerListener(privateChatManagerListener);
 
Integer opponentId = 45;
 
try {
    QBChatMessage chatMessage = new QBChatMessage();
    chatMessage.setBody("Hi there!");
    chatMessage.setProperty("save_to_history", "1"); // Save a message to history
 
    QBPrivateChat privateChat = privateChatManager.getChat(opponentId);
    if (privateChat == null) {
        privateChat = privateChatManager.createChat(opponentId, privateChatMessageListener);
    }
    privateChat.sendMessage(chatMessage);
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
}

Chat in group dialog

Before start chating in a group dialog you should join this dialog.

QBMessageListener<QBGroupChat> groupChatQBMessageListener = new QBMessageListener<QBGroupChat>() {
    @Override
    public void processMessage(final QBGroupChat groupChat, final QBChatMessage chatMessage) {
 
    }
 
    @Override
    public void processError(final QBGroupChat groupChat, QBChatException error, QBChatMessage originMessage){
 
    }
 
    @Override
    public void processMessageDelivered(QBGroupChat groupChat, String messageID){
        // never be called, works only for 1-1 chat
    }
 
    @Override
    public void processMessageRead(QBGroupChat groupChat, String messageID){
        // never be called, works only for 1-1 chat
    }
};
 
QBDialog groupDialog = ...;
 
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(0);
 
QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager();
 
QBGroupChat currentChatRoom = groupChatManager.createGroupChat(groupDialog.getRoomJid());
currentChatRoom.join(history, new QBEntityCallbackImpl() {
    @Override
    public void onSuccess() {
        // add listeners
        currentChatRoom.addMessageListener(groupChatQBMessageListener);
    }
 
    @Override
    public void onError(final List list) {
 
    }
});


Now you can send and receive messages:

QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody("Hi there");
chatMessage.setProperty("save_to_history", "1"); // Save to Chat 2.0 history
 
try {
    currentChatRoom.sendMessage(chatMessage);
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
} catch (IllegalStateException e){
 
}
Get online users

You can request online users in group chat dialog

Collection<Integer> onlineGroupUsers = null;
try {
    onlineRoomUsers = currentChatRoom.getOnlineUsers();
} catch (XMPPException e) {
 
}
Leave group chat dialog
try {
    currentChatRoom.leave();
    currentChatRoom = null;
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
}

Send and receive a message with attachment

Send attachment

It's possible to add attachments to message: for example, image, audio file or video file. We don't have any restrictions here - you can attach any type of file.

To send a message with attachments you should use the same way as you send regular message with text, but add to it an attachment object. Attachment can be:


To send a message with attachment you have to upload a file to Content module, Custom Objects module using sample above or use an url to any file in Internet. Then you should incorporate an ID to file to message.

For example, we use Content module to store attachments. Next snippets show how to upload a file to Content module and send it as an attach:

File filePhoto = new File("holy_grail.png");
Boolean fileIsPublic = false;
QBContent.uploadFileTask(filePhoto, fileIsPublic, null, new QBEntityCallbackImpl<QBFile>() {
    @Override
    public void onSuccess(QBFile file, Bundle params) {
 
        // create a message
        QBChatMessage chatMessage = new QBChatMessage();
        chatMessage.setProperty("save_to_history", "1"); // Save a message to history
 
        // attach a photo
        QBAttachment attachment = new QBAttachment("photo");
        attachment.setId(file.getId().toString());
        chatMessage.addAttachment(attachment);
 
        // send a message
        // ...
    }
 
    @Override
    public void onError(List<String> errors) {
        // error
    }
});

Receive attachment

For example we use Content module to store attachments. Next snippets allow to receive a message with an attachment and download it:

// QBMessageListener
 
...
 
@Override
public void processMessage(QBPrivateChat privateChat, final QBChatMessage chatMessage) {
    for(QBAttachment attachment : chatMessage.getAttachments()){
        Integer fileId = attachment.getId();
 
        // download a file
        QBContent.downloadFileTask(fileId, new QBEntityCallbackImpl<InputStream>(){
            @Override
            public void onSuccess(InputStream inputStream, Bundle params) {
                // process file
            }
 
            @Override
            public void onError(List<String> errors) {
                // errors
            }
        });
    }
}
 
...

Use custom parameters in a message

You can use custom parameters for the messages you send in the chat, for example to send some additional info or to send control messages:

QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody("Hi there");
 
chatMessage.setProperty("name", "Bob");
chatMessage.setProperty("age", "25");


Chat history

You can choose a way to save chat message to history or not. If you decided to store - you should add save_to_history parameter to message:

QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setProperty("save_to_history", "1");
...


List chat messages

If you decided to use save_to_history parameter - all chat messages will be stored to history and user can request a chat history for particular dialog.

Chat2 messages android.png

To get a chat history for particular dialog use next request:

QBDialog qbDialog = new QBDialog("53cfc593efa3573ebd000017");
 
QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
requestBuilder.setPagesLimit(100);
 
QBChatService.getDialogMessages(qbDialog, customObjectRequestBuilder, new QBEntityCallbackImpl<ArrayList<QBChatHistoryMessage>>() {
    @Override
    public void onSuccess(ArrayList<QBChatHistoryMessage> messages, Bundle args) {
 
    }
 
    @Override
    public void onError(List<String> errors) {
 
    }
});

Filters

There are some filters to get only chat dialogs you need, not just all:

Operator Applied fields Description Usage example
{field_name} all Search records with field which contains exactly specified value requestBuilder.addParameter("type", "2");
{field_name}[{search_operator}] all Search record with field which contains value according to specified value and operator.

Possible filters: lt (Less Than operator), lte (Less Than or Equal to operator), gt (Greater Than operator), gte (Greater Than or Equal to operator), ne (Not Equal to operator), in (Contained IN array operator), nin (Not contained IN array), all (ALL contained IN array), or (OR operator), ctn (Contains substring operator)
requestBuilder.in("type", "1", "2");
limit standalone operator Limit search results to N records. Useful for pagination. Default value - 100 requestBuilder.setPagesLimit(100);
skip standalone operator Skip N records in search results. Useful for pagination. Default (if not specified): 0 requestBuilder.setPagesSkip(50);
sort_desc/sort_asc type,last_message_date_sent Search results will be sorted by specified field in ascending/descending order requestBuilder.sortAsc("last_message_

date_sent");


Push notifications to the offline users

QuickBlox provides a way to setup automatic push notifications for the offline users. It means if your opponent is offline while you writing a message - he can automatically receive push notification.

Look at Admin panel and read how to setup automatic push notifications in Alerts section.


Dashboard

QuickBlox dashboard provide a way to view and manage all dialogs for your application. Go to admin panel, Chat module. Read more info here.


Contact list

Contact list mode

In traditional IM applications, the "buddy" system is rather straightforward. User A sends a request to become "friends" with user B. User B accepts the friend request. And now user A and B appear in each other's roster.


But, alternatively, you can use twitter like logic. User A sends a presence subscription request to user B. Think about this more like following on twitter. User A is requesting permission to receive presence information from user B (following their presence). User B can accept this request, but may not be interested in receiving presence info from user B. Again, this is more like twitter following, but with the addition of required permission.So when user B accepts the request, this *only* means that user A will receive presence from user B. It does *not* mean that user B will receive presence from user A. Again, twitter-style, user A is now "following" user B. In diagram form, presence is flowing like this:

 A <-- B


Now, if B also wants to receive presence from user A, then user B must request this permission. And furthermore, user A must accept the request. Just because B has granted A permission to receive presence, doesn't mean that B gets a free pass to receive presence from A.


By default this SDK provides 'twitter like' mode.

To enable Facebook like logic pass QBRoster.SubscriptionMode.mutual value when you are obtaining a roser:

QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener);

Access to the Contact list

Main setup

To access contact list you have to obtain it and set all needed listeners:

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) {
 
    }
};
 
QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() {
    @Override
    public void subscriptionRequested(int userId) {
 
    }
};
 
 
// Do this after success Chat login
QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener);
chatRoster.addRosterListener(rosterListener);

QBRosterListener is a listener that is fired any time a roster is changed or the presence of a user in the roster is changed (user becomes online/offline)

QBSubscriptionListener is a listener that is fired on "subscribe" (add to contact list) request from any user.

Access contact list users

To get users from contact list:

Collection<QBRosterEntry> entries = сhatRoster.getEntries();

QBRosterEntry describes a user entity in your contact list. To get user's ID use getUserId() getter.

To request user's status (online/offline):

int userID = 45;
 
QBPresence presence = chatRoster.getPresence(userID);
if (presence == null) {
    // No user in your roster
    return;
}
 
if (presence.getType() == QBPresence.Type.online) {
    // User is online
}else{
    // User is offline
}

Add/Remove users

To add users to the contact list just use the method below:

int userID = 56;
 
if (chatRoster.contains(userID)) {
    try {
        chatRoster.subscribe(userID);
    } catch (SmackException.NotConnectedException e) {
 
    }
} else {
    try {
        chatRoster.createEntry(userID, null);
    } catch (XMPPException e) {
 
    } catch (SmackException.NotLoggedInException e) {
 
    } catch (SmackException.NotConnectedException e) {
 
    } catch (SmackException.NoResponseException e) {
 
    }
}

This user will receive the request to be added to the contact list

// QBSubscriptionListener
 
...
 
@Override
public void subscriptionRequested(int userId) {
 
}

To confirm the request:

try {
    chatRoster.confirmSubscription(userID);
} catch (SmackException.NotConnectedException e) {
 
} catch (SmackException.NotLoggedInException e) {
 
} catch (XMPPException e) {
 
} catch (SmackException.NoResponseException e) {
 
}

To reject the request:

try {
    chatRoster.reject(userID);
} catch (SmackException.NotConnectedException e) {
 
}

To remove a previously added user from the contact list:

int userID = 67;
 
try {
    chatRoster.unsubscribe(userID);
} catch (SmackException.NotConnectedException e) {
 
}

Custom status

A client MAY provide detailed status information to his contacts by constructing a presence object by himself:

QBPresence presence = new QBPresence(QBPresence.Type.online, "I'm at home", 1, QBPresence.Mode.available);
try {
    chatRoster.sendPresence(presence);
} catch (SmackException.NotConnectedException e) {
 
}

In this case there is no need to use QBChatService.getInstance().startAutoSendPresence(60);, you have to manage it by yourself.

Privacy list

coming soon


Typing status

Many instant messaging systems include notifications about the state of one's conversation partner in a one-to-one chat (or, sometimes, in a many-to-many chat). In essence, chat state notifications can be thought of as a form of chat-specific presence.

This section describes how to integrate chat states notifications into your application.

Here is a list of common Chat State Notifications:

  1. typing: The user is composing a message. The user is actively interacting with a message input interface specific to this chat session (e.g., by typing in the input area of a chat window)
  2. paused: The user had been composing but now has stopped. The user was composing but has not interacted with the message input interface for a short period of time (e.g., 30 seconds)


With QuickBlox you can use all these chat status notifications.

Here is an example of how to implement the typing notification.

int opponentId = 45;
QBPrivateChat privateChat = privateChatManager.getChat(opponentId);
if (privateChat == null) {
    privateChat = privateChatManager.createChat(opponentId, privateChatMessageListener);
}
 
try {
    privateChat.sendIsTypingNotification();
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
}

Also it's possible to send a stop typing notification:

try {
    privateChat.sendStopTypingNotification();
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
}

On the opponent's side we can track this notification and update the UI:

QBIsTypingListener<QBPrivateChat> privateChatIsTypingListener = new QBIsTypingListener<QBPrivateChat>() {
    @Override
    public void processUserIsTyping(QBPrivateChat privateChat) {
 
    }
 
    @Override
    public void processUserStopTyping(QBPrivateChat privateChat) {
 
    }
};
 
privateChat.addIsTypingListener(privateChatIsTypingListener);


Delivered status

SDK automatically manages delivery notifications if you use marked messages.

Term 'marked' relies to messages that have automatic delivery control.

To mark a message as 'markable' use next message property:

QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setMarkable(true);
...

For such messages you will receive delivery confirmation:

// QBMessageListener
 
...
 
@Override
public void processMessageDelivered(QBPrivateChat privateChat, String messageID){
 
}


Read status

You can manage 'read' notifications in chat. For example, User1 sends messages to User2 and User1 would like to know when User2 reads these messages.

First of all, if User1 would like to handle 'read' status of his messages, he should mark message as markable. To mark a message as 'markable' use chatMessage.setMarkable(true) class method to create a message instance.


User1 sends a message:

Integer opponentId = 45;
try {
    QBChatMessage chatMessage = new QBChatMessage();
    chatMessage.setBody("Hi there!");
    chatMessage.setProperty("save_to_history", "1"); // Save a message to history
    chatMessage.setMarkable(true);
 
    QBPrivateChat privateChat = privateChatManager.getChat(opponentId);
    if (privateChat == null) {
        privateChat = privateChatManager.createChat(opponentId, privateChatMessageListener);
    }
    privateChat.sendMessage(chatMessage);
 
    // save packet ID of current message
    String _id = chatMessage.getId();
} catch (XMPPException e) {
 
} catch (SmackException.NotConnectedException e) {
 
}

User2 receives a message, reads it and sends 'read' status back:

// QBMessageListener
 
...
 
@Override
public void processMessage(QBPrivateChat privateChat, final QBChatMessage chatMessage) {
    if(chatMessage.isMarkable()){
        try {
            privateChat.readMessage(chatMessage.getId());
        } catch (XMPPException e) {
 
        } catch (SmackException.NotConnectedException e) {
 
        }
    }
}

User1 receives a 'read' status notification that User2 read his message:

// QBMessageListener
 
...
 
@Override
public void processMessageRead(QBPrivateChat privateChat, String messageID){
    // message was read
}


Message carbons

This feature defines an approach for ensuring that all of user's devices get both sides of all conversations in order to avoid confusion. Information about the current state of a conversation is shared between all of a user's clients that enable this feature.

Is it convenient to enable carbons after chat login:

try {
    QBChatService.getInstance().enableCarbons();
} catch (XMPPException e) {
 
} catch (SmackException e) {
 
}


Comments

Feel free to comment on this page using the form below.

blog comments powered by Disqus