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;
}
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()
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:
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()
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;
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()
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;
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()
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++) {
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();
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);
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()
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