im::floo::floolib::BMXMessage

Message

Inherits from BMXBaseObject

Public Functions

Name
synchronized void delete()
long msgId()
Message unique ID
long clientMsgId()
Message client ID, only exists on message sender-side
long fromId()
Message sender ID
long toId()
Message receiver ID
BMXMessage.MessageType type()
Message type
long conversationId()
Conversation ID that message belongs to
BMXMessage.DeliveryStatus deliveryStatus()
Messaging state
void setDeliveryStatus(BMXMessage.DeliveryStatus arg0)
Set messaging state
long serverTimestamp()
Message timestamp (when received by server-side)
void setServerTimestamp(long arg0)
Set message timestamp (when received by server-side)
long clientTimestamp()
Local timestamp (local time when message created or received)
void setClientTimestamp(long arg0)
Set message local timestamp
boolean isPlayed()
Whether voice or video message has been played, valid only for received audio/video messages
void setIsPlayed(boolean arg0)
boolean isPlayAcked()
Whether voice or video message receives a playback acknowledgement, valid only for received audio/video messages
void setIsPlayAcked(boolean arg0)
boolean isReceiveMsg()
Message whether to receive
void setIsReceiveMsg(boolean arg0)
boolean isRead()
Message read or unread mark
void setIsRead(boolean arg0)
boolean isReadAcked()
Show sender whether read acknowledgement received, and show receiver whether message read acknowledgement sent
void setIsReadAcked(boolean arg0)
boolean isDeliveryAcked()
Show sender whether message has been delivered to the other party, and show receiver whether message delivered acknowledgement has been sent
void setIsDeliveryAcked(boolean arg0)
String content()
Message text content
void setContent(String content)
Message text content
BMXMessage.ContentType contentType()
Message content type, attachment-type with attachment, text-type with no attachment
BMXMessageAttachment attachment()
Message attachment, BMXMessage owns the attachment and is responsible for releasing it
BMXMessageConfig config()
Message settings
void setConfig(BMXMessageConfig arg0)
Set message config information
String extension()
Message extension information
void setExtension(String arg0)
Set message extension information
BMXMessage.DeliveryQos deliveryQos()
QOS of messaging
void setDeliveryQos(BMXMessage.DeliveryQos qos)
Set QOS of messaging
String senderName()
Display name of message sender
void setSenderName(String senderName)
Set display name of message sender
int groupAckCount()
AckCount of read group messages
void setGroupAckCount(int count)
Set groupAckCount of read messages (an SDK internal calling interface that shall not be called by upper layer)
int groupAckUnreadCount()
AckCount of unread group messages
void setGroupAckUnreadCount(int count)
Set groupAckCount of unread messages (an SDK internal calling interface that shall not be called by upper layer)
boolean groupAckReadAll()
Whether all group messages are read
int groupPlayAckCount()
Get count of played group messages
void setGroupPlayAckCount(int count)
int groupPlayAckUnreadCount()
Get count of unread playback acknowledgements of group messages
void setGroupPlayAckUnreadCount(int count)
boolean groupPlayAckReadAll()
Set all playback acknowledgements of group messages as read
void setPriority(int priority)
Set message diffusion priority, default 0. 0 means diffusion, and the smaller the number, the more diffused. Value range 0-10. The default level of messages sent by ordinary users in chatroom is 5, which can be discarded. Admin level defaults to 0 and will not be discarded. Other values can be set according to business.
int priority()
Message diffusion priority
void setPushMessageMode(boolean arg0)
Set whether to push messages
boolean isPushMessage()
Whether it is a push message
BMXMessage createMessage(long from, long to, BMXMessage.MessageType type, long conversationId, String content)
Create a text message
BMXMessage createMessage(long from, long to, BMXMessage.MessageType type, long conversationId, BMXMessageAttachment attachment)
Create a sent-attachment message
BMXMessage createCommandMessage(long from, long to, BMXMessage.MessageType type, long conversationId, String content)
Create a sent command message (command message holds command information in a content field or an extension field)
BMXMessage createMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, String content, long serverTimestamp)
Create a received message
BMXMessage createMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, BMXMessageAttachment attachment, long serverTimestamp)
Create a received message
BMXMessage createCommandMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, String content, long serverTimestamp)
Create a received command message (command message holds command information in a content field or an extension field)
BMXMessage createForwardMessage(BMXMessage msg, long from, long to, BMXMessage.MessageType type, long conversationId)
Create a forwarding message

Protected Functions

Name
BMXMessage(long cPtr, boolean cMemoryOwn)
void finalize()
long getCPtr(BMXMessage obj)

Public Functions Documentation

function delete

inline synchronized void delete()

Example:

function msgId

inline long msgId()

Message unique ID

Return: int64_t

Example:

private long getFirstMessageId() {
    if (mAdapter == null) {
        return -1;
    }
    List<BMXMessage> list = mAdapter.getList();
    BMXMessage bean = null;
    if (list != null && list.size() > 0) {
        bean = list.get(0);
    }
    return bean.msgId();
public final void onCallProgress(BMXMessage msg, int percent) {
    if (msg == null) {
        mainHandler.post(() -> onFail(-1));
        return;
    }
    long msgId = msg.msgId();
    if (percent >= 100) {
        mainHandler.post(() -> onFinish(msgId));
    } else {
        mainHandler.post(() -> onProgress(msgId, percent <= 0 ? 0 : percent));
    }
private void clearTypeWriterMsgId(BMXMessage message){
    if (message.msgId() == ((MaxIMApplication) getApplication()).typeWriterMsgId){
        ((MaxIMApplication) getApplication()).typeWriterMsgId = 0;
    }
public void onProgressCallback(BMXMessage msg, int percent) {
    if (msg == null) {
        return;
    }
    long msgId = msg.msgId();
    if (mListeners.get(msgId) != null) {
        mListeners.get(msgId).onCallProgress(msg, percent);
    }
public void onStartCallback(BMXMessage msg) {
    if (msg == null) {
        return;
    }
    long msgId = msg.msgId();
    if (mListeners.get(msgId) != null) {
        mListeners.get(msgId).onStart(msgId);
    }
public void onFinishCallback(BMXMessage msg) {
    if (msg == null) {
        return;
    }
    long msgId = msg.msgId();
    if (mListeners.get(msgId) != null) {
        mListeners.get(msgId).onCallProgress(msg, 100);
    }
public long getFirstMsgId() {
    BMXMessage firstMessage = getFirstMessage();
    return firstMessage != null ? firstMessage.msgId() : -1;
void updateMessage(BMXMessage bean) {
    BMXMessage preBean;
    for (int i = 0; i < mList.size(); i++) {
        preBean = mList.get(i);
        if (preBean.msgId() == bean.msgId()) {
            update(i, bean);
            break;
        }
    }

function clientMsgId

inline long clientMsgId()

Message client ID, only exists on message sender-side

Return: int64_t

Example:

function fromId

inline long fromId()

Message sender ID

Return: int64_t

Example:

private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    if (mMaxMessage.isReceiveMsg()) {
        BMXRosterItem item = RosterFetcher.getFetcher().getRoster(mMaxMessage.fromId());
        if(group){
            //如果是群  需要获取群成员名称
            BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
            if (item != null && !TextUtils.isEmpty(item.alias())) {
                userName = item.alias();
            } else if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
                userName = member.getMGroupNickname();
            } else if (item != null && !TextUtils.isEmpty(item.nickname())) {
                userName = item.nickname();
            } else if (item != null) {
                userName = item.username();
private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    if (mMaxMessage.isReceiveMsg()) {
        BMXRosterItem item = RosterFetcher.getFetcher().getRoster(mMaxMessage.fromId());
        if(group){
            //如果是群  需要获取群成员名称
            BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
            if (item != null && !TextUtils.isEmpty(item.alias())) {
                userName = item.alias();
            } else if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
                userName = member.getMGroupNickname();
            } else if (item != null && !TextUtils.isEmpty(item.nickname())) {
                userName = item.nickname();
            } else if (item != null) {
                userName = item.username();
            userName = item.username();
        }
    }
    if (mIconView != null) {
        ChatUtils.getInstance().showRosterAvatar(item, mIconView, ICON_CONFIG);
    }
} else {
    BMXUserProfile profile = RosterFetcher.getFetcher().getProfile();
    if (group) {
        //如果是群  需要获取群成员名称
        BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
        if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
            userName = member.getMGroupNickname();
        } else if (profile != null && !TextUtils.isEmpty(profile.nickname())) {
            userName = profile.nickname();
        } else if (profile != null) {
            userName = profile.username();
        }
    } else {
        if (profile != null && !TextUtils.isEmpty(profile.nickname())) {
RosterDetailActivity.openRosterDetail(mContext, mMaxMessage.fromId());
    protected boolean filterMessage(BMXMessage message) {
        if (message == null) {
            return false;
        }
        if (message.contentType() == BMXMessage.ContentType.Text
                && !TextUtils.isEmpty(message.extension())) {
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(message.extension());
                if (jsonObject.has(MessageConfig.INPUT_STATUS) && message.fromId() != mMyUserId) {
                    handelInputStatus(message.extension());
                }
                //TODO
//                if (jsonObject.has("rtcKey") && jsonObject.has("rtcValue")) {
//                    if (TextUtils.equals(jsonObject.getString("rtcKey"), "join") && !TextUtils.isEmpty(jsonObject.getString("rtcValue"))) {
//                        String[] values = jsonObject.getString("rtcValue").split("_");
//                        String roomId = values[0];
//                        String[] chatIdArray = values[1].split(",");
//                        boolean hasVideo = TextUtils.equals(MessageConfig.CallMode.CALL_VIDEO+"", values[2]);
//                        List<Long> chatIds = new ArrayList<>();
@Override
protected boolean isCurrentSession(BMXMessage message) {
    if (message == null || message.type() != BMXMessage.MessageType.Single) {
        return false;
    }
    if (message.isReceiveMsg()) {
        // 对方发过来的消息
        return message.fromId() == mChatId;
    }
    return message.toId() == mChatId;
private void notifyMessage(List<BMXMessage> messages) {
    if (messages == null || messages.isEmpty()) {
        return;
    }
    ListOfLongLong rosterIds = new ListOfLongLong();
    for (int i = 0; i < messages.size(); i++) {
        BMXMessage message = messages.get(i);
        if (message == null) {
            continue;
        }
        rosterIds.add(message.fromId());
    }
    if (!rosterIds.isEmpty()) {
        RosterManager.getInstance().getRosterList(rosterIds, true, (bmxErrorCode, itemList) -> {
            RosterFetcher.getFetcher().putRosters(itemList);
            if (BaseManager.bmxFinish(bmxErrorCode)) {
                if (mAdapter != null) {
                    mAdapter.notifyDataSetChanged();
                }
protected void onBindHolder(BaseViewHolder holder, int position) {
    ShapeImageView avatar = holder.findViewById(R.id.session_avatar);
    TextView tvTitle = holder.findViewById(R.id.session_title);
    TextView desc = holder.findViewById(R.id.session_desc);
    TextView time = holder.findViewById(R.id.session_time);
    BMXMessage message = getItem(position);
    if (message == null) {
        return;
    }
    String name = "";
    BMXRosterItem rosterItem = RosterFetcher.getFetcher().getRoster(message.fromId());
    if (rosterItem != null && !TextUtils.isEmpty(rosterItem.nickname())) {
        name = rosterItem.nickname();
    } else if (rosterItem != null) {
        name = rosterItem.username();
    }
    ChatUtils.getInstance().showRosterAvatar(rosterItem, avatar, mConfig);
    tvTitle.setText(TextUtils.isEmpty(name) ? "" : name);
    time.setText(TimeUtils.millis2String(mContext, message.serverTimestamp()));
    String msgDesc = ChatUtils.getInstance().getMessageDesc(mContext, message);

function toId

inline long toId()

Message receiver ID

Return: int64_t

Example:

@Override
protected boolean isCurrentSession(BMXMessage message) {
    return message != null && message.type() == BMXMessage.MessageType.Group
            && message.toId() == mChatId;
@Override
protected boolean isCurrentSession(BMXMessage message) {
    if (message == null || message.type() != BMXMessage.MessageType.Single) {
        return false;
    }
    if (message.isReceiveMsg()) {
        // 对方发过来的消息
        return message.fromId() == mChatId;
    }
    return message.toId() == mChatId;
private void notifyNotification(BMXMessage bean) {
    if (bean == null || !bean.isReceiveMsg()) {
        return;
    }
    Context context = AppContextUtils.getAppContext();
    Intent intent = new Intent(String.format(context.getString(R.string.im_push_msg_action),
            context.getPackageName()));
    if (bean.type() == BMXMessage.MessageType.Group) {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.toId()));
    } else {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.fromId()));
    }
    intent.setPackage(context.getPackageName());
    context.sendBroadcast(intent);

function type

inline BMXMessage.MessageType type()

Message type

Return: [MessageType]

Example:

private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    if (mMaxMessage.isReceiveMsg()) {
        BMXRosterItem item = RosterFetcher.getFetcher().getRoster(mMaxMessage.fromId());
        if(group){
            //如果是群  需要获取群成员名称
            BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
            if (item != null && !TextUtils.isEmpty(item.alias())) {
                userName = item.alias();
            } else if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
                userName = member.getMGroupNickname();
            } else if (item != null && !TextUtils.isEmpty(item.nickname())) {
                userName = item.nickname();
            } else if (item != null) {
                userName = item.username();
private void showReadStatus() {
    if (mItemPos != ITEM_RIGHT || mTvReadStatus == null) {
        return;
    }
    if (mMaxMessage == null) {
        mTvReadStatus.setVisibility(View.GONE);
        return;
    }
    if (mMaxMessage.type() == BMXMessage.MessageType.Single) {
        // 单聊
        mTvReadStatus.setVisibility(View.VISIBLE);
        boolean isRead = mMaxMessage.isReadAcked();
        mTvReadStatus.setText(isRead ? getResources().getString(R.string.read) : getResources().getString(R.string.unread));
    } else if (mMaxMessage.type() == BMXMessage.MessageType.Group) {
        // 群聊
        mTvReadStatus.setVisibility(mShowReadAck ? View.VISIBLE : View.GONE);
        int readCount = mMaxMessage.groupAckCount();
        mTvReadStatus.setText(getResources().getString(R.string.read_persons) + (readCount > 0 ? readCount : 0));
    } else {
        mTvReadStatus.setVisibility(View.GONE);
}
if (mMaxMessage == null) {
    mTvReadStatus.setVisibility(View.GONE);
    return;
}
if (mMaxMessage.type() == BMXMessage.MessageType.Single) {
    // 单聊
    mTvReadStatus.setVisibility(View.VISIBLE);
    boolean isRead = mMaxMessage.isReadAcked();
    mTvReadStatus.setText(isRead ? getResources().getString(R.string.read) : getResources().getString(R.string.unread));
} else if (mMaxMessage.type() == BMXMessage.MessageType.Group) {
    // 群聊
    mTvReadStatus.setVisibility(mShowReadAck ? View.VISIBLE : View.GONE);
    int readCount = mMaxMessage.groupAckCount();
    mTvReadStatus.setText(getResources().getString(R.string.read_persons) + (readCount > 0 ? readCount : 0));
} else {
    mTvReadStatus.setVisibility(View.GONE);
}
mTvReadStatus.setOnClickListener((v) -> {
    if (!mShowReadAck || mActionListener == null) {
@Override
protected boolean isCurrentSession(BMXMessage message) {
    return message != null && message.type() == BMXMessage.MessageType.Group
            && message.toId() == mChatId;
@Override
protected boolean isCurrentSession(BMXMessage message) {
    if (message == null || message.type() != BMXMessage.MessageType.Single) {
        return false;
    }
    if (message.isReceiveMsg()) {
        // 对方发过来的消息
        return message.fromId() == mChatId;
    }
    return message.toId() == mChatId;
private void notifyNotification(BMXMessage bean) {
    if (bean == null || !bean.isReceiveMsg()) {
        return;
    }
    Context context = AppContextUtils.getAppContext();
    Intent intent = new Intent(String.format(context.getString(R.string.im_push_msg_action),
            context.getPackageName()));
    if (bean.type() == BMXMessage.MessageType.Group) {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.toId()));
    } else {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.fromId()));
    }
    intent.setPackage(context.getPackageName());
    context.sendBroadcast(intent);
private void notifyNotification(BMXMessage bean) {
    if (bean == null || !bean.isReceiveMsg()) {
        return;
    }
    Context context = AppContextUtils.getAppContext();
    Intent intent = new Intent(String.format(context.getString(R.string.im_push_msg_action),
            context.getPackageName()));
    if (bean.type() == BMXMessage.MessageType.Group) {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.toId()));
    } else {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.fromId()));
    }
    intent.setPackage(context.getPackageName());
    context.sendBroadcast(intent);
private void notifyNotification(BMXMessage bean) {
    if (bean == null || !bean.isReceiveMsg()) {
        return;
    }
    Context context = AppContextUtils.getAppContext();
    Intent intent = new Intent(String.format(context.getString(R.string.im_push_msg_action),
            context.getPackageName()));
    if (bean.type() == BMXMessage.MessageType.Group) {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.toId()));
    } else {
        intent.putExtra(MessageConfig.CHAT_MSG,
                ChatUtils.getInstance().buildMessage(bean, bean.type(), bean.fromId()));
    }
    intent.setPackage(context.getPackageName());
    context.sendBroadcast(intent);

function conversationId

inline long conversationId()

Conversation ID that message belongs to

Return: int64_t

Example:

private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    if (mMaxMessage.isReceiveMsg()) {
        BMXRosterItem item = RosterFetcher.getFetcher().getRoster(mMaxMessage.fromId());
        if(group){
            //如果是群  需要获取群成员名称
            BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
            if (item != null && !TextUtils.isEmpty(item.alias())) {
                userName = item.alias();
            } else if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
                userName = member.getMGroupNickname();
            } else if (item != null && !TextUtils.isEmpty(item.nickname())) {
                userName = item.nickname();
            } else if (item != null) {
                userName = item.username();
            userName = item.username();
        }
    }
    if (mIconView != null) {
        ChatUtils.getInstance().showRosterAvatar(item, mIconView, ICON_CONFIG);
    }
} else {
    BMXUserProfile profile = RosterFetcher.getFetcher().getProfile();
    if (group) {
        //如果是群  需要获取群成员名称
        BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
        if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
            userName = member.getMGroupNickname();
        } else if (profile != null && !TextUtils.isEmpty(profile.nickname())) {
            userName = profile.nickname();
        } else if (profile != null) {
            userName = profile.username();
        }
    } else {
        if (profile != null && !TextUtils.isEmpty(profile.nickname())) {

function deliveryStatus

inline BMXMessage.DeliveryStatus deliveryStatus()

Messaging state

Return: [DeliveryStatus]

Example:

private void showSendStatus() {
    if (mItemPos != ITEM_RIGHT || mSendFailImg == null || mSendingImg == null) {
        return;
    }
    BMXMessage.DeliveryStatus sendStatus = mMaxMessage == null ? null
            : mMaxMessage.deliveryStatus();
    // 消息发送状态是否失败
    if (sendStatus == null || sendStatus == BMXMessage.DeliveryStatus.Deliveried) {
        // 空和成功都展示成功
        mSendFailImg.setVisibility(View.GONE);
        mSendingImg.setVisibility(View.GONE);
    } else if (sendStatus == BMXMessage.DeliveryStatus.Failed) {
        // 失败
        mSendFailImg.setVisibility(View.VISIBLE);
        mSendingImg.setVisibility(View.GONE);
    } else {
        mSendFailImg.setVisibility(View.GONE);
        mSendingImg.setVisibility(View.VISIBLE);
    }
    dialog.dismiss();
    ForwardMsgRosterActivity.openForwardMsgRosterActivity((Activity)mView.getContext(),
            ChatUtils.getInstance().buildMessage(message, mChatType, mChatId),
            FORWARD_REQUEST);
});
ll.addView(relay, params);

// 自己发送的消息才有撤回
if (!message.isReceiveMsg()) {
    // 撤回
    BMXMessage.DeliveryStatus sendStatus = message.deliveryStatus();
    // 发送成功才有撤回
    if (sendStatus == null || sendStatus == BMXMessage.DeliveryStatus.Deliveried) {
        TextView revoke = new TextView(mView.getContext());
        revoke.setPadding(ScreenUtils.dp2px(15), ScreenUtils.dp2px(15),
                ScreenUtils.dp2px(15), 0);
        revoke.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
        revoke.setTextColor(
                mView.getContext().getResources().getColor(R.color.color_black));
        revoke.setBackgroundColor(

function setDeliveryStatus

inline void setDeliveryStatus(
    BMXMessage.DeliveryStatus arg0
)

Set messaging state

Example:

function serverTimestamp

inline long serverTimestamp()

Message timestamp (when received by server-side)

Return: int64_t

Example:

private boolean isShowTime(int position) {
    // 聊天消息时间戳为毫秒级 目前为10分钟间隔 也就是10 * 60 * 1000
    long timeOut = 10 * 60 * 1000;
    BMXMessage current = mBeans.get(position);
    boolean showtime = true;
    if (position > 0) {
        BMXMessage pre = mBeans.get(position - 1);
        if (current.serverTimestamp() == 0 || pre.serverTimestamp() == 0) {
            showtime = false;
        } else {
            long time_cha = 0;
            try {
                time_cha = (current.serverTimestamp() - pre.serverTimestamp()) / timeOut;
            } catch (Exception e) {
                e.printStackTrace();
            }
            showtime = time_cha >= 1;
        }
    }
    return showtime;
long timeOut = 10 * 60 * 1000;
BMXMessage current = mBeans.get(position);
boolean showtime = true;
if (position > 0) {
    BMXMessage pre = mBeans.get(position - 1);
    if (current.serverTimestamp() == 0 || pre.serverTimestamp() == 0) {
        showtime = false;
    } else {
        long time_cha = 0;
        try {
            time_cha = (current.serverTimestamp() - pre.serverTimestamp()) / timeOut;
        } catch (Exception e) {
            e.printStackTrace();
        }
        showtime = time_cha >= 1;
    }
}
return showtime;
} else {
    ivDisturb.setVisibility(View.GONE);
    if (unReadCount > 0) {
        tvUnReadCount.setVisibility(View.VISIBLE);
        tvUnReadCount.setText(String.valueOf(unReadCount));
    } else {
        tvUnReadCount.setVisibility(View.GONE);
    }
}
tvTitle.setText(TextUtils.isEmpty(name) ? "" : name);
time.setText(lastMsg != null ? TimeUtils.millis2StringOnConversationList(mContext, lastMsg.serverTimestamp()) : "");
String draft = item == null ? "" : item.editMessage();
if (!TextUtils.isEmpty(draft)) {
    // 有草稿
    SpannableStringBuilder spannable = new SpannableStringBuilder();
    String draftText = mContext.getString(R.string.draft);
    SpannableString spannableString = new SpannableString(draftText);
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, draftText.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.append(spannableString).append(draft);
@Override
public void bindData(BMXMessage maXMessage) {
    mMaxMessage = maXMessage;
    mTxtMessageTime.setText(TimeUtils.millis2StringOnMessageList(mContext, maXMessage.serverTimestamp()));
    showHead();
    bindData();
    showReadStatus();
    showSendStatus();
}
String name = "";
BMXRosterItem rosterItem = RosterFetcher.getFetcher().getRoster(message.fromId());
if (rosterItem != null && !TextUtils.isEmpty(rosterItem.nickname())) {
    name = rosterItem.nickname();
} else if (rosterItem != null) {
    name = rosterItem.username();
}
ChatUtils.getInstance().showRosterAvatar(rosterItem, avatar, mConfig);
tvTitle.setText(TextUtils.isEmpty(name) ? "" : name);
time.setText(TimeUtils.millis2String(mContext, message.serverTimestamp()));
String msgDesc = ChatUtils.getInstance().getMessageDesc(mContext, message);
desc.setText(!TextUtils.isEmpty(msgDesc) ? msgDesc : "");
long o1Time = m1 == null ? -1 : m1.serverTimestamp();

function setServerTimestamp

inline void setServerTimestamp(
    long arg0
)

Set message timestamp (when received by server-side)

Example:

function clientTimestamp

inline long clientTimestamp()

Local timestamp (local time when message created or received)

Return: int64_t

Example:

function setClientTimestamp

inline void setClientTimestamp(
    long arg0
)

Set message local timestamp

Example:

function isPlayed

inline boolean isPlayed()

Whether voice or video message has been played, valid only for received audio/video messages

Return: bool

Example:

function setIsPlayed

inline void setIsPlayed(
    boolean arg0
)

Example:

function isPlayAcked

inline boolean isPlayAcked()

Whether voice or video message receives a playback acknowledgement, valid only for received audio/video messages

Return: bool

Example:

function setIsPlayAcked

inline void setIsPlayAcked(
    boolean arg0
)

Example:

function isReceiveMsg

inline boolean isReceiveMsg()

Message whether to receive

Return: bool

Example:

private int getChatItemType(BMXMessage bean) {
    if (bean == null) {
        return -1;
    }
    boolean isMySend = !bean.isReceiveMsg();
    int viewType = MsgBodyHelper.getContentBodyClass(bean.contentType().swigValue()) != null
            ? bean.contentType().swigValue()
            : -1;
    return isMySend ? viewType : ~viewType;
    // 有草稿
    SpannableStringBuilder spannable = new SpannableStringBuilder();
    String draftText = mContext.getString(R.string.draft);
    SpannableString spannableString = new SpannableString(draftText);
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, draftText.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.append(spannableString).append(draft);
    desc.setText(spannable);
} else {
    String msgDesc = ChatUtils.getInstance().getMessageDesc(mContext, lastMsg);
    if (lastMsg != null && lastMsg.isReceiveMsg() && lastMsg.config() != null) {
        // 有@
        try {
            BMXMessageConfig config = lastMsg.config();
            if (config.getMentionAll()) {
                msgDesc = mContext.getString(R.string.someone_at_you) + msgDesc;
            } else {
                ListOfLongLong atList = config.getMentionList();
                if (atList != null && !atList.isEmpty()) {
                    for (int i = 0; i < atList.size(); i++) {
private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    if (mMaxMessage.isReceiveMsg()) {
        BMXRosterItem item = RosterFetcher.getFetcher().getRoster(mMaxMessage.fromId());
        if(group){
            //如果是群  需要获取群成员名称
            BMXGroup.Member member = GroupManager.getInstance().getMemberByDB(mMaxMessage.conversationId(), mMaxMessage.fromId());
            if (item != null && !TextUtils.isEmpty(item.alias())) {
                userName = item.alias();
            } else if (member != null && !TextUtils.isEmpty(member.getMGroupNickname())) {
                userName = member.getMGroupNickname();
            } else if (item != null && !TextUtils.isEmpty(item.nickname())) {
                userName = item.nickname();
            } else if (item != null) {
                userName = item.username();
if (mMaxMessage.isReceiveMsg()) {
relay.setText(mView.getContext().getString(R.string.chat_msg_relay));
relay.setOnClickListener(v -> {
    dialog.dismiss();
    ForwardMsgRosterActivity.openForwardMsgRosterActivity((Activity)mView.getContext(),
            ChatUtils.getInstance().buildMessage(message, mChatType, mChatId),
            FORWARD_REQUEST);
});
ll.addView(relay, params);

// 自己发送的消息才有撤回
if (!message.isReceiveMsg()) {
    // 撤回
    BMXMessage.DeliveryStatus sendStatus = message.deliveryStatus();
    // 发送成功才有撤回
    if (sendStatus == null || sendStatus == BMXMessage.DeliveryStatus.Deliveried) {
        TextView revoke = new TextView(mView.getContext());
        revoke.setPadding(ScreenUtils.dp2px(15), ScreenUtils.dp2px(15),
                ScreenUtils.dp2px(15), 0);
        revoke.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
        revoke.setTextColor(
                mView.getContext().getResources().getColor(R.color.color_white));
        revoke.setText(mView.getContext().getString(R.string.chat_msg_revoke));
        revoke.setOnClickListener(v -> {
            dialog.dismiss();
            revokeMessage(message);
        });
        ll.addView(revoke, params);
    }
}
// 对方发送的消息才有标记已读
if (message.isReceiveMsg()) {
    // 标记已读
    TextView ackRead = new TextView(mView.getContext());
    ackRead.setPadding(ScreenUtils.dp2px(15), ScreenUtils.dp2px(15), ScreenUtils.dp2px(15),
            0);
    ackRead.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
    ackRead.setTextColor(mView.getContext().getResources().getColor(R.color.color_black));
    ackRead.setBackgroundColor(
            mView.getContext().getResources().getColor(R.color.color_white));
    ackRead.setText(mView.getContext().getString(R.string.chat_msg_ack));
protected void ackMessage(final BMXMessage message) {
    // 已读不在发送 自己发送的消息不设置已读
    if (message == null || message.isReadAcked() || !message.isReceiveMsg()) {
        return;
    }
    Observable.just(message).map(new Func1<BMXMessage, BMXMessage>() {
        @Override
        public BMXMessage call(BMXMessage message) {
            ChatManager.getInstance().ackMessage(message);
            return message;
        }
    }).subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<BMXMessage>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
@Override
protected boolean isCurrentSession(BMXMessage message) {
    if (message == null || message.type() != BMXMessage.MessageType.Single) {
        return false;
    }
    if (message.isReceiveMsg()) {
        // 对方发过来的消息
        return message.fromId() == mChatId;
    }
    return message.toId() == mChatId;

function setIsReceiveMsg

inline void setIsReceiveMsg(
    boolean arg0
)

Example:

function isRead

inline boolean isRead()

Message read or unread mark

Return: bool

Example:

function setIsRead

inline void setIsRead(
    boolean arg0
)

Example:

function isReadAcked

inline boolean isReadAcked()

Show sender whether read acknowledgement received, and show receiver whether message read acknowledgement sent

Return: bool

Example:

if (mItemPos != ITEM_RIGHT || mTvReadStatus == null) {
    return;
}
if (mMaxMessage == null) {
    mTvReadStatus.setVisibility(View.GONE);
    return;
}
if (mMaxMessage.type() == BMXMessage.MessageType.Single) {
    // 单聊
    mTvReadStatus.setVisibility(View.VISIBLE);
    boolean isRead = mMaxMessage.isReadAcked();
    mTvReadStatus.setText(isRead ? getResources().getString(R.string.read) : getResources().getString(R.string.unread));
} else if (mMaxMessage.type() == BMXMessage.MessageType.Group) {
    // 群聊
    mTvReadStatus.setVisibility(mShowReadAck ? View.VISIBLE : View.GONE);
    int readCount = mMaxMessage.groupAckCount();
    mTvReadStatus.setText(getResources().getString(R.string.read_persons) + (readCount > 0 ? readCount : 0));
} else {
    mTvReadStatus.setVisibility(View.GONE);
protected void ackMessage(final BMXMessage message) {
    // 已读不在发送 自己发送的消息不设置已读
    if (message == null || message.isReadAcked() || !message.isReceiveMsg()) {
        return;
    }
    Observable.just(message).map(new Func1<BMXMessage, BMXMessage>() {
        @Override
        public BMXMessage call(BMXMessage message) {
            ChatManager.getInstance().ackMessage(message);
            return message;
        }
    }).subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<BMXMessage>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

function setIsReadAcked

inline void setIsReadAcked(
    boolean arg0
)

Example:

function isDeliveryAcked

inline boolean isDeliveryAcked()

Show sender whether message has been delivered to the other party, and show receiver whether message delivered acknowledgement has been sent

Return: bool

Example:

function setIsDeliveryAcked

inline void setIsDeliveryAcked(
    boolean arg0
)

Example:

function content

inline String content()

Message text content

Return: std::string

Example:

@Override
protected void onBindHolder(BaseViewHolder holder, int position) {
    TextView tv = holder.findViewById(R.id.tv_push_msg);
    BMXMessage message = getItem(position);
    String content = message == null ? "" : message.content();
    tv.setText(content);
private void copyMessage(BMXMessage message) {
    if (message == null || message.contentType() != BMXMessage.ContentType.Text) {
        return;
    }
    ClipboardManager clipboard = (ClipboardManager)mView.getContext()
            .getSystemService(Context.CLIPBOARD_SERVICE);
    if (clipboard == null) {
        return;
    }
    String text = message.content();
    if (TextUtils.isEmpty(text)) {
        return;
    }
    ClipData clip = ClipData.newPlainText("chat_text", text);
    clipboard.setPrimaryClip(clip);
    ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.copy_successful));
public String getMessageDesc(Context context, BMXMessage message) {
    if (message == null) {
        return "";
    }
    BMXMessage.ContentType type = message.contentType();
    String content = message.content();
    return getMessageDesc(context, type, content, message.isReceiveMsg(), message);
if (mBmxMessage == null) {
    return null;
}
MessageBean messageBean = new MessageBean();
BMXMessage.ContentType contentType = mBmxMessage.contentType();
messageBean.setContentType(contentType);
messageBean.setType(type);
messageBean.setChatId(chatId);
messageBean.setReceiveMsg(mBmxMessage.isReceiveMsg());
if (contentType == BMXMessage.ContentType.Text) {
    String text = mBmxMessage.content();
    if (!TextUtils.isEmpty(text)) {
        messageBean.setContent(text);
        return messageBean;
    }
    return null;
}
if (contentType == BMXMessage.ContentType.Image) {
    // 图片
    BMXImageAttachment body = BMXImageAttachment.dynamic_cast(mBmxMessage.attachment());

function setContent

inline void setContent(
    String content
)

Message text content

Parameters:

  • content Message text content

Example:

function contentType

inline BMXMessage.ContentType contentType()

Message content type, attachment-type with attachment, text-type with no attachment

Return: [ContentType]

Example:

private int getChatItemType(BMXMessage bean) {
    if (bean == null) {
        return -1;
    }
    boolean isMySend = !bean.isReceiveMsg();
    int viewType = MsgBodyHelper.getContentBodyClass(bean.contentType().swigValue()) != null
            ? bean.contentType().swigValue()
            : -1;
    return isMySend ? viewType : ~viewType;
private int getChatItemType(BMXMessage bean) {
    if (bean == null) {
        return -1;
    }
    boolean isMySend = !bean.isReceiveMsg();
    int viewType = MsgBodyHelper.getContentBodyClass(bean.contentType().swigValue()) != null
            ? bean.contentType().swigValue()
            : -1;
    return isMySend ? viewType : ~viewType;
@Override
public void onItemFunc(BMXMessage bean) {
    if (bean == null) {
        return;
    }
    BMXMessage.ContentType contentType = bean.contentType();
    if (contentType == BMXMessage.ContentType.Text) {
        // TODO
    } else if (contentType == BMXMessage.ContentType.Image) {
        // 图片
        onImageItemClick(bean);
    } else if (contentType == BMXMessage.ContentType.Voice) {
        // 语音播放
        onAudioItemClick(bean);
    } else if (contentType == BMXMessage.ContentType.File) {
        // 文件查看
        onFileItemClick(bean);
    } else if (contentType == BMXMessage.ContentType.Video) {
        // 视频
        openVideoItemClick(bean);
delete.setBackgroundColor(mView.getContext().getResources().getColor(R.color.color_white));
delete.setText(mView.getContext().getString(R.string.delete));
delete.setOnClickListener(v -> {
    dialog.dismiss();
    deleteMessage(message);
});
ll.addView(delete, params);

// 复制 文字才有
// 自己发送的消息才有撤回
if (message.contentType() == BMXMessage.ContentType.Text) {
    // 撤回
    TextView copy = new TextView(mView.getContext());
    copy.setPadding(ScreenUtils.dp2px(15), ScreenUtils.dp2px(15), ScreenUtils.dp2px(15), 0);
    copy.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
    copy.setTextColor(mView.getContext().getResources().getColor(R.color.color_black));
    copy.setBackgroundColor(
            mView.getContext().getResources().getColor(R.color.color_white));
    copy.setText(mView.getContext().getString(R.string.chat_msg_copy));
    copy.setOnClickListener(v -> {
private void copyMessage(BMXMessage message) {
    if (message == null || message.contentType() != BMXMessage.ContentType.Text) {
        return;
    }
    ClipboardManager clipboard = (ClipboardManager)mView.getContext()
            .getSystemService(Context.CLIPBOARD_SERVICE);
    if (clipboard == null) {
        return;
    }
    String text = message.content();
    if (TextUtils.isEmpty(text)) {
        return;
    }
    ClipData clip = ClipData.newPlainText("chat_text", text);
    clipboard.setPrimaryClip(clip);
    ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.copy_successful));
private void onAudioItemClick(final BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.Voice) {
        return;
    }
    ackMessage(bean);
    final BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    if (mVoicePlayHelper == null) {
        mVoicePlayHelper = new VoicePlayHelper((Activity)mView.getContext());
        registerSensor();
    }
    if (mVoicePlayHelper.isPlaying()) {
        stopVoicePlay();
        return;
    }
    if (TextUtils.isEmpty(body.path())) {
        Log.i(TAG, "http voiceUrl is null");
private void playVoice(String voicePath, final BMXMessage bean) {
    if (mView == null || TextUtils.isEmpty(voicePath) || bean == null
            || bean.contentType() != BMXMessage.ContentType.Voice || mVoicePlayHelper == null) {
        return;
    }
    BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    mVoicePlayHelper.setOnVoiceFinishListener(new VoicePlayHelper.OnVoiceFinishListener() {
        @Override
        public void onFinish() {
            if (mView == null) {
                return;
            }
            VoicePlayManager.getInstance().onFinishCallback(bean);
            // mView.getVoiceMessageMsgId(chatBean.getMsgId());
        }

        @Override
private void onFileItemClick(BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.File) {
        return;
    }
    final BMXFileAttachment body = BMXFileAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    String filePath = null;
    if (!TextUtils.isEmpty(body.path()) && new File(body.path()).exists()) {
        filePath = body.path();
    } else {
        Log.i(TAG, "local path is null");
    }
    if (!TextUtils.isEmpty(filePath)) {
        openFilePreView(filePath);
        return;
    }
    ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.downloading));
    BMXMessageAttachment.DownloadStatus status = body.downloadStatus();

function attachment

inline BMXMessageAttachment attachment()

Message attachment, BMXMessage owns the attachment and is responsible for releasing it

Return: BMXMessageAttachmentPtr

Example:

private void onAudioItemClick(final BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.Voice) {
        return;
    }
    ackMessage(bean);
    final BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    if (mVoicePlayHelper == null) {
        mVoicePlayHelper = new VoicePlayHelper((Activity)mView.getContext());
        registerSensor();
    }
    if (mVoicePlayHelper.isPlaying()) {
        stopVoicePlay();
        return;
    }
    if (TextUtils.isEmpty(body.path())) {
        Log.i(TAG, "http voiceUrl is null");
private void playVoice(String voicePath, final BMXMessage bean) {
    if (mView == null || TextUtils.isEmpty(voicePath) || bean == null
            || bean.contentType() != BMXMessage.ContentType.Voice || mVoicePlayHelper == null) {
        return;
    }
    BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    mVoicePlayHelper.setOnVoiceFinishListener(new VoicePlayHelper.OnVoiceFinishListener() {
        @Override
        public void onFinish() {
            if (mView == null) {
                return;
            }
            VoicePlayManager.getInstance().onFinishCallback(bean);
            // mView.getVoiceMessageMsgId(chatBean.getMsgId());
        }

        @Override
private void onFileItemClick(BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.File) {
        return;
    }
    final BMXFileAttachment body = BMXFileAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    String filePath = null;
    if (!TextUtils.isEmpty(body.path()) && new File(body.path()).exists()) {
        filePath = body.path();
    } else {
        Log.i(TAG, "local path is null");
    }
    if (!TextUtils.isEmpty(filePath)) {
        openFilePreView(filePath);
        return;
    }
    ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.downloading));
    BMXMessageAttachment.DownloadStatus status = body.downloadStatus();
private void onImageItemClick(final BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.Image) {
        return;
    }
    BMXImageAttachment body = BMXImageAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    String picUrl = null;
    if (!TextUtils.isEmpty(body.thumbnailPath()) && new File(body.thumbnailPath()).exists()) {
        picUrl = body.thumbnailPath();
    } else if (!TextUtils.isEmpty(body.path()) && new File(body.path()).exists()) {
        picUrl = body.path();
    } else if (!TextUtils.isEmpty(body.thumbnailUrl())) {
        picUrl = body.thumbnailUrl();
    } else if (!TextUtils.isEmpty(body.url())) {
        picUrl = body.url();
    }
    if (TextUtils.isEmpty(picUrl)) {
        // 正在下载
private void openVideoItemClick(BMXMessage bean) {
    if (mView == null || bean == null || bean.contentType() != BMXMessage.ContentType.Video) {
        return;
    }
    BMXVideoAttachment body = BMXVideoAttachment.dynamic_cast(bean.attachment());
    if (body == null) {
        return;
    }
    String videoUrl = null;
    if (!TextUtils.isEmpty(body.path()) && new File(body.path()).exists()) {
        videoUrl = body.path();
    }
    if (TextUtils.isEmpty(videoUrl)) {
        // 正在下载
        ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.downloading));
        return;
    }
    BMXMessageAttachment.DownloadStatus status = body.downloadStatus();
    if (status == BMXMessageAttachment.DownloadStatus.Downloaing) {
        ToastUtil.showTextViewPrompt(mView.getContext().getString(R.string.downloading));
if (contentType == BMXMessage.ContentType.Text) {
    String text = mBmxMessage.content();
    if (!TextUtils.isEmpty(text)) {
        messageBean.setContent(text);
        return messageBean;
    }
    return null;
}
if (contentType == BMXMessage.ContentType.Image) {
    // 图片
    BMXImageAttachment body = BMXImageAttachment.dynamic_cast(mBmxMessage.attachment());
    if (body == null || body.size() == null || TextUtils.isEmpty(body.path())) {
        return null;
    }
    int w = (int)body.size().getMWidth();
    int h = (int)body.size().getMHeight();
    messageBean.setPath(body.path());
    messageBean.setW(w);
    messageBean.setH(h);
    return messageBean;
    }
    int w = (int)body.size().getMWidth();
    int h = (int)body.size().getMHeight();
    messageBean.setPath(body.path());
    messageBean.setW(w);
    messageBean.setH(h);
    return messageBean;
}
if (contentType == BMXMessage.ContentType.Voice) {
    // 语音
    BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(mBmxMessage.attachment());
    if (body == null || TextUtils.isEmpty(body.path())) {
        return null;
    }
    messageBean.setPath(body.path());
    messageBean.setDuration(body.duration());
    return messageBean;
}
if (contentType == BMXMessage.ContentType.File) {
    // 文件
    BMXVoiceAttachment body = BMXVoiceAttachment.dynamic_cast(mBmxMessage.attachment());
    if (body == null || TextUtils.isEmpty(body.path())) {
        return null;
    }
    messageBean.setPath(body.path());
    messageBean.setDuration(body.duration());
    return messageBean;
}
if (contentType == BMXMessage.ContentType.File) {
    // 文件
    BMXFileAttachment body = BMXFileAttachment.dynamic_cast(mBmxMessage.attachment());
    if (body == null || TextUtils.isEmpty(body.path())) {
        return null;
    }
    messageBean.setPath(body.path());
    messageBean.setDisplayName(body.displayName());
    return messageBean;
}
if (contentType == BMXMessage.ContentType.Location) {
    // 地图

function config

inline BMXMessageConfig config()

Message settings

Return: JSON(std::string)

Example:

@Override
public void onBindViewHolder(BaseChatHolder holder, int position) {
    if (holder == null) {
        return;
    }
    holder.showChatExtra(isShowTime(position), showReadAck);
    BMXMessage bean = mBeans.get(position);
    BMXMessageConfig config = bean.config();
    if (config != null){
        String action = config.getRTCAction();
        if (action != null && action.length() != 0 && !action.equals("record")){
            RecyclerView.LayoutParams param = new RecyclerView.LayoutParams(1, 1);
            holder.itemView.setLayoutParams(param);
        }
    }

    holder.setData(bean);
    // 有草稿
    SpannableStringBuilder spannable = new SpannableStringBuilder();
    String draftText = mContext.getString(R.string.draft);
    SpannableString spannableString = new SpannableString(draftText);
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, draftText.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.append(spannableString).append(draft);
    desc.setText(spannable);
} else {
    String msgDesc = ChatUtils.getInstance().getMessageDesc(mContext, lastMsg);
    if (lastMsg != null && lastMsg.isReceiveMsg() && lastMsg.config() != null) {
        // 有@
        try {
            BMXMessageConfig config = lastMsg.config();
            if (config.getMentionAll()) {
                msgDesc = mContext.getString(R.string.someone_at_you) + msgDesc;
            } else {
                ListOfLongLong atList = config.getMentionList();
                if (atList != null && !atList.isEmpty()) {
                    for (int i = 0; i < atList.size(); i++) {
    SpannableString spannableString = new SpannableString(draftText);
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, draftText.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.append(spannableString).append(draft);
    desc.setText(spannable);
} else {
    String msgDesc = ChatUtils.getInstance().getMessageDesc(mContext, lastMsg);
    if (lastMsg != null && lastMsg.isReceiveMsg() && lastMsg.config() != null) {
        // 有@
        try {
            BMXMessageConfig config = lastMsg.config();
            if (config.getMentionAll()) {
                msgDesc = mContext.getString(R.string.someone_at_you) + msgDesc;
            } else {
                ListOfLongLong atList = config.getMentionList();
                if (atList != null && !atList.isEmpty()) {
                    for (int i = 0; i < atList.size(); i++) {
                        if (atList.get(
                                i) == (SharePreferenceUtils.getInstance().getUserId())) {
                            msgDesc = mContext.getString(R.string.someone_at_you) + msgDesc;
} else if (type == BMXMessage.ContentType.File) {
    desc = "[" + context.getString(R.string.file) + "]";
} else if (type == BMXMessage.ContentType.Voice) {
    // 语音
    desc = "[" + context.getString(R.string.voice) + "]";
} else if (type == BMXMessage.ContentType.RTC) {
    if (message == null){
        return "[" + context.getString(R.string.unknown_message) + "]";
    }
    boolean isRecordMsg = false;
    BMXMessageConfig config = message.config();
    if (config != null) {
        String action = config.getRTCAction();
        if (action != null) {
            if (action.equals("record")) {
                isRecordMsg = true;
            }
        }
    }
    if (!isRecordMsg){

function setConfig

inline void setConfig(
    BMXMessageConfig arg0
)

Set message config information

Example:

public String sendRTCCallMessage(BMXMessageConfig.RTCCallType type, long roomId, long from, long to,
                                 String pin) {
    BMXMessageConfig con = BMXMessageConfig.createMessageConfig(false);
    con.setRTCCallInfo(type, roomId, from, BMXMessageConfig.RTCRoomType.Broadcast, pin);
    con.setPushMessageLocKey("call_in");
    BMXMessage msg = BMXMessage.createRTCMessage(from, to, BMXMessage.MessageType.Single, to, "");
    msg.setConfig(con);
    msg.setExtension("{\"rtc\":\"call\"}");
    handlerMessage(msg);
    return con.getRTCCallId();
public void sendRTCPickupMessage(long from, long to, String callId) {
    BMXMessageConfig con = BMXMessageConfig.createMessageConfig(false);
    con.setRTCPickupInfo(callId);
    BMXMessage msg = BMXMessage.createRTCMessage(from, to, BMXMessage.MessageType.Single, to, "");
    msg.setConfig(con);
    handlerMessage(msg);
public void sendRTCHangupMessage(long from, long to, String callId, String content, String pushMessageLocKey, String pushMessageLocArgs, boolean peerDrop) {
    BMXMessageConfig con = BMXMessageConfig.createMessageConfig(false);
    con.setRTCHangupInfo(callId, peerDrop);
    con.setPushMessageLocKey(pushMessageLocKey);
    if (pushMessageLocArgs.length() > 0){
        con.setPushMessageLocArgs(pushMessageLocArgs);
    }
    BMXMessage msg = BMXMessage.createRTCMessage(from, to, BMXMessage.MessageType.Single, to, content);
    msg.setConfig(con);
    handlerMessage(msg);

function extension

inline String extension()

Message extension information

Return: JSON(std::string)

Example:

    protected boolean filterMessage(BMXMessage message) {
        if (message == null) {
            return false;
        }
        if (message.contentType() == BMXMessage.ContentType.Text
                && !TextUtils.isEmpty(message.extension())) {
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(message.extension());
                if (jsonObject.has(MessageConfig.INPUT_STATUS) && message.fromId() != mMyUserId) {
                    handelInputStatus(message.extension());
                }
                //TODO
//                if (jsonObject.has("rtcKey") && jsonObject.has("rtcValue")) {
//                    if (TextUtils.equals(jsonObject.getString("rtcKey"), "join") && !TextUtils.isEmpty(jsonObject.getString("rtcValue"))) {
//                        String[] values = jsonObject.getString("rtcValue").split("_");
//                        String roomId = values[0];
//                        String[] chatIdArray = values[1].split(",");
//                        boolean hasVideo = TextUtils.equals(MessageConfig.CallMode.CALL_VIDEO+"", values[2]);
//                        List<Long> chatIds = new ArrayList<>();
    protected boolean filterMessage(BMXMessage message) {
        if (message == null) {
            return false;
        }
        if (message.contentType() == BMXMessage.ContentType.Text
                && !TextUtils.isEmpty(message.extension())) {
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(message.extension());
                if (jsonObject.has(MessageConfig.INPUT_STATUS) && message.fromId() != mMyUserId) {
                    handelInputStatus(message.extension());
                }
                //TODO
//                if (jsonObject.has("rtcKey") && jsonObject.has("rtcValue")) {
//                    if (TextUtils.equals(jsonObject.getString("rtcKey"), "join") && !TextUtils.isEmpty(jsonObject.getString("rtcValue"))) {
//                        String[] values = jsonObject.getString("rtcValue").split("_");
//                        String roomId = values[0];
//                        String[] chatIdArray = values[1].split(",");
//                        boolean hasVideo = TextUtils.equals(MessageConfig.CallMode.CALL_VIDEO+"", values[2]);
//                        List<Long> chatIds = new ArrayList<>();
    protected boolean filterMessage(BMXMessage message) {
        if (message == null) {
            return false;
        }
        if (message.contentType() == BMXMessage.ContentType.Text
                && !TextUtils.isEmpty(message.extension())) {
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(message.extension());
                if (jsonObject.has(MessageConfig.INPUT_STATUS) && message.fromId() != mMyUserId) {
                    handelInputStatus(message.extension());
                }
                //TODO
//                if (jsonObject.has("rtcKey") && jsonObject.has("rtcValue")) {
//                    if (TextUtils.equals(jsonObject.getString("rtcKey"), "join") && !TextUtils.isEmpty(jsonObject.getString("rtcValue"))) {
//                        String[] values = jsonObject.getString("rtcValue").split("_");
//                        String roomId = values[0];
//                        String[] chatIdArray = values[1].split(",");
//                        boolean hasVideo = TextUtils.equals(MessageConfig.CallMode.CALL_VIDEO+"", values[2]);
//                        List<Long> chatIds = new ArrayList<>();
private void handleRTCMessage(BMXMessage message){
    if (message == null) {
        return;
    }
    if (message.contentType() == BMXMessage.ContentType.RTC
            && !TextUtils.isEmpty(message.extension())) {
        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject(message.extension());
            if(!jsonObject.has("rtc_cmd")){
                return;
            }
            String cmd = jsonObject.getString("rtc_cmd");
            switch (cmd){
                case "switch_audio":
                    //切换为语音通话
                    switchAudio();
                    break;
                default:
                    break;
private void handleRTCMessage(BMXMessage message){
    if (message == null) {
        return;
    }
    if (message.contentType() == BMXMessage.ContentType.RTC
            && !TextUtils.isEmpty(message.extension())) {
        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject(message.extension());
            if(!jsonObject.has("rtc_cmd")){
                return;
            }
            String cmd = jsonObject.getString("rtc_cmd");
            switch (cmd){
                case "switch_audio":
                    //切换为语音通话
                    switchAudio();
                    break;
                default:
                    break;

function setExtension

inline void setExtension(
    String arg0
)

Set message extension information

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);
public void sendRTCMessage(long from, long to,
                                 String ext) {
    BMXMessage msg = BMXMessage.createRTCMessage(from, to, BMXMessage.MessageType.Single, to, "");
    msg.setExtension(ext);
    handlerMessage(msg);
public String sendRTCCallMessage(BMXMessageConfig.RTCCallType type, long roomId, long from, long to,
                                 String pin) {
    BMXMessageConfig con = BMXMessageConfig.createMessageConfig(false);
    con.setRTCCallInfo(type, roomId, from, BMXMessageConfig.RTCRoomType.Broadcast, pin);
    con.setPushMessageLocKey("call_in");
    BMXMessage msg = BMXMessage.createRTCMessage(from, to, BMXMessage.MessageType.Single, to, "");
    msg.setConfig(con);
    msg.setExtension("{\"rtc\":\"call\"}");
    handlerMessage(msg);
    return con.getRTCCallId();

function deliveryQos

inline BMXMessage.DeliveryQos deliveryQos()

QOS of messaging

Return: [DeliveryQos]

Example:

function setDeliveryQos

inline void setDeliveryQos(
    BMXMessage.DeliveryQos qos
)

Set QOS of messaging

Parameters:

  • qos QOS of messaging

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);

function senderName

inline String senderName()

Display name of message sender

Return: std::string

Example:

function setSenderName

inline void setSenderName(
    String senderName
)

Set display name of message sender

Parameters:

  • senderName Message text content

Example:

function groupAckCount

inline int groupAckCount()

AckCount of read group messages

Return: int

Example:

    return;
}
if (mMaxMessage.type() == BMXMessage.MessageType.Single) {
    // 单聊
    mTvReadStatus.setVisibility(View.VISIBLE);
    boolean isRead = mMaxMessage.isReadAcked();
    mTvReadStatus.setText(isRead ? getResources().getString(R.string.read) : getResources().getString(R.string.unread));
} else if (mMaxMessage.type() == BMXMessage.MessageType.Group) {
    // 群聊
    mTvReadStatus.setVisibility(mShowReadAck ? View.VISIBLE : View.GONE);
    int readCount = mMaxMessage.groupAckCount();
    mTvReadStatus.setText(getResources().getString(R.string.read_persons) + (readCount > 0 ? readCount : 0));
} else {
    mTvReadStatus.setVisibility(View.GONE);
}
mTvReadStatus.setOnClickListener((v) -> {
    if (!mShowReadAck || mActionListener == null) {
        return;
    }
    mActionListener.onGroupAck(mMaxMessage);

function setGroupAckCount

inline void setGroupAckCount(
    int count
)

Set groupAckCount of read messages (an SDK internal calling interface that shall not be called by upper layer)

Parameters:

  • count Set the number of read group messages

Example:

function groupAckUnreadCount

inline int groupAckUnreadCount()

AckCount of unread group messages

Return: int

Example:

function setGroupAckUnreadCount

inline void setGroupAckUnreadCount(
    int count
)

Set groupAckCount of unread messages (an SDK internal calling interface that shall not be called by upper layer)

Parameters:

  • count Set the number of unread group messages

Example:

function groupAckReadAll

inline boolean groupAckReadAll()

Whether all group messages are read

Return: bool

Example:

function groupPlayAckCount

inline int groupPlayAckCount()

Get count of played group messages

Return: bool

Example:

function setGroupPlayAckCount

inline void setGroupPlayAckCount(
    int count
)

Example:

function groupPlayAckUnreadCount

inline int groupPlayAckUnreadCount()

Get count of unread playback acknowledgements of group messages

Return: bool

Example:

function setGroupPlayAckUnreadCount

inline void setGroupPlayAckUnreadCount(
    int count
)

Example:

function groupPlayAckReadAll

inline boolean groupPlayAckReadAll()

Set all playback acknowledgements of group messages as read

Return: bool

Example:

function setPriority

inline void setPriority(
    int priority
)

Set message diffusion priority, default 0. 0 means diffusion, and the smaller the number, the more diffused. Value range 0-10. The default level of messages sent by ordinary users in chatroom is 5, which can be discarded. Admin level defaults to 0 and will not be discarded. Other values can be set according to business.

Parameters:

  • priority Set the number of unread group messages

Example:

function priority

inline int priority()

Message diffusion priority

Return: int

Example:

function setPushMessageMode

inline void setPushMessageMode(
    boolean arg0
)

Set whether to push messages

Example:

function isPushMessage

inline boolean isPushMessage()

Whether it is a push message

Return: boolean

Example:

function createMessage

static inline BMXMessage createMessage(
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    String content
)

Create a text message

Parameters:

  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • content Message content

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);
public BMXMessage sendTextMessage(Context context, BMXMessage.MessageType type, long from, long to, String text,
                                  Map<String, String> atMap, String senderName) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, text);
    if (msg == null) {
        return null;
    }
    // 文本功能添加@对象
    if (atMap != null && !atMap.isEmpty()) {
        BMXMessageConfig config = BMXMessageConfig.createMessageConfig(false);
        config.setSenderNickname(senderName);
        config.setPushMessage(ChatUtils.getInstance().getMessageDesc(context, msg));
        // @对象的存储信息 包括全部成员或者部分成员
        if (atMap.containsKey("-1")) {
            // @全部
            String atTitle = atMap.get("-1");
            if (!TextUtils.isEmpty(atTitle) && text.contains(atTitle)) {
                // 如果包含全部直接走全部 还需要判断文本消息是否包含完成的@名称 如果没有就不触发@
                config.setMentionAll(true);
            }
        } else {
public BMXMessage sendImageMessage(BMXMessage.MessageType type, long from, long to, String path,
        int w, int h) {
    BMXImageAttachment.Size size = new BMXMessageAttachment.Size(w, h);
    BMXImageAttachment imageAttachment = new BMXImageAttachment(path, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    return handlerMessage(msg);
public BMXMessage sendAudioMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time) {
    BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(path, time);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, voiceAttachment);
    return handlerMessage(msg);
public BMXMessage sendVideoMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time, int w, int h) {
    BMXVideoAttachment.Size size = new BMXVideoAttachment.Size(w, h);
    BMXVideoAttachment videoAttachment = new BMXVideoAttachment(path, time, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, videoAttachment);
    return handlerMessage(msg);
public BMXMessage sendFileMessage(BMXMessage.MessageType type, long from, long to, String path,
        String name) {
    BMXFileAttachment fileAttachment = new BMXFileAttachment(path, name);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, fileAttachment);
    return handlerMessage(msg);
public BMXMessage sendLocationMessage(BMXMessage.MessageType type, long from, long to,
        double latitude, double longitude, String address) {
    BMXLocationAttachment locationAttachment = new BMXLocationAttachment(latitude, longitude,
            address);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, locationAttachment);
    return handlerMessage(msg);
public BMXMessage forwardMessage(MessageBean messageBean, BMXMessage.MessageType type,
        long from, long to) {
    if (messageBean == null) {
        return null;
    }
    BMXMessage.ContentType contentType = messageBean.getContentType();
    BMXMessage message = null;
    if (contentType == BMXMessage.ContentType.Text) {
        message = BMXMessage.createMessage(from, to, type, to, messageBean.getContent());
    } else if (contentType == BMXMessage.ContentType.Image) {
        // 图片
        BMXImageAttachment.Size size = new BMXMessageAttachment.Size(messageBean.getW(),
                messageBean.getH());
        BMXImageAttachment imageAttachment = new BMXImageAttachment(messageBean.getPath(),
                size);
        message = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    } else if (contentType == BMXMessage.ContentType.Voice) {
        // 语音
        BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(messageBean.getPath(),
                messageBean.getDuration());

function createMessage

static inline BMXMessage createMessage(
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    BMXMessageAttachment attachment
)

Create a sent-attachment message

Parameters:

  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • attachment Attachment

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);
public BMXMessage sendTextMessage(Context context, BMXMessage.MessageType type, long from, long to, String text,
                                  Map<String, String> atMap, String senderName) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, text);
    if (msg == null) {
        return null;
    }
    // 文本功能添加@对象
    if (atMap != null && !atMap.isEmpty()) {
        BMXMessageConfig config = BMXMessageConfig.createMessageConfig(false);
        config.setSenderNickname(senderName);
        config.setPushMessage(ChatUtils.getInstance().getMessageDesc(context, msg));
        // @对象的存储信息 包括全部成员或者部分成员
        if (atMap.containsKey("-1")) {
            // @全部
            String atTitle = atMap.get("-1");
            if (!TextUtils.isEmpty(atTitle) && text.contains(atTitle)) {
                // 如果包含全部直接走全部 还需要判断文本消息是否包含完成的@名称 如果没有就不触发@
                config.setMentionAll(true);
            }
        } else {
public BMXMessage sendImageMessage(BMXMessage.MessageType type, long from, long to, String path,
        int w, int h) {
    BMXImageAttachment.Size size = new BMXMessageAttachment.Size(w, h);
    BMXImageAttachment imageAttachment = new BMXImageAttachment(path, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    return handlerMessage(msg);
public BMXMessage sendAudioMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time) {
    BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(path, time);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, voiceAttachment);
    return handlerMessage(msg);
public BMXMessage sendVideoMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time, int w, int h) {
    BMXVideoAttachment.Size size = new BMXVideoAttachment.Size(w, h);
    BMXVideoAttachment videoAttachment = new BMXVideoAttachment(path, time, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, videoAttachment);
    return handlerMessage(msg);
public BMXMessage sendFileMessage(BMXMessage.MessageType type, long from, long to, String path,
        String name) {
    BMXFileAttachment fileAttachment = new BMXFileAttachment(path, name);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, fileAttachment);
    return handlerMessage(msg);
public BMXMessage sendLocationMessage(BMXMessage.MessageType type, long from, long to,
        double latitude, double longitude, String address) {
    BMXLocationAttachment locationAttachment = new BMXLocationAttachment(latitude, longitude,
            address);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, locationAttachment);
    return handlerMessage(msg);
public BMXMessage forwardMessage(MessageBean messageBean, BMXMessage.MessageType type,
        long from, long to) {
    if (messageBean == null) {
        return null;
    }
    BMXMessage.ContentType contentType = messageBean.getContentType();
    BMXMessage message = null;
    if (contentType == BMXMessage.ContentType.Text) {
        message = BMXMessage.createMessage(from, to, type, to, messageBean.getContent());
    } else if (contentType == BMXMessage.ContentType.Image) {
        // 图片
        BMXImageAttachment.Size size = new BMXMessageAttachment.Size(messageBean.getW(),
                messageBean.getH());
        BMXImageAttachment imageAttachment = new BMXImageAttachment(messageBean.getPath(),
                size);
        message = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    } else if (contentType == BMXMessage.ContentType.Voice) {
        // 语音
        BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(messageBean.getPath(),
                messageBean.getDuration());

function createCommandMessage

static inline BMXMessage createCommandMessage(
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    String content
)

Create a sent command message (command message holds command information in a content field or an extension field)

Parameters:

  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • content Message content

Example:

public void sendCommandMessage(BMXMessage.MessageType type, long from, long to,
        String content) {
    handlerMessage(BMXMessage.createCommandMessage(from, to, type, to, content));

function createMessage

static inline BMXMessage createMessage(
    long msgId,
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    String content,
    long serverTimestamp
)

Create a received message

Parameters:

  • msgId Message id
  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • content Message content
  • serverTimestamp Server timestamp

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);
public BMXMessage sendTextMessage(Context context, BMXMessage.MessageType type, long from, long to, String text,
                                  Map<String, String> atMap, String senderName) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, text);
    if (msg == null) {
        return null;
    }
    // 文本功能添加@对象
    if (atMap != null && !atMap.isEmpty()) {
        BMXMessageConfig config = BMXMessageConfig.createMessageConfig(false);
        config.setSenderNickname(senderName);
        config.setPushMessage(ChatUtils.getInstance().getMessageDesc(context, msg));
        // @对象的存储信息 包括全部成员或者部分成员
        if (atMap.containsKey("-1")) {
            // @全部
            String atTitle = atMap.get("-1");
            if (!TextUtils.isEmpty(atTitle) && text.contains(atTitle)) {
                // 如果包含全部直接走全部 还需要判断文本消息是否包含完成的@名称 如果没有就不触发@
                config.setMentionAll(true);
            }
        } else {
public BMXMessage sendImageMessage(BMXMessage.MessageType type, long from, long to, String path,
        int w, int h) {
    BMXImageAttachment.Size size = new BMXMessageAttachment.Size(w, h);
    BMXImageAttachment imageAttachment = new BMXImageAttachment(path, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    return handlerMessage(msg);
public BMXMessage sendAudioMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time) {
    BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(path, time);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, voiceAttachment);
    return handlerMessage(msg);
public BMXMessage sendVideoMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time, int w, int h) {
    BMXVideoAttachment.Size size = new BMXVideoAttachment.Size(w, h);
    BMXVideoAttachment videoAttachment = new BMXVideoAttachment(path, time, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, videoAttachment);
    return handlerMessage(msg);
public BMXMessage sendFileMessage(BMXMessage.MessageType type, long from, long to, String path,
        String name) {
    BMXFileAttachment fileAttachment = new BMXFileAttachment(path, name);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, fileAttachment);
    return handlerMessage(msg);
public BMXMessage sendLocationMessage(BMXMessage.MessageType type, long from, long to,
        double latitude, double longitude, String address) {
    BMXLocationAttachment locationAttachment = new BMXLocationAttachment(latitude, longitude,
            address);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, locationAttachment);
    return handlerMessage(msg);
public BMXMessage forwardMessage(MessageBean messageBean, BMXMessage.MessageType type,
        long from, long to) {
    if (messageBean == null) {
        return null;
    }
    BMXMessage.ContentType contentType = messageBean.getContentType();
    BMXMessage message = null;
    if (contentType == BMXMessage.ContentType.Text) {
        message = BMXMessage.createMessage(from, to, type, to, messageBean.getContent());
    } else if (contentType == BMXMessage.ContentType.Image) {
        // 图片
        BMXImageAttachment.Size size = new BMXMessageAttachment.Size(messageBean.getW(),
                messageBean.getH());
        BMXImageAttachment imageAttachment = new BMXImageAttachment(messageBean.getPath(),
                size);
        message = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    } else if (contentType == BMXMessage.ContentType.Voice) {
        // 语音
        BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(messageBean.getPath(),
                messageBean.getDuration());

function createMessage

static inline BMXMessage createMessage(
    long msgId,
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    BMXMessageAttachment attachment,
    long serverTimestamp
)

Create a received message

Parameters:

  • msgId Message id
  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • attachment Attachment
  • serverTimestamp Server timestamp

Example:

public BMXMessage sendInputStatusMessage(BMXMessage.MessageType type, long from, long to,
        String extension) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, "");
    if (msg == null) {
        return null;
    }
    msg.setDeliveryQos(BMXMessage.DeliveryQos.AtMostOnce);
    msg.setExtension(extension);
    return handlerMessage(msg);
public BMXMessage sendTextMessage(Context context, BMXMessage.MessageType type, long from, long to, String text,
                                  Map<String, String> atMap, String senderName) {
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, text);
    if (msg == null) {
        return null;
    }
    // 文本功能添加@对象
    if (atMap != null && !atMap.isEmpty()) {
        BMXMessageConfig config = BMXMessageConfig.createMessageConfig(false);
        config.setSenderNickname(senderName);
        config.setPushMessage(ChatUtils.getInstance().getMessageDesc(context, msg));
        // @对象的存储信息 包括全部成员或者部分成员
        if (atMap.containsKey("-1")) {
            // @全部
            String atTitle = atMap.get("-1");
            if (!TextUtils.isEmpty(atTitle) && text.contains(atTitle)) {
                // 如果包含全部直接走全部 还需要判断文本消息是否包含完成的@名称 如果没有就不触发@
                config.setMentionAll(true);
            }
        } else {
public BMXMessage sendImageMessage(BMXMessage.MessageType type, long from, long to, String path,
        int w, int h) {
    BMXImageAttachment.Size size = new BMXMessageAttachment.Size(w, h);
    BMXImageAttachment imageAttachment = new BMXImageAttachment(path, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    return handlerMessage(msg);
public BMXMessage sendAudioMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time) {
    BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(path, time);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, voiceAttachment);
    return handlerMessage(msg);
public BMXMessage sendVideoMessage(BMXMessage.MessageType type, long from, long to, String path,
        int time, int w, int h) {
    BMXVideoAttachment.Size size = new BMXVideoAttachment.Size(w, h);
    BMXVideoAttachment videoAttachment = new BMXVideoAttachment(path, time, size);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, videoAttachment);
    return handlerMessage(msg);
public BMXMessage sendFileMessage(BMXMessage.MessageType type, long from, long to, String path,
        String name) {
    BMXFileAttachment fileAttachment = new BMXFileAttachment(path, name);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, fileAttachment);
    return handlerMessage(msg);
public BMXMessage sendLocationMessage(BMXMessage.MessageType type, long from, long to,
        double latitude, double longitude, String address) {
    BMXLocationAttachment locationAttachment = new BMXLocationAttachment(latitude, longitude,
            address);
    BMXMessage msg = BMXMessage.createMessage(from, to, type, to, locationAttachment);
    return handlerMessage(msg);
public BMXMessage forwardMessage(MessageBean messageBean, BMXMessage.MessageType type,
        long from, long to) {
    if (messageBean == null) {
        return null;
    }
    BMXMessage.ContentType contentType = messageBean.getContentType();
    BMXMessage message = null;
    if (contentType == BMXMessage.ContentType.Text) {
        message = BMXMessage.createMessage(from, to, type, to, messageBean.getContent());
    } else if (contentType == BMXMessage.ContentType.Image) {
        // 图片
        BMXImageAttachment.Size size = new BMXMessageAttachment.Size(messageBean.getW(),
                messageBean.getH());
        BMXImageAttachment imageAttachment = new BMXImageAttachment(messageBean.getPath(),
                size);
        message = BMXMessage.createMessage(from, to, type, to, imageAttachment);
    } else if (contentType == BMXMessage.ContentType.Voice) {
        // 语音
        BMXVoiceAttachment voiceAttachment = new BMXVoiceAttachment(messageBean.getPath(),
                messageBean.getDuration());

function createCommandMessage

static inline BMXMessage createCommandMessage(
    long msgId,
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId,
    String content,
    long serverTimestamp
)

Create a received command message (command message holds command information in a content field or an extension field)

Parameters:

  • msgId Message id
  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id
  • content Message content
  • serverTimestamp Server timestamp

Example:

public void sendCommandMessage(BMXMessage.MessageType type, long from, long to,
        String content) {
    handlerMessage(BMXMessage.createCommandMessage(from, to, type, to, content));

function createForwardMessage

static inline BMXMessage createForwardMessage(
    BMXMessage msg,
    long from,
    long to,
    BMXMessage.MessageType type,
    long conversationId
)

Create a forwarding message

Parameters:

  • msg Message to forward
  • from Message sender
  • to Message receiver
  • type Message type
  • conversationId Conversation id

Protected Functions Documentation

Example:

function BMXMessage

inline BMXMessage(
    long cPtr,
    boolean cMemoryOwn
)

Example:

function finalize

inline void finalize()

Example:

function getCPtr

static inline long getCPtr(
    BMXMessage obj
)

Example:


Updated on 2022-01-26 at 17:18:31 +0800

© 2019-2023 MaximTop | Homepage Last modified time: 2023-08-09 14:48:15

results matching ""

    No results matching ""