im::floo::floolib::BMXMessage

消息

Inherits from BMXBaseObject

Public Functions

Name
synchronized void delete()
long msgId()
消息唯一ID
long clientMsgId()
消息客户端ID,仅在消息发送端存在
long fromId()
消息发送方ID
long toId()
消息接收方ID
BMXMessage.MessageType type()
消息类型
long conversationId()
消息所属会话ID
BMXMessage.DeliveryStatus deliveryStatus()
消息投递状态
void setDeliveryStatus(BMXMessage.DeliveryStatus arg0)
设置消息投递状态
long serverTimestamp()
消息时间戳(服务端收到时的时间)
void setServerTimestamp(long arg0)
设置时间戳(服务端收到时的时间)
long clientTimestamp()
本地时间戳(消息创建或者收到时的本地时间)
void setClientTimestamp(long arg0)
设置消息本地时间戳
boolean isPlayed()
语音或者视频消息是否播放过,仅对收到的音视频消息有效
void setIsPlayed(boolean arg0)
boolean isPlayAcked()
语音或者视频消息是否收到播放回执,仅对收到的音视频消息有效
void setIsPlayAcked(boolean arg0)
boolean isReceiveMsg()
是否接收的消息
void setIsReceiveMsg(boolean arg0)
boolean isRead()
消息是否已读标志
void setIsRead(boolean arg0)
boolean isReadAcked()
对于发送方表示是否收到了已读回执,对于接收方表示是否发送了已读回执
void setIsReadAcked(boolean arg0)
boolean isDeliveryAcked()
对于发送方表示消息是否已投递到对方,对于接收方表示是否发送了消息已到达回执
void setIsDeliveryAcked(boolean arg0)
String content()
消息文本内容
void setContent(String content)
消息文本内容
BMXMessage.ContentType contentType()
消息内容类型,如果带附件就表示附件类型,不带附件就是文本类型
BMXMessageAttachment attachment()
消息附件,BMXMessage拥有附件的所有权,负责释放
BMXMessageConfig config()
消息的配置信息
void setConfig(BMXMessageConfig arg0)
设置消息配置信息
String extension()
消息扩展信息
void setExtension(String arg0)
设置消息扩展信息
BMXMessage.DeliveryQos deliveryQos()
消息投递QOS
void setDeliveryQos(BMXMessage.DeliveryQos qos)
设置消息投递QOS
String senderName()
消息发送者的显示名称
void setSenderName(String senderName)
设置消息的发送者显示名称
int groupAckCount()
群消息已读AckCount数目
void setGroupAckCount(int count)
设置消息已读groupAckCount数目(SDK 内部调用接口,上层不应该调用)
int groupAckUnreadCount()
群消息未读AckCount数目
void setGroupAckUnreadCount(int count)
设置消息未读groupAckCount数目(SDK 内部调用接口,上层不应该调用)
boolean groupAckReadAll()
群消息是否全部已读
int groupPlayAckCount()
获取群消息已播放计数
void setGroupPlayAckCount(int count)
int groupPlayAckUnreadCount()
获取群消息已播放回执未读计数
void setGroupPlayAckUnreadCount(int count)
boolean groupPlayAckReadAll()
设置所有群消息已播回执为已读
void setPriority(int priority)
设置消息的扩散优先级,默认为0。0表示扩散,数字越小扩散的越多。 取值范围0-10。普通人在聊天室发送的消息级别默认为5,可以丢弃。管理员默认为0不会丢弃。其它值可以根据业务自行设置。
int priority()
消息的扩散优先级
void setPushMessageMode(boolean arg0)
设置是否推送消息
boolean isPushMessage()
是否是推送消息
BMXMessage createMessage(long from, long to, BMXMessage.MessageType type, long conversationId, String content)
创建发送文本消息
BMXMessage createMessage(long from, long to, BMXMessage.MessageType type, long conversationId, BMXMessageAttachment attachment)
创建发送附件消息
BMXMessage createCommandMessage(long from, long to, BMXMessage.MessageType type, long conversationId, String content)
创建发送命令消息(命令消息通过content字段或者extension字段存放命令信息)
BMXMessage createMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, String content, long serverTimestamp)
创建收到的消息
BMXMessage createMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, BMXMessageAttachment attachment, long serverTimestamp)
创建收到的消息
BMXMessage createCommandMessage(long msgId, long from, long to, BMXMessage.MessageType type, long conversationId, String content, long serverTimestamp)
创建收到的命令消息(命令消息通过content字段或者extension字段存放命令信息)
BMXMessage createForwardMessage(BMXMessage msg, long from, long to, BMXMessage.MessageType type, long conversationId)
创建转发消息

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()

