After logging in to Chat, users can send the following types of messages to a peer user, a chat group, or a chat room:
The Chat message feature is language agnostic. End users can send messages in any language, as long as their devices support input in that language.
This page shows how to implement sending and receiving these messages using the Chat SDK.
This section shows how to implement sending and receiving the various types of messages.
Use the ChatMessage
class to create a text message, and send the message.
_7// Call createTextSendMessage to create a text message. Set content as the content of the text message, and toChatUsernames the user ID of the message recipient.
_7ChatMessage message = ChatMessage.createTxtSendMessage(content, toChatUsername);
_7// Set the message type using the MessageType attribute in Message.
_7// You can set `MessageType` as `Chat`, `Group`, or `Room`, which indicates whether to send the message to a peer user, a chat group, or a chat room.
_7message.setChatType(ChatType.GroupChat);
_7 ChatClient.getInstance().chatManager().sendMessage(message);
_13// Calls setMessageStatusCallback to set the callback instance to get the status of messaging sending. You can update the status of messages in this callback, for example, adding a tip when the message sending fails.
_13 message.setMessageStatusCallback(new CallBack() {
_13 public void onSuccess() {
_13 showToast("Message sending succeeds");
_13 public void onError(int code, String error) {
_13 showToast("Message sending fails");
_13 ChatClient.getInstance().chatManager().sendMessage(message);
In high-concurrency scenarios, you can set a certain message type or messages from a chat room member as high, normal, or low priority.
In this case, low-priority messages are dropped first to reserve resources for the high-priority ones, for example, gifts and announcements, when the server is overloaded.
This ensures that the high-priority messages can be dealt with first when loads of messages are being sent in high concurrency or high frequency.
Note that this feature can increase the delivery reliability of high-priority messages, but cannot guarantee the deliveries.
Even high-priorities messages can be dropped when the server load goes too high.
You can set the priority for all types of messages in the chat room.
_5ChatMessage message = ChatMessage.createTextSendMessage(content, toChatUsername);
_5message.setChatType(ChatMessage.ChatType.ChatRoom);
_5// Set the message priority. The default value is `Normal`, indicating the normal priority.
_5message.setPriority(ChatMessage.ChatRoomMessagePriority.PriorityHigh);
You can use MessageListener
to listen for message events. You can add multiple MessageListener
s to listen for multiple events. When you no longer listen for an event, ensure that you remove the listener.
When a message arrives, the recipient receives an onMessgesReceived
callback. Each callback contains one or more messages. You can traverse the message list, and parse and render these messages in this callback.
_8ChatClient.getInstance().chatManager().addMessageListener(msgListener);
_8MessageListener msgListener = new MessageListener() {
_8// Traverse the message list, and parse and render the messages.
_8public void onMessageReceived(List<ChatMessage> messages) {
_8ChatClient.getInstance().chatManager().removeMessageListener(msgListener);
Two minutes after a user sends a message, this user can withdraw it. Contact support@agora.io if you want to adjust the time limit.
_7 ChatClient.getInstance().chatManager().recallMessage(message);
_7 EMLog.d("TAG", "Recalling message succeeds");
_7} catch (ChatException e) {
_7 EMLog.e("TAG", "Recalling message fails: "+e.getDescription());
You can also use onMessageRecalled
to listen for the message recall state:
_4 * Occurs when a received message is recalled.
_4void onMessageRecalled(List<ChatMessage> messages);
Voice, image, video, and file messages are essentially attachment messages. This section introduces how to send these types of messages.
Before sending a voice message, you should implement audio recording on the app level, which provides the URI and duration of the recorded audio file.
Refer to the following code example to create and send a voice message:
_6// Set voiceUri as the local URI of the audio file, and duration as the length of the file in seconds.
_6ChatMessage message = ChatMessage.createVoiceSendMessage(voiceUri, duration, toChatUsername);
_6// Sets the chat type as one-to-one chat, group chat, or chatroom.
_6if (chatType == CHATTYPE_GROUP)
_6 message.setChatType(ChatType.GroupChat);
_6ChatClient.getInstance().chatManager().sendMessage(message);
When the recipient receives the message, refer to the following code example to get the audio file:
_5VoiceMessageBody voiceBody = (VoiceMessageBody) msg.getBody();
_5// Retrieves the URL of the audio file on the server.
_5String voiceRemoteUrl = voiceBody.getRemoteUrl();
_5// Retrieves the URI if the audio file on the local device.
_5Uri voiceLocalUri = voiceBody.getLocalUri();
By default, the SDK compresses the image file before sending it. To send the original file, you can set original
as true
.
Refer to the following code example to create and send an image message:
_6// Set imageUri as the URI of the image file on the local device. false means not to send the original image. The SDK compresses image files that exceeds 100K before sending them.
_6ChatMessage.createImageSendMessage(imageUri, false, toChatUsername);
_6// Sets the chat type as one-to-one chat, group chat, or chatroom.
_6if (chatType == CHATTYPE_GROUP)
_6 message.setChatType(ChatType.GroupChat);
_6ChatClient.getInstance().chatManager().sendMessage(message);
When the recipient receives the message, refer to the following code example to get the thumbnail and attachment file of the image message:
_10// Retrieves the thumbnail and attachment of the image file.
_10ImageMessageBody imgBody = (ImageMessageBody) message.getBody();
_10// Retrieves the image file the server.
_10String imgRemoteUrl = imgBody.getRemoteUrl();
_10// Retrieves the image thumbnail from the server.
_10String thumbnailUrl = imgBody.getThumbnailUrl();
_10// Retrives the URI of the image file on the local device.
_10Uri imgLocalUri = imgBody.getLocalUri();
_10// Retrieves the URI of the image thumbnail on the local device.
_10Uri thumbnailLocalUri = imgBody.thumbnailLocalUri();
If ChatClient.getInstance().getOptions().getAutodownloadThumbnail()
is set as true
on the recipient's client, the SDK automatically downloads the thumbnail after receiving the message. If not, you need to call ChatClient.getInstance().chatManager().downloadThumbnail(message)
to download the thumbnail and get the path from the thumbnailLocalUri
member in messageBody
.
Before sending a video message, you should implement video capturing on the app level, which provides the duration of the captured video file.
Refer to the following code example to create and send a video message:
_3String thumbPath = getThumbPath(videoUri);
_3ChatMessage message = ChatMessage.createVideoSendMessage(videoUri, thumbPath, videoLength, toChatUsername);
By default, when the recipient receives the message, the SDK downloads the thumbnail of the video message.
If you do not want the SDK to automatically download the video thumbnail, set ChatClient.getInstance().getOptions().setAutodownloadThumbnail
as false
, and to download the thumbnail, you need to call ChatClient.getInstance().chatManager().downloadThumbnail(message)
, and get the path of the thumbnail from the thumbnailLocalUri
member in messageBody
.
To download the actual video file, call SChatClient.getInstance().chatManager().downloadAttachment(message)
, and get the path of the video file from the getLocalUri
member in messageBody
.
_44// If you received a message with video attachment, you need download the attachment before you open it.
_44if (message.getType() == ChatMessage.Type.VIDEO) {
_44 VideoMessageBody messageBody = (VideoMessageBody)message.getBody();
_44 // Get the URL of the video on the server.
_44 String videoRemoteUrl = messageBody.getRemoteUrl();
_44 // Download the video.
_44 ChatClient.getInstance().chatManager().downloadAttachment(message);
_44 // Set Callback to know whether the download is finished.
_44 public void onError(final int error, String message) {
_44 EMLog.e(TAG, "offline file transfer error:" + message);
_44 runOnUiThread(new Runnable() {
_44 if (EaseShowBigImageActivity.this.isFinishing() || EaseShowBigImageActivity.this.isDestroyed()) {
_44 image.setImageResource(default_res);
_44 if (error == Error.FILE_NOT_FOUND) {
_44 Toast.makeText(getApplicationContext(), R.string.Image_expired, Toast.LENGTH_SHORT).show();
_44 public void onProgress(final int progress, String status) {
_44 EMLog.d(TAG, "Progress: " + progress);
_44 final String str2 = getResources().getString(R.string.Download_the_pictures_new);
_44 runOnUiThread(new Runnable() {
_44 if (EaseShowBigImageActivity.this.isFinishing() || EaseShowBigImageActivity.this.isDestroyed()) {
_44 pd.setMessage(str2 + progress + "%");
_44 msg.setMessageStatusCallback(callback);
_44 ChatClient.getInstance().chatManager().downloadAttachment(msg);
_44 // After the download finishes, get the URI of the local file.
_44 Uri videoLocalUri = messageBody.getLocalUri();
Refer to the following code example to create, send, and receive a file message:
_4// Set fileLocalUri as the URI of the file message on the local device.
_4ChatMessage message = ChatMessage.createFileSendMessage(fileLocalUri, toChatUsername);
_4// Sets the chat type as one-to-one chat, group chat, or chatroom.
_4if (chatType == CHATTYPE_GROUP) message.setChatType(ChatType.GroupChat);ChatClient.getInstance().chatManager().sendMessage(message);
While sending a file message, refer to the following sample code to get the progress for uploading the attachment file:
_19// Calls setMessageStatusCallback to set the callback instance to listen for the state of messaging sending. You can update the message states in this callback.
_19message.setMessageStatusCallback(new CallBack() {
_19 public void onSuccess() {
_19 showToast("Message sending succeeds");
_19 public void onError(int code, String error) {
_19 showToast("Message sending fails");
_19 // The status of sending the message. This only applies to sending attachment files.
_19 public void onProgress(int progress, String status) {
_19ChatClient.getInstance().chatManager().sendMessage(message);
When the recipient receives the message, refer to the following code example to get the attachment file:
_5NormalFileMessageBody fileMessageBody = (NormalFileMessageBody) message.getBody();
_5// Retrieves the file from the server.
_5String fileRemoteUrl = fileMessageBody.getRemoteUrl();
_5// Retrieves the file from the local device.
_5Uri fileLocalUri = fileMessageBody.getLocalUri();
To send and receive a location message, you need to integrate a third-party map service provider. When sending a location message, you get the longitude and latitude information of the location from the map service provider; when receiving a location message, you extract the received longitude and latitude information and displays the location on the third-party map.
_4// Sets the latitude and longitude information of the address.
_4ChatMessage message = ChatMessage.createLocationSendMessage(latitude, longitude, locationAddress, toChatUsername);
_4// Sets the chat type as one-to-one chat, group chat, or chatroom.
_4if (chatType == CHATTYPE_GROUP) message.setChatType(ChatType.GroupChat);ChatClient.getInstance().chatManager().sendMessage(message);
CMD messages are command messages that instruct a specified user to take a certain action. The recipient deals with the command messages themselves.
- CMD messages are not stored in the local database.
- Actions beginning with
em_
and easemob::
are internal fields. Do not use them.
_7ChatMessage cmdMsg = ChatMessage.createSendMessage(ChatMessage.Type.CMD);
_7// Sets the chat type as one-to-one chat, group chat, or chat room
_7cmdMsg.setChatType(ChatType.GroupChat)String action="action1";
_7// You can customize the action
_7CmdMessageBody cmdBody = new CmdMessageBody(action);String toUsername = "test1";
_7// Specify a username to send the cmd message.
_7cmdMsg.setTo(toUsername);cmdMsg.addBody(cmdBody); ChatClient.getInstance().chatManager().sendMessage(cmdMsg);
To notify the recipient that a CMD message is received, use a seperate delegate so that users can deal with the message differently.
_11MessageListener msgListener = new MessageListener()
_11 // Occurs when the message is received
_11 public void onMessageReceived(List<ChatMessage> messages) {
_11 // Occues when a CMD message is received
_11 public void onCmdMessageReceived(List<ChatMessage> messages) {
Custom messages are self-defined key-value pairs that include the message type and the message content.
The following code example shows how to create and send a customized message:
_9ChatMessage customMessage = ChatMessage.createSendMessage(ChatMessage.Type.CUSTOM);
_9// Set event as the customized message type, for example, gift.
_9event = "gift"CustomMessageBody customBody = new CustomMessageBody(event);
_9// The data type of params is Map<String, String>.
_9customBody.setParams(params);customMessage.addBody(customBody);
_9// Specifies the user ID to receive the message, as Chat ID, chat group ID, or chat room ID.
_9customMessage.setTo(to);
_9// Sets the chat type as one-to-one chat, group chat, or chat room
_9customMessage.setChatType(chatType);ChatClient.getInstance().chatManager().sendMessage(customMessage);
If the message types listed above do not meet your requirements, you can use message extensions to add attributes to the message. This can be applied in more complicated messaging scenarios.
_7ChatMessage message = ChatMessage.createTxtSendMessage(content, toChatUsername);
_7// Adds message attributes.
_7message.setAttribute("attribute1", "value");message.setAttribute("attribute2", true);
_7ChatClient.getInstance().chatManager().sendMessage(message);
_7// Retrieves the message attributes when receiving the message.
_7message.getStringAttribute("attribute1",null);message.getBooleanAttribute("attribute2", false)
After implementing sending and receiving messages, you can refer to the following documents to add more messaging functionalities to your app: