Message overview
Learn about the Android SDK Message model, message lifecycle, and message listener.
The Android SDK represents each message as Message. Message creation, sending, receiving, querying, and state changes are separate stages: creating a Message does not send it, and a successful send does not mean that other clients have already received it.
Use clientMsgID as the client-side deduplication and update key, together with the conversation context that identifies a one-to-one or group chat. Message does not contain conversationID; obtain it from the active conversation, history query, or message event context.
Message processing flow
| Stage | Android API or callback | Description |
|---|---|---|
| Create | MessageManager.create*Message() | Creates a Message object ready to be sent, without writing it to the server or triggering a new-message callback. |
| Send | sendMessage() or sendMessageNotOss() | Pass recvUid for a one-to-one chat or recvGid for a group chat. |
| Receive | OnAdvanceMsgListener | Handles live, offline, online-only, revoked, deleted, and read-receipt changes. |
| Query | History, ID lookup, or search APIs | Queries return the messages read by that request and do not replace real-time message listening. |
| Update | Revoke, delete, modify, pin, read, and local-extension APIs | Handle API results, related events, and any necessary list re-query separately. |
Receive messages is the owning page for message events. Set OnAdvanceMsgListener once in the shared message state layer, then dispatch new, offline, revoked, and deleted message changes to screens. This overview does not register the listener again.
Message fields
The message object returned by creation, sending, receiving, and querying APIs is a Message. Common fields include:
| Field | Type | Description |
|---|---|---|
clientMsgID | String | Client message ID used for list deduplication, state updates, and message lookup. |
serverMsgID | String | Server message ID; it may not have a valid value before a message is sent successfully. |
sessionType | int | Conversation type; use it with recvID and groupID to distinguish one-to-one and group chats. |
sendID | String | Sender user ID. |
recvID | String | Recipient user ID for a one-to-one message. |
groupID | String | Group ID for a group message. |
msgFrom | int | Indicates whether the message is user-level or system-level. |
contentType | int | Message type; use MessageType constants to select the content field. |
createTime | long | Message creation time; the Android model documents this value in nanoseconds. |
sendTime | long | Message send time; the Android model documents this value in milliseconds. |
seq | int | Server message sequence number. |
status | int | Send state; use MessageStatus constants to interpret it. |
isRead | boolean | Read-state snapshot stored on the current client. |
platformID | int | Client platform from which the message was sent. |
senderNickname | String | Snapshot of the sender's nickname. |
senderFaceUrl | String | Snapshot of the sender's avatar URL. |
isReact | boolean | Whether the message carries a reaction marker. |
isExternalExtensions | boolean | Whether the message uses external extensions. |
offlinePush | OfflinePushInfo | Offline-push content. |
attachedInfo | String | SDK attachment information. |
ext | Object | Android message attachment field. |
ex | Object | Message attachment field. |
localEx | Object | Message extension field stored only on the current device. |
The message body is stored in the element field selected by contentType. Do not infer the message type from list position or rendered text:
| Message content | Corresponding field |
|---|---|
| Text and rich text | textElem, advancedTextElem |
| Image, audio, video, and file | pictureElem, soundElem, videoElem, fileElem |
| @ mention and reply | atTextElem, quoteElem |
| Merged forward | mergeElem |
| Contact card, location, and emoji | cardElem, locationElem, faceElem |
| Custom message | customElem |
| Notification, typing, and attached state | notificationElem, typingElem, attachedInfoElem |
Create and send different content types
Sending a message has two steps:
- Call the
create*Message()method for the desired content to obtain a pendingMessage. - Pass that
Messageto Send a message. For a one-to-one chat, setrecvUid; for a group chat, setrecvGid.
The available message types and creation methods are:
| Message content | Creation API |
|---|---|
| Text | Create a text message |
| Rich text | Create an advanced text message |
| @ mention | Create an @ mention message |
| Image | From a platform path, from a full local path, or from an uploaded URL |
| Audio | From a platform path, from a full local path, or from an uploaded URL |
| Video | From a platform path, from a full local path, or from an uploaded URL |
| File | From a platform path, from a full local path, or from an uploaded URL |
| Contact card | Create a contact card message |
| Location | Create a location message |
| Emoji | Create an emoji message |
| Reply | Create a reply message or create an advanced reply message |
| Forward | Create a forwarded message |
| Merged forward | Create a merged-forward message |
| Custom message | Create a custom message |
Choose the send method based on the media source. For a message created from a local path or local file, call sendMessage() so the SDK uploads the media during sending. For a message created from an existing remote URL with create*MessageByURL(), follow Send an uploaded media message to avoid uploading it again.
Find a page by task
| Task | Page |
|---|---|
| Send an ordinary message or already-uploaded media | Send a message, Send an uploaded media message |
| Receive live, offline, and online-only messages | Receive messages, Receive custom business messages |
| Load message history or load it in reverse | Load message history, Load message history in reverse |
| Locate or search messages | Find messages by ID, Search messages |
| Delete, revoke, modify, or pin messages | Delete messages, Revoke a message, Modify a message, Pin a message |
| Manage conversation unread state and group read receipts | Mark a conversation as read, Report group messages as read, Get group message readers |
| Report or retrieve typing status | Update typing status, Get typing status |
| Insert, delete, or extend current-device-only messages | Insert a local one-to-one message, Delete a local message, Set a local message extension |
State synchronization boundaries
| Change | Handling location | Merge strategy |
|---|---|---|
| New and offline messages | Receive messages | Determine the target conversation, then merge by clientMsgID. |
| Message revocation | onRecvMessageRevokedV2 | Update the original message by the ID in the revoke information. |
| Message deletion | onMsgDeleted | Remove the message from the current conversation by ID. |
| C2C and group read receipts | onRecvC2CReadReceipt, onRecvGroupMessageReadReceipt | Update the corresponding message or conversation read state. |
| Message extension changes | onRecvMessageExtensionsChanged and related callbacks | Update extension fields by message ID without replacing the message body. |
| Typing status | Update typing status | Maintain temporary state by conversation and user, outside the ordinary message list. |
For message revocation, deletion, read receipts, and extension changes, handle the API result first, then process the related OnAdvanceMsgListener callbacks. Re-query the message list when necessary.
Was this page helpful?