Skip to main content
The message manager is responsible for CRUD operations on messages, new message listening, refresh message listening, message storage, send message receipt listening, monitoring sync of specific chat data, etc.

Sending Messages

Basic Send Method

/**
 * Send message
 * @param textContent Message content
 * @param channelID Target channel ID
 * @param channelType Target channel type (personal channel, group channel, customer service channel, etc.)
 */
WKIM.getInstance().getMsgManager().sendMessage(textContent, channelID, channelType);
Built-in channel types in SDK can be viewed through WKChannelType

Text Messages

// Define text message
WKTextContent textContent = new WKTextContent("Hello, WuKong");
// Send message
WKIM.getInstance().getMsgManager().send(textContent, channel);

Image Messages

// Define image message
WKImageContent imageContent = new WKImageContent(localPath);
// Send message
WKIM.getInstance().getMsgManager().send(imageContent, channel);
When building image message content, there’s no need to pass image width and height. The SDK will automatically get the image dimensions.

Complete Send Example

public class ChatActivity extends AppCompatActivity {
    
    private String channelID;
    private byte channelType;
    
    // Send text message
    private void sendTextMessage(String content) {
        WKTextContent textContent = new WKTextContent(content);
        WKIM.getInstance().getMsgManager().send(textContent, channelID, channelType);
    }
    
    // Send image message
    private void sendImageMessage(String imagePath) {
        WKImageContent imageContent = new WKImageContent(imagePath);
        WKIM.getInstance().getMsgManager().send(imageContent, channelID, channelType);
    }
    
    // Send voice message
    private void sendVoiceMessage(String voicePath, int duration) {
        WKVoiceContent voiceContent = new WKVoiceContent(voicePath, duration);
        WKIM.getInstance().getMsgManager().send(voiceContent, channelID, channelType);
    }
    
    // Send location message
    private void sendLocationMessage(double latitude, double longitude, String address) {
        WKLocationContent locationContent = new WKLocationContent(latitude, longitude, address);
        WKIM.getInstance().getMsgManager().send(locationContent, channelID, channelType);
    }
}

Custom Messages

See custom messages: Custom Messages

Message Storage Listening

When sending messages, the SDK will trigger a storage callback after saving the message to the local database. At this point, the message has not been sent yet, and you can display the message in the UI in this listener.
WKIM.getInstance().getMsgManager().addOnSendMsgCallback("key", new ISendMsgCallBackListener() {
    @Override
    public void onInsertMsg(WKMsg wkMsg) {
        // You can display the message `wkMsg` saved in the database on the UI here
        runOnUiThread(() -> {
            addMessageToUI(wkMsg);
        });
    }
});
For explanation about whether to pass a unique key for events, see Event Listening

New Message Listening

// Add listener
WKIM.getInstance().getMsgManager().addOnNewMsgListener("key", new INewMsgListener() {
    @Override
    public void newMsg(List<WKMsg> list) {
        // list: received messages
        runOnUiThread(() -> {
            handleNewMessages(list);
        });
    }
});

// Remove listener when exiting page
WKIM.getInstance().getMsgManager().removeNewMsgListener("key");
If you receive new messages in a chat page, you need to determine whether the message belongs to the current conversation by checking the channelID and channelType of the message object WKMsg

New Message Handling Example

public class ChatActivity extends AppCompatActivity {
    
    private List<WKMsg> messageList = new ArrayList<>();
    private MessageAdapter messageAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Add new message listener
        WKIM.getInstance().getMsgManager().addOnNewMsgListener("ChatActivity", new INewMsgListener() {
            @Override
            public void newMsg(List<WKMsg> list) {
                handleNewMessages(list);
            }
        });
    }
    
    private void handleNewMessages(List<WKMsg> newMessages) {
        for (WKMsg msg : newMessages) {
            // Check if message belongs to current conversation
            if (msg.channelID.equals(this.channelID) && msg.channelType == this.channelType) {
                runOnUiThread(() -> {
                    messageList.add(msg);
                    messageAdapter.notifyItemInserted(messageList.size() - 1);
                    
                    // Scroll to latest message
                    recyclerView.scrollToPosition(messageList.size() - 1);
                    
                    // Mark message as read
                    markMessageAsRead(msg);
                });
            }
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Remove listener
        WKIM.getInstance().getMsgManager().removeNewMsgListener("ChatActivity");
    }
}