消息唯一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;
    }
if (TextUtils.isEmpty(picUrl)) {
    // 正在下载
    return;
}
List<PhotoViewBean> photoViewBeans = new ArrayList<>();
PhotoViewBean photoViewBean = new PhotoViewBean();
photoViewBean.setLocalPath(body.path());
photoViewBean.setThumbLocalPath(body.thumbnailPath());
photoViewBean.setThumbHttpUrl(body.thumbnailUrl());
photoViewBean.setHttpUrl(body.url());
photoViewBean.setMsgId(bean.msgId());
photoViewBeans.add(photoViewBean);
PhotoViewListBean listBean = new PhotoViewListBean();
listBean.setPhotoViewBeans(photoViewBeans);
PhotoDetailActivity.openPhotoDetail(mView.getContext(), listBean);
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;

function clientMsgId

inline long clientMsgId()

消息客户端ID,仅在消息发送端存在

Return: int64_t

Example:

function fromId

inline long fromId()

消息发送方ID

Return: int64_t

Example:

        boolean isOwner = GroupManager.getInstance().isGroupOwner(bmxGroup.ownerId());
        boolean isAdmin = GroupManager.getInstance().isAdmin(bmxGroup, SharePreferenceUtils.getInstance().getUserId()) || isOwner;
        boolean hideByGroupSettings = bmxGroup.hideMemberInfo();
        if (!hideByGroupSettings || isAdmin){
            hideMemberInfo = false;
        }
    }
}

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();
        if (!hideByGroupSettings || isAdmin){
            hideMemberInfo = false;
        }
    }
}

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 (hideMemberInfo){
    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 (hideMemberInfo){
            userName = CommonUtils.md5InBase64(item.username()+String.valueOf(mMaxMessage.fromId())).substring(0, 12);
        }
    }
} else{
    if (item != null && !TextUtils.isEmpty(item.alias())) {
        userName = item.alias();
    } 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();
                }

function toId

inline long toId()

消息接收方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()

消息类型

Return: [MessageType]

Example:

private void showHead() {
    if (mItemPos == ITEM_CENTER || mMaxMessage == null) {
        return;
    }
    String userName = null;
    boolean group = mMaxMessage.type() == BMXMessage.MessageType.Group;
    boolean hideMemberInfo = true;
    if (group){
        BMXGroup bmxGroup = RosterFetcher.getFetcher().getGroup(mMaxMessage.conversationId());
        if (bmxGroup != null) {
            boolean isOwner = GroupManager.getInstance().isGroupOwner(bmxGroup.ownerId());
            boolean isAdmin = GroupManager.getInstance().isAdmin(bmxGroup, SharePreferenceUtils.getInstance().getUserId()) || isOwner;
            boolean hideByGroupSettings = bmxGroup.hideMemberInfo();
            if (!hideByGroupSettings || isAdmin){
                hideMemberInfo = false;
            }
        }
    }

    if (mMaxMessage.isReceiveMsg()) {
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()

消息所属会话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;
    boolean hideMemberInfo = true;
    if (group){
        BMXGroup bmxGroup = RosterFetcher.getFetcher().getGroup(mMaxMessage.conversationId());
        if (bmxGroup != null) {
            boolean isOwner = GroupManager.getInstance().isGroupOwner(bmxGroup.ownerId());
            boolean isAdmin = GroupManager.getInstance().isAdmin(bmxGroup, SharePreferenceUtils.getInstance().getUserId()) || isOwner;
            boolean hideByGroupSettings = bmxGroup.hideMemberInfo();
            if (!hideByGroupSettings || isAdmin){
                hideMemberInfo = false;
            }
        }
    }

    if (mMaxMessage.isReceiveMsg()) {
        if (!hideByGroupSettings || isAdmin){
            hideMemberInfo = false;
        }
    }
}

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 (hideMemberInfo){
            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()

消息投递状态

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();
    ForwardMsgActivity.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
)

设置消息投递状态

Example:

function serverTimestamp

inline long serverTimestamp()

消息时间戳(服务端收到时的时间)

Return: int64_t

Example:

long o1Time = m1 == null ? -1 : m1.serverTimestamp();
long o2Time = m2 == null ? -1 : m2.serverTimestamp();
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();

function setServerTimestamp

inline void setServerTimestamp(
    long arg0
)

设置时间戳(服务端收到时的时间)

Example:

function clientTimestamp

inline long clientTimestamp()

本地时间戳(消息创建或者收到时的本地时间)

Return: int64_t

Example:

function setClientTimestamp

inline void setClientTimestamp(
    long arg0
)

设置消息本地时间戳

Example:

function isPlayed

inline boolean isPlayed()

语音或者视频消息是否播放过,仅对收到的音视频消息有效

Return: bool

Example:

function setIsPlayed

inline void setIsPlayed(
    boolean arg0
)

Example:

function isPlayAcked

inline boolean isPlayAcked()

语音或者视频消息是否收到播放回执,仅对收到的音视频消息有效

Return: bool

Example:

function setIsPlayAcked

inline void setIsPlayAcked(
    boolean arg0
)

Example:

function isReceiveMsg

inline boolean isReceiveMsg()

是否接收的消息

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++) {
    if (bmxGroup != null) {
        boolean isOwner = GroupManager.getInstance().isGroupOwner(bmxGroup.ownerId());
        boolean isAdmin = GroupManager.getInstance().isAdmin(bmxGroup, SharePreferenceUtils.getInstance().getUserId()) || isOwner;
        boolean hideByGroupSettings = bmxGroup.hideMemberInfo();
        if (!hideByGroupSettings || isAdmin){
            hideMemberInfo = false;
        }
    }
}

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())) {
if (mMaxMessage.isReceiveMsg()) {
relay.setText(mView.getContext().getString(R.string.chat_msg_relay));
relay.setOnClickListener(v -> {
    dialog.dismiss();
    ForwardMsgActivity.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()

消息是否已读标志

Return: bool

Example:

function setIsRead

inline void setIsRead(
    boolean arg0
)

Example:

function isReadAcked

inline boolean isReadAcked()

对于发送方表示是否收到了已读回执,对于接收方表示是否发送了已读回执

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()

对于发送方表示消息是否已投递到对方,对于接收方表示是否发送了消息已到达回执

Return: bool

Example:

function setIsDeliveryAcked

inline void setIsDeliveryAcked(
    boolean arg0
)

Example:

function content

inline String 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
)

消息文本内容

Parameters:

  • content 消息文本内容

Example:

function contentType

inline BMXMessage.ContentType contentType()

消息内容类型,如果带附件就表示附件类型,不带附件就是文本类型

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()

消息附件,BMXMessage拥有附件的所有权,负责释放

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()

消息的配置信息

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
)

设置消息配置信息

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);
        for (Map.Entry<String, String> entry : atMap.entrySet()) {
            // 发送文字包含@对象的名称时再加入 防止输入框@对象名称被修改
            if (entry.getValue() != null && !TextUtils.isEmpty(entry.getValue())
                    && text.contains(entry.getValue())) {
                // @部分成员 feed信息只需要feedId和userId 所以需要去除无用的信息
                atIds.add(Long.valueOf(entry.getKey()));
            }
        }
        config.setMentionList(atIds);
    }
    msg.setConfig(config);
}
return handlerMessage(msg);

function extension

inline String extension()

消息扩展信息

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
)

设置消息扩展信息

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

Return: [DeliveryQos]

Example:

function setDeliveryQos

inline void setDeliveryQos(
    BMXMessage.DeliveryQos qos
)

设置消息投递QOS

Parameters:

  • qos 消息投递QOS

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()

消息发送者的显示名称

Return: std::string

Example:

function setSenderName

inline void setSenderName(
    String senderName
)

设置消息的发送者显示名称

Parameters:

  • senderName 消息文本内容

Example:

function groupAckCount

inline int groupAckCount()

群消息已读AckCount数目

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
)

设置消息已读groupAckCount数目(SDK 内部调用接口,上层不应该调用)

Parameters:

  • count 设置群消息已读数目

Example:

function groupAckUnreadCount

inline int groupAckUnreadCount()

群消息未读AckCount数目

Return: int

Example:

function setGroupAckUnreadCount

inline void setGroupAckUnreadCount(
    int count
)

设置消息未读groupAckCount数目(SDK 内部调用接口,上层不应该调用)

Parameters:

  • count 设置群消息未读数目

Example:

function groupAckReadAll

inline boolean groupAckReadAll()

群消息是否全部已读

Return: bool

Example:

function groupPlayAckCount

inline int groupPlayAckCount()

获取群消息已播放计数

Return: bool

Example:

function setGroupPlayAckCount

inline void setGroupPlayAckCount(
    int count
)

Example:

function groupPlayAckUnreadCount

inline int groupPlayAckUnreadCount()

获取群消息已播放回执未读计数

Return: bool

Example:

function setGroupPlayAckUnreadCount

inline void setGroupPlayAckUnreadCount(
    int count
)

Example:

function groupPlayAckReadAll

inline boolean groupPlayAckReadAll()

设置所有群消息已播回执为已读

Return: bool

Example:

function setPriority

inline void setPriority(
    int priority
)

设置消息的扩散优先级,默认为0。0表示扩散,数字越小扩散的越多。 取值范围0-10。普通人在聊天室发送的消息级别默认为5,可以丢弃。管理员默认为0不会丢弃。其它值可以根据业务自行设置。

Parameters:

  • priority 优先级

Example:

function priority

inline int priority()

消息的扩散优先级

Return: int

Example:

function setPushMessageMode

inline void setPushMessageMode(
    boolean arg0
)

设置是否推送消息

Example:

function isPushMessage

inline boolean isPushMessage()

是否是推送消息

Return: boolean

Example:

function createMessage

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

创建发送文本消息

Parameters:

  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • 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
)

创建发送附件消息

Parameters:

  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • 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
)

创建发送命令消息(命令消息通过content字段或者extension字段存放命令信息)

Parameters:

  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • 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
)

创建收到的消息

Parameters:

  • msgId 消息id
  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • content 消息内容
  • serverTimestamp 服务器时间戳

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
)

创建收到的消息

Parameters:

  • msgId 消息id
  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • attachment 附件
  • serverTimestamp 服务器时间戳

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
)

创建收到的命令消息(命令消息通过content字段或者extension字段存放命令信息)

Parameters:

  • msgId 消息id
  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话id
  • content 消息内容
  • serverTimestamp 服务器时间戳

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
)

创建转发消息

Parameters:

  • msg 要转发的消息
  • from 消息发送者
  • to 消息接收者
  • type 消息类型
  • conversationId 会话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-2024 美信拓扑 | 官网 | 网站地图 该文件修订时间: 2024-12-07 06:49:06