Message Refresh Listening

When the SDK updates messages, such as: message send status, someone likes a message, message read receipt, message recall, message editing, etc., the SDK will callback the following event. The UI can determine which specific message has changed through the clientMsgNO of the message object WKMsg.
// Add refresh listener
WKIM.getInstance().getMsgManager().addOnRefreshMsgListener("key", new IRefreshMsg() {
    @Override
    public void onRefresh(WKMsg wkMsg, boolean isEnd) {
        // wkMsg: refreshed message object
        // isEnd: to avoid frequent UI refreshes causing lag, refresh UI only when isEnd is true
        if (isEnd) {
            runOnUiThread(() -> {
                refreshMessageInUI(wkMsg);
            });
        }
    }
});

// Remove refresh listener when exiting page
WKIM.getInstance().getMsgManager().removeRefreshMsgListener("key");

Message Refresh Handling Example

private void refreshMessageInUI(WKMsg updatedMsg) {
    // Find corresponding message by clientMsgNO and update
    for (int i = 0; i < messageList.size(); i++) {
        WKMsg msg = messageList.get(i);
        if (msg.clientMsgNO.equals(updatedMsg.clientMsgNO)) {
            messageList.set(i, updatedMsg);
            messageAdapter.notifyItemChanged(i);
            break;
        }
    }
}

Message Send Status Code (ReasonCode)

When a message is sent, you can obtain the WKMsg object by listening for message refresh events. The status (send status) and reasonCode in WKMsg indicate the result of the message delivery.
ValueNameDescription
0ReasonUnknownUnknown error
1ReasonSuccessSuccess
2ReasonAuthFailAuthentication failed
3ReasonSubscriberNotExistSubscriber does not exist in the channel
4ReasonInBlacklistIn blacklist
5ReasonChannelNotExistChannel does not exist
6ReasonUserNotOnNodeUser is not on node
7ReasonSenderOfflineSender is offline, message delivery failed
8ReasonMsgKeyErrorMessage key error, invalid message
9ReasonPayloadDecodeErrorPayload decoding failed
10ReasonForwardSendPacketErrorForwarding send packet failed
11ReasonNotAllowSendNot allowed to send message
12ReasonConnectKickConnection kicked
13ReasonNotInWhitelistNot in whitelist
14ReasonQueryTokenErrorQuery user token error
15ReasonSystemErrorSystem error
16ReasonChannelIDErrorWrong channel ID
17ReasonNodeMatchErrorNode matching error
18ReasonNodeNotMatchNode not matched
19ReasonBanChannel is banned
20ReasonNotSupportHeaderUnsupported header
21ReasonClientKeyIsEmptyclientKey is empty
22ReasonRateLimitRate limit exceeded
23ReasonNotSupportChannelTypeUnsupported channel type
24ReasonDisbandChannel disbanded
25ReasonSendBanSending is banned

View History Messages

/**
 * Query or sync messages for a channel
 *
 * @param channelId                Channel ID
 * @param channelType              Channel type
 * @param oldestOrderSeq           Last message's large orderSeq, pass 0 for first entry into chat
 * @param contain                  Whether to include the oldestOrderSeq message
 * @param dropDown                 Whether it's a dropdown
 * @param aroundMsgOrderSeq        Query messages around this message, e.g. aroundMsgOrderSeq=20 returns [16,17,19,20,21,22,23,24,25]
 * @param limit                    Number to get each time
 * @param iGetOrSyncHistoryMsgBack Request callback
 */
WKIM.getInstance().getMsgManager().getOrSyncHistoryMessages(
    channelId, 
    channelType, 
    oldestOrderSeq, 
    contain, 
    dropDown, 
    limit, 
    aroundMsgOrderSeq, 
    new IGetOrSyncHistoryMsgBack() {
        @Override
        public void onSyncing() {
            // Syncing - show loading as needed
        }

        @Override
        public void onResult(List<WKMsg> list) {
            // Display messages
        }
    }
);
Getting history messages is not a synchronous method, as there may be non-continuous data that needs to be synced from the server

Next Steps