mirror of
https://github.com/WuKongIM/WuKongIMAndroidSDK
synced 2025-06-06 09:08:33 +00:00
1341 lines
55 KiB
Java
1341 lines
55 KiB
Java
package com.xinbida.wukongim.manager;
|
||
|
||
import android.text.TextUtils;
|
||
import android.util.Log;
|
||
|
||
import androidx.annotation.NonNull;
|
||
|
||
import com.xinbida.wukongim.WKIM;
|
||
import com.xinbida.wukongim.WKIMApplication;
|
||
import com.xinbida.wukongim.db.ConversationDbManager;
|
||
import com.xinbida.wukongim.db.MsgDbManager;
|
||
import com.xinbida.wukongim.db.WKDBColumns;
|
||
import com.xinbida.wukongim.entity.WKChannel;
|
||
import com.xinbida.wukongim.entity.WKChannelType;
|
||
import com.xinbida.wukongim.entity.WKConversationMsg;
|
||
import com.xinbida.wukongim.entity.WKMentionInfo;
|
||
import com.xinbida.wukongim.entity.WKMessageGroupByDate;
|
||
import com.xinbida.wukongim.entity.WKMessageSearchResult;
|
||
import com.xinbida.wukongim.entity.WKMsg;
|
||
import com.xinbida.wukongim.entity.WKMsgExtra;
|
||
import com.xinbida.wukongim.entity.WKMsgReaction;
|
||
import com.xinbida.wukongim.entity.WKMsgSetting;
|
||
import com.xinbida.wukongim.entity.WKSendOptions;
|
||
import com.xinbida.wukongim.entity.WKSyncExtraMsg;
|
||
import com.xinbida.wukongim.entity.WKSyncMsg;
|
||
import com.xinbida.wukongim.entity.WKSyncMsgReaction;
|
||
import com.xinbida.wukongim.entity.WKSyncRecent;
|
||
import com.xinbida.wukongim.entity.WKUIConversationMsg;
|
||
import com.xinbida.wukongim.interfaces.IClearMsgListener;
|
||
import com.xinbida.wukongim.interfaces.IDeleteMsgListener;
|
||
import com.xinbida.wukongim.interfaces.IGetOrSyncHistoryMsgBack;
|
||
import com.xinbida.wukongim.interfaces.IMessageStoreBeforeIntercept;
|
||
import com.xinbida.wukongim.interfaces.INewMsgListener;
|
||
import com.xinbida.wukongim.interfaces.IRefreshMsg;
|
||
import com.xinbida.wukongim.interfaces.ISendACK;
|
||
import com.xinbida.wukongim.interfaces.ISendMsgCallBackListener;
|
||
import com.xinbida.wukongim.interfaces.ISyncChannelMsgBack;
|
||
import com.xinbida.wukongim.interfaces.ISyncChannelMsgListener;
|
||
import com.xinbida.wukongim.interfaces.ISyncOfflineMsgBack;
|
||
import com.xinbida.wukongim.interfaces.ISyncOfflineMsgListener;
|
||
import com.xinbida.wukongim.interfaces.IUploadAttacResultListener;
|
||
import com.xinbida.wukongim.interfaces.IUploadAttachmentListener;
|
||
import com.xinbida.wukongim.interfaces.IUploadMsgExtraListener;
|
||
import com.xinbida.wukongim.message.MessageHandler;
|
||
import com.xinbida.wukongim.message.WKConnection;
|
||
import com.xinbida.wukongim.message.type.WKMsgContentType;
|
||
import com.xinbida.wukongim.message.type.WKSendMsgResult;
|
||
import com.xinbida.wukongim.msgmodel.WKFormatErrorContent;
|
||
import com.xinbida.wukongim.msgmodel.WKImageContent;
|
||
import com.xinbida.wukongim.msgmodel.WKMessageContent;
|
||
import com.xinbida.wukongim.msgmodel.WKMsgEntity;
|
||
import com.xinbida.wukongim.msgmodel.WKReply;
|
||
import com.xinbida.wukongim.msgmodel.WKTextContent;
|
||
import com.xinbida.wukongim.msgmodel.WKVideoContent;
|
||
import com.xinbida.wukongim.msgmodel.WKVoiceContent;
|
||
import com.xinbida.wukongim.utils.DateUtils;
|
||
import com.xinbida.wukongim.utils.WKCommonUtils;
|
||
import com.xinbida.wukongim.utils.WKLoggerUtils;
|
||
import com.xinbida.wukongim.utils.WKTypeUtils;
|
||
|
||
import org.json.JSONArray;
|
||
import org.json.JSONException;
|
||
import org.json.JSONObject;
|
||
|
||
import java.lang.reflect.InvocationTargetException;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Timer;
|
||
import java.util.TimerTask;
|
||
import java.util.UUID;
|
||
import java.util.concurrent.ConcurrentHashMap;
|
||
|
||
/**
|
||
* 5/20/21 5:38 PM
|
||
* 消息管理
|
||
*/
|
||
public class MsgManager extends BaseManager {
|
||
private final String TAG = "MsgManager";
|
||
|
||
private MsgManager() {
|
||
}
|
||
|
||
private static class MsgManagerBinder {
|
||
static final MsgManager msgManager = new MsgManager();
|
||
}
|
||
|
||
public static MsgManager getInstance() {
|
||
return MsgManagerBinder.msgManager;
|
||
}
|
||
|
||
private final long wkOrderSeqFactor = 1000L;
|
||
// 消息修改
|
||
private ConcurrentHashMap<String, IRefreshMsg> refreshMsgListenerMap;
|
||
// 监听发送消息回调
|
||
private ConcurrentHashMap<String, ISendMsgCallBackListener> sendMsgCallBackListenerHashMap;
|
||
// 删除消息监听
|
||
private ConcurrentHashMap<String, IDeleteMsgListener> deleteMsgListenerMap;
|
||
// 发送消息ack监听
|
||
private ConcurrentHashMap<String, ISendACK> sendAckListenerMap;
|
||
// 新消息监听
|
||
private ConcurrentHashMap<String, INewMsgListener> newMsgListenerMap;
|
||
// 清空消息
|
||
private ConcurrentHashMap<String, IClearMsgListener> clearMsgMap;
|
||
// 上传文件附件
|
||
private IUploadAttachmentListener iUploadAttachmentListener;
|
||
// 同步离线消息
|
||
private ISyncOfflineMsgListener iOfflineMsgListener;
|
||
// 同步channel内消息
|
||
private ISyncChannelMsgListener iSyncChannelMsgListener;
|
||
|
||
// 消息存库拦截器
|
||
private IMessageStoreBeforeIntercept messageStoreBeforeIntercept;
|
||
// 自定义消息model
|
||
private List<java.lang.Class<? extends WKMessageContent>> customContentMsgList;
|
||
// 上传消息扩展
|
||
private IUploadMsgExtraListener iUploadMsgExtraListener;
|
||
private Timer checkMsgNeedUploadTimer;
|
||
|
||
// 初始化默认消息model
|
||
public void initNormalMsg() {
|
||
if (customContentMsgList == null) {
|
||
customContentMsgList = new ArrayList<>();
|
||
customContentMsgList.add(WKTextContent.class);
|
||
customContentMsgList.add(WKImageContent.class);
|
||
customContentMsgList.add(WKVideoContent.class);
|
||
customContentMsgList.add(WKVoiceContent.class);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 注册消息module
|
||
*
|
||
* @param contentMsg 消息
|
||
*/
|
||
public void registerContentMsg(java.lang.Class<? extends WKMessageContent> contentMsg) {
|
||
if (WKCommonUtils.isEmpty(customContentMsgList))
|
||
initNormalMsg();
|
||
try {
|
||
boolean isAdd = true;
|
||
for (int i = 0, size = customContentMsgList.size(); i < size; i++) {
|
||
if (customContentMsgList.get(i).getDeclaredConstructor().newInstance().type == contentMsg.newInstance().type) {
|
||
isAdd = false;
|
||
break;
|
||
}
|
||
}
|
||
if (isAdd)
|
||
customContentMsgList.add(contentMsg);
|
||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException |
|
||
InvocationTargetException e) {
|
||
WKLoggerUtils.getInstance().e(TAG, "registerContentMsg error " + e.getLocalizedMessage());
|
||
}
|
||
|
||
}
|
||
|
||
// 通过json获取消息model
|
||
public WKMessageContent getMsgContentModel(JSONObject jsonObject) {
|
||
int type = jsonObject.optInt("type");
|
||
WKMessageContent messageContent = getMsgContentModel(type, jsonObject);
|
||
return messageContent;
|
||
}
|
||
|
||
public WKMessageContent getMsgContentModel(String jsonStr) {
|
||
if (TextUtils.isEmpty(jsonStr)) {
|
||
return new WKFormatErrorContent();
|
||
}
|
||
JSONObject jsonObject = null;
|
||
try {
|
||
jsonObject = new JSONObject(jsonStr);
|
||
} catch (JSONException e) {
|
||
WKLoggerUtils.getInstance().e(TAG, "getMsgContentModel The parameter is not a JSON");
|
||
}
|
||
if (jsonObject == null) {
|
||
return new WKFormatErrorContent();
|
||
}
|
||
return getMsgContentModel(jsonObject);
|
||
}
|
||
|
||
public WKMessageContent getMsgContentModel(int contentType, JSONObject jsonObject) {
|
||
if (jsonObject == null) jsonObject = new JSONObject();
|
||
WKMessageContent baseContentMsgModel = getContentMsgModel(contentType, jsonObject);
|
||
if (baseContentMsgModel == null) {
|
||
baseContentMsgModel = new WKMessageContent();
|
||
}
|
||
//解析@成员列表
|
||
if (jsonObject.has("mention")) {
|
||
JSONObject tempJson = jsonObject.optJSONObject("mention");
|
||
if (tempJson != null) {
|
||
//是否@所有人
|
||
if (tempJson.has("all"))
|
||
baseContentMsgModel.mentionAll = tempJson.optInt("all");
|
||
JSONArray uidList = tempJson.optJSONArray("uids");
|
||
|
||
if (uidList != null && uidList.length() > 0) {
|
||
WKMentionInfo mentionInfo = new WKMentionInfo();
|
||
List<String> mentionInfoUIDs = new ArrayList<>();
|
||
for (int i = 0, size = uidList.length(); i < size; i++) {
|
||
String uid = uidList.optString(i);
|
||
if (uid.equals(WKIMApplication.getInstance().getUid())) {
|
||
mentionInfo.isMentionMe = true;
|
||
}
|
||
mentionInfoUIDs.add(uid);
|
||
}
|
||
mentionInfo.uids = mentionInfoUIDs;
|
||
if (baseContentMsgModel.mentionAll == 1) {
|
||
mentionInfo.isMentionMe = true;
|
||
}
|
||
baseContentMsgModel.mentionInfo = mentionInfo;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (jsonObject.has("from_uid"))
|
||
baseContentMsgModel.fromUID = jsonObject.optString("from_uid");
|
||
if (jsonObject.has("flame"))
|
||
baseContentMsgModel.flame = jsonObject.optInt("flame");
|
||
if (jsonObject.has("flame_second"))
|
||
baseContentMsgModel.flameSecond = jsonObject.optInt("flame_second");
|
||
if (jsonObject.has("robot_id"))
|
||
baseContentMsgModel.robotID = jsonObject.optString("robot_id");
|
||
|
||
//判断消息中是否包含回复情况
|
||
if (jsonObject.has("reply")) {
|
||
baseContentMsgModel.reply = new WKReply();
|
||
JSONObject replyJson = jsonObject.optJSONObject("reply");
|
||
if (replyJson != null) {
|
||
baseContentMsgModel.reply = baseContentMsgModel.reply.decodeMsg(replyJson);
|
||
}
|
||
}
|
||
|
||
if (jsonObject.has("entities")) {
|
||
JSONArray jsonArray = jsonObject.optJSONArray("entities");
|
||
if (jsonArray != null && jsonArray.length() > 0) {
|
||
List<WKMsgEntity> list = new ArrayList<>();
|
||
for (int i = 0; i < jsonArray.length(); i++) {
|
||
WKMsgEntity entity = new WKMsgEntity();
|
||
JSONObject jo = jsonArray.optJSONObject(i);
|
||
entity.type = jo.optString("type");
|
||
entity.offset = jo.optInt("offset");
|
||
entity.length = jo.optInt("length");
|
||
entity.value = jo.optString("value");
|
||
list.add(entity);
|
||
}
|
||
baseContentMsgModel.entities = list;
|
||
}
|
||
}
|
||
return baseContentMsgModel;
|
||
}
|
||
|
||
/**
|
||
* 将json消息转成对于的消息model
|
||
*
|
||
* @param type content type
|
||
* @param jsonObject content json
|
||
* @return model
|
||
*/
|
||
private WKMessageContent getContentMsgModel(int type, JSONObject jsonObject) {
|
||
java.lang.Class<? extends WKMessageContent> baseMsg = null;
|
||
if (customContentMsgList != null && !customContentMsgList.isEmpty()) {
|
||
try {
|
||
for (int i = 0, size = customContentMsgList.size(); i < size; i++) {
|
||
if (customContentMsgList.get(i).getDeclaredConstructor().newInstance().type == type) {
|
||
baseMsg = customContentMsgList.get(i);
|
||
break;
|
||
}
|
||
}
|
||
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException |
|
||
InvocationTargetException e) {
|
||
WKLoggerUtils.getInstance().e(TAG, "getContentMsgModel error" + e.getLocalizedMessage());
|
||
return null;
|
||
}
|
||
}
|
||
try {
|
||
// 注册的消息model必须提供无参的构造方法
|
||
if (baseMsg != null) {
|
||
return baseMsg.newInstance().decodeMsg(jsonObject);
|
||
}
|
||
} catch (IllegalAccessException | InstantiationException e) {
|
||
WKLoggerUtils.getInstance().e(TAG, "getContentMsgModel decodeMsg error");
|
||
return null;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
private long getOrNearbyMsgSeq(long orderSeq) {
|
||
if (orderSeq % wkOrderSeqFactor == 0) {
|
||
return orderSeq / wkOrderSeqFactor;
|
||
}
|
||
return (orderSeq - orderSeq % wkOrderSeqFactor) / wkOrderSeqFactor;
|
||
}
|
||
|
||
/**
|
||
* 查询或同步某个频道消息
|
||
*
|
||
* @param channelId 频道ID
|
||
* @param channelType 频道类型
|
||
* @param oldestOrderSeq 最后一次消息大orderSeq 第一次进入聊天传入0
|
||
* @param contain 是否包含 oldestOrderSeq 这条消息
|
||
* @param pullMode 拉取模式 0:向下拉取 1:向上拉取
|
||
* @param aroundMsgOrderSeq 查询此消息附近消息
|
||
* @param limit 每次获取数量
|
||
* @param iGetOrSyncHistoryMsgBack 请求返还
|
||
*/
|
||
public void getOrSyncHistoryMessages(String channelId, byte channelType, long oldestOrderSeq, boolean contain, int pullMode, int limit, long aroundMsgOrderSeq, final IGetOrSyncHistoryMsgBack iGetOrSyncHistoryMsgBack) {
|
||
new Thread(() -> {
|
||
int tempPullMode = pullMode;
|
||
long tempOldestOrderSeq = oldestOrderSeq;
|
||
boolean tempContain = contain;
|
||
if (aroundMsgOrderSeq != 0) {
|
||
// long maxMsgSeq = getMaxMessageSeqWithChannel(channelId, channelType);
|
||
long maxMsgSeq =
|
||
MsgDbManager.getInstance().queryMaxMessageSeqNotDeletedWithChannel(channelId, channelType);
|
||
long aroundMsgSeq = getOrNearbyMsgSeq(aroundMsgOrderSeq);
|
||
|
||
if (maxMsgSeq >= aroundMsgSeq && maxMsgSeq - aroundMsgSeq <= limit) {
|
||
// 显示最后一页数据
|
||
// oldestOrderSeq = 0;
|
||
tempOldestOrderSeq = getMaxOrderSeqWithChannel(channelId, channelType);
|
||
// tempOldestOrderSeq = getMessageOrderSeq(maxMsgSeq, channelId, channelType);
|
||
if (tempOldestOrderSeq < aroundMsgOrderSeq) {
|
||
tempOldestOrderSeq = aroundMsgOrderSeq;
|
||
}
|
||
tempContain = true;
|
||
tempPullMode = 0;
|
||
} else {
|
||
long minOrderSeq = MsgDbManager.getInstance().queryOrderSeq(channelId, channelType, aroundMsgOrderSeq, 3);
|
||
if (minOrderSeq == 0) {
|
||
tempOldestOrderSeq = aroundMsgOrderSeq;
|
||
} else {
|
||
if (minOrderSeq + limit < aroundMsgOrderSeq) {
|
||
if (aroundMsgOrderSeq % wkOrderSeqFactor == 0) {
|
||
tempOldestOrderSeq = (aroundMsgOrderSeq / wkOrderSeqFactor - 3) * wkOrderSeqFactor;
|
||
} else
|
||
tempOldestOrderSeq = aroundMsgOrderSeq - 3;
|
||
// oldestOrderSeq = aroundMsgOrderSeq;
|
||
} else {
|
||
// todo 这里只会查询3条数据 oldestOrderSeq = minOrderSeq
|
||
long startOrderSeq = MsgDbManager.getInstance().queryOrderSeq(channelId, channelType, aroundMsgOrderSeq, limit);
|
||
if (startOrderSeq == 0) {
|
||
tempOldestOrderSeq = aroundMsgOrderSeq;
|
||
} else
|
||
tempOldestOrderSeq = startOrderSeq;
|
||
}
|
||
}
|
||
tempPullMode = 1;
|
||
tempContain = true;
|
||
}
|
||
}
|
||
MsgDbManager.getInstance().queryOrSyncHistoryMessages(channelId, channelType, tempOldestOrderSeq, tempContain, tempPullMode, limit, iGetOrSyncHistoryMsgBack);
|
||
}).start();
|
||
}
|
||
|
||
public List<WKMsg> getAll() {
|
||
return MsgDbManager.getInstance().queryAll();
|
||
}
|
||
|
||
public List<WKMsg> getWithFromUID(String channelID, byte channelType, String fromUID, long oldestOrderSeq, int limit) {
|
||
return MsgDbManager.getInstance().queryWithFromUID(channelID, channelType, fromUID, oldestOrderSeq, limit);
|
||
}
|
||
|
||
/**
|
||
* 批量删除消息
|
||
*
|
||
* @param clientMsgNos 消息编号集合
|
||
*/
|
||
public void deleteWithClientMsgNos(List<String> clientMsgNos) {
|
||
if (WKCommonUtils.isEmpty(clientMsgNos)) return;
|
||
List<WKMsg> list = new ArrayList<>();
|
||
try {
|
||
WKIMApplication.getInstance().getDbHelper().getDb()
|
||
.beginTransaction();
|
||
for (int i = 0, size = clientMsgNos.size(); i < size; i++) {
|
||
WKMsg msg = MsgDbManager.getInstance().deleteWithClientMsgNo(clientMsgNos.get(i));
|
||
if (msg != null) {
|
||
list.add(msg);
|
||
}
|
||
}
|
||
WKIMApplication.getInstance().getDbHelper().getDb()
|
||
.setTransactionSuccessful();
|
||
} catch (Exception ignored) {
|
||
} finally {
|
||
if (WKIMApplication.getInstance().getDbHelper().getDb().inTransaction()) {
|
||
WKIMApplication.getInstance().getDbHelper().getDb()
|
||
.endTransaction();
|
||
}
|
||
}
|
||
List<WKMsg> deleteMsgList = new ArrayList<>();
|
||
for (int i = 0, size = list.size(); i < size; i++) {
|
||
setDeleteMsg(list.get(i));
|
||
boolean isAdd = true;
|
||
for (int j = 0, len = deleteMsgList.size(); j < len; j++) {
|
||
if (deleteMsgList.get(j).channelID.equals(list.get(i).channelID)
|
||
&& deleteMsgList.get(j).channelType == list.get(i).channelType) {
|
||
isAdd = false;
|
||
break;
|
||
}
|
||
}
|
||
if (isAdd) deleteMsgList.add(list.get(i));
|
||
}
|
||
for (int i = 0, size = deleteMsgList.size(); i < size; i++) {
|
||
WKMsg msg = MsgDbManager.getInstance().queryMaxOrderSeqMsgWithChannel(deleteMsgList.get(i).channelID, deleteMsgList.get(i).channelType);
|
||
if (msg != null) {
|
||
WKUIConversationMsg uiMsg = WKIM.getInstance().getConversationManager().updateWithWKMsg(msg);
|
||
if (uiMsg != null) {
|
||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(uiMsg, i == deleteMsgList.size()
|
||
- 1, "deleteWithClientMsgNOList");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public List<WKMsg> getExpireMessages(int limit) {
|
||
long time = DateUtils.getInstance().getCurrentSeconds();
|
||
return MsgDbManager.getInstance().queryExpireMessages(time, limit);
|
||
}
|
||
|
||
/**
|
||
* 删除某条消息
|
||
*
|
||
* @param client_seq 客户端序列号
|
||
*/
|
||
public boolean deleteWithClientSeq(long client_seq) {
|
||
return MsgDbManager.getInstance().deleteWithClientSeq(client_seq);
|
||
}
|
||
|
||
/**
|
||
* 查询某条消息所在行
|
||
*
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道类型
|
||
* @param clientMsgNo 客户端消息ID
|
||
* @return int
|
||
*/
|
||
public int getRowNoWithOrderSeq(String channelID, byte channelType, String clientMsgNo) {
|
||
WKMsg msg = MsgDbManager.getInstance().queryWithClientMsgNo(clientMsgNo);
|
||
return MsgDbManager.getInstance().queryRowNoWithOrderSeq(channelID, channelType, msg == null ? 0 : msg.orderSeq);
|
||
}
|
||
|
||
public int getRowNoWithMessageID(String channelID, byte channelType, String messageID) {
|
||
WKMsg msg = MsgDbManager.getInstance().queryWithMessageID(messageID, false);
|
||
return MsgDbManager.getInstance().queryRowNoWithOrderSeq(channelID, channelType, msg == null ? 0 : msg.orderSeq);
|
||
}
|
||
|
||
public void deleteWithClientMsgNO(String clientMsgNo) {
|
||
WKMsg msg = MsgDbManager.getInstance().deleteWithClientMsgNo(clientMsgNo);
|
||
if (msg != null) {
|
||
setDeleteMsg(msg);
|
||
WKConversationMsg conversationMsg = WKIM.getInstance().getConversationManager().getWithChannel(msg.channelID, msg.channelType);
|
||
if (conversationMsg != null && conversationMsg.lastClientMsgNO.equals(clientMsgNo)) {
|
||
WKMsg tempMsg = MsgDbManager.getInstance().queryMaxOrderSeqMsgWithChannel(msg.channelID, msg.channelType);
|
||
if (tempMsg != null) {
|
||
WKUIConversationMsg uiMsg = ConversationDbManager.getInstance().insertOrUpdateWithMsg(tempMsg, 0);
|
||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(uiMsg, true, "deleteWithClientMsgNO");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
public boolean deleteWithMessageID(String messageID) {
|
||
return MsgDbManager.getInstance().deleteWithMessageID(messageID);
|
||
}
|
||
|
||
public WKMsg getWithMessageID(String messageID) {
|
||
return MsgDbManager.getInstance().queryWithMessageID(messageID, true);
|
||
}
|
||
|
||
public List<WKMsg> getWithMessageIDs(List<String> msgIds) {
|
||
return MsgDbManager.getInstance().queryWithMsgIds(msgIds);
|
||
}
|
||
|
||
public int isDeletedMsg(JSONObject jsonObject) {
|
||
int isDelete = 0;
|
||
//消息可见数组
|
||
if (jsonObject != null && jsonObject.has("visibles")) {
|
||
boolean isIncludeLoginUser = false;
|
||
JSONArray jsonArray = jsonObject.optJSONArray("visibles");
|
||
if (jsonArray != null && jsonArray.length() > 0) {
|
||
for (int i = 0, size = jsonArray.length(); i < size; i++) {
|
||
if (jsonArray.optString(i).equals(WKIMApplication.getInstance().getUid())) {
|
||
isIncludeLoginUser = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
isDelete = isIncludeLoginUser ? 0 : 1;
|
||
}
|
||
return isDelete;
|
||
}
|
||
|
||
public List<WKMsg> getWithFlame() {
|
||
return MsgDbManager.getInstance().queryWithFlame();
|
||
}
|
||
|
||
public long getMessageOrderSeq(long messageSeq, String channelID, byte channelType) {
|
||
if (messageSeq == 0) {
|
||
long tempOrderSeq = MsgDbManager.getInstance().queryMaxOrderSeqWithChannel(channelID, channelType);
|
||
return tempOrderSeq + 1;
|
||
}
|
||
return messageSeq * wkOrderSeqFactor;
|
||
}
|
||
|
||
public long getMessageSeq(long messageOrderSeq) {
|
||
if (messageOrderSeq % wkOrderSeqFactor == 0) {
|
||
return messageOrderSeq / wkOrderSeqFactor;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
public long getReliableMessageSeq(long messageOrderSeq) {
|
||
return messageOrderSeq / wkOrderSeqFactor;
|
||
}
|
||
|
||
/**
|
||
* use getMaxReactionSeqWithChannel
|
||
*
|
||
* @param channelID channelId
|
||
* @param channelType channelType
|
||
* @return channel reaction max seq version
|
||
*/
|
||
@Deprecated
|
||
public long getMaxSeqWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().getMaxReactionSeqWithChannel(channelID, channelType);
|
||
}
|
||
|
||
public long getMaxReactionSeqWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().getMaxReactionSeqWithChannel(channelID, channelType);
|
||
}
|
||
|
||
|
||
public void saveMessageReactions(List<WKSyncMsgReaction> list) {
|
||
if (WKCommonUtils.isEmpty(list)) return;
|
||
List<WKMsgReaction> reactionList = new ArrayList<>();
|
||
List<String> msgIds = new ArrayList<>();
|
||
for (int i = 0, size = list.size(); i < size; i++) {
|
||
WKMsgReaction reaction = new WKMsgReaction();
|
||
reaction.messageID = list.get(i).message_id;
|
||
reaction.channelID = list.get(i).channel_id;
|
||
reaction.channelType = list.get(i).channel_type;
|
||
reaction.uid = list.get(i).uid;
|
||
reaction.name = list.get(i).name;
|
||
reaction.seq = list.get(i).seq;
|
||
reaction.emoji = list.get(i).emoji;
|
||
reaction.isDeleted = list.get(i).is_deleted;
|
||
reaction.createdAt = list.get(i).created_at;
|
||
msgIds.add(list.get(i).message_id);
|
||
reactionList.add(reaction);
|
||
}
|
||
saveMsgReactions(reactionList);
|
||
List<WKMsg> msgList = MsgDbManager.getInstance().queryWithMsgIds(msgIds);
|
||
getMsgReactionsAndRefreshMsg(msgIds, msgList);
|
||
}
|
||
|
||
public int getMaxMessageSeq() {
|
||
return MsgDbManager.getInstance().queryMaxMessageSeqWithChannel();
|
||
}
|
||
|
||
public int getMaxMessageSeqWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().queryMaxMessageSeqWithChannel(channelID, channelType);
|
||
}
|
||
|
||
public int getMaxOrderSeqWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().queryMaxMessageOrderSeqWithChannel(channelID, channelType);
|
||
}
|
||
|
||
public int getMinMessageSeqWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().queryMinMessageSeqWithChannel(channelID, channelType);
|
||
}
|
||
|
||
|
||
public List<WKMsgReaction> getMsgReactions(String messageID) {
|
||
List<String> ids = new ArrayList<>();
|
||
ids.add(messageID);
|
||
return MsgDbManager.getInstance().queryMsgReactionWithMsgIds(ids);
|
||
}
|
||
|
||
private void getMsgReactionsAndRefreshMsg(List<String> messageIds, List<WKMsg> updatedMsgList) {
|
||
List<WKMsgReaction> reactionList = MsgDbManager.getInstance().queryMsgReactionWithMsgIds(messageIds);
|
||
for (int i = 0, size = updatedMsgList.size(); i < size; i++) {
|
||
for (int j = 0, len = reactionList.size(); j < len; j++) {
|
||
if (updatedMsgList.get(i).messageID.equals(reactionList.get(j).messageID)) {
|
||
if (updatedMsgList.get(i).reactionList == null)
|
||
updatedMsgList.get(i).reactionList = new ArrayList<>();
|
||
updatedMsgList.get(i).reactionList.add(reactionList.get(j));
|
||
}
|
||
}
|
||
setRefreshMsg(updatedMsgList.get(i), i == updatedMsgList.size() - 1);
|
||
}
|
||
}
|
||
|
||
|
||
public synchronized long getClientSeq() {
|
||
return MsgDbManager.getInstance().queryMaxMessageSeqWithChannel();
|
||
}
|
||
|
||
/**
|
||
* 修改消息的扩展字段
|
||
*
|
||
* @param clientMsgNo 客户端ID
|
||
* @param hashExtra 扩展字段
|
||
*/
|
||
public boolean updateLocalExtraWithClientMsgNO(String clientMsgNo, HashMap<String, Object> hashExtra) {
|
||
if (hashExtra != null) {
|
||
JSONObject jsonObject = new JSONObject();
|
||
for (String key : hashExtra.keySet()) {
|
||
try {
|
||
jsonObject.put(key, hashExtra.get(key));
|
||
} catch (JSONException e) {
|
||
WKLoggerUtils.getInstance().e(TAG, "updateLocalExtraWithClientMsgNO local_extra is not a JSON");
|
||
}
|
||
}
|
||
return MsgDbManager.getInstance().updateFieldWithClientMsgNo(clientMsgNo, WKDBColumns.WKMessageColumns.extra, jsonObject.toString(), true);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 查询按日期分组的消息数量
|
||
*
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道类型
|
||
* @return List<WKMessageGroupByDate>
|
||
*/
|
||
public List<WKMessageGroupByDate> getMessageGroupByDateWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().queryMessageGroupByDateWithChannel(channelID, channelType);
|
||
}
|
||
|
||
public void clearAll() {
|
||
MsgDbManager.getInstance().clearEmpty();
|
||
}
|
||
|
||
public void saveMsg(WKMsg msg) {
|
||
int refreshType = 0;
|
||
if (!TextUtils.isEmpty(msg.clientMsgNO)) {
|
||
WKMsg tempMsg = MsgDbManager.getInstance().queryWithClientMsgNo(msg.clientMsgNO);
|
||
if (tempMsg != null) {
|
||
refreshType = 1;
|
||
}
|
||
}
|
||
if (msg.orderSeq == 0) {
|
||
long tempOrderSeq = getMessageOrderSeq(0, msg.channelID, msg.channelType);
|
||
msg.orderSeq = tempOrderSeq + 1;
|
||
}
|
||
msg.clientSeq = MsgDbManager.getInstance().insert(msg);
|
||
if (refreshType == 0)
|
||
pushNewMsg(msg);
|
||
else setRefreshMsg(msg, true);
|
||
}
|
||
|
||
/**
|
||
* 本地插入一条消息并更新会话记录表且未读消息数量加一
|
||
*
|
||
* @param wkMsg 消息对象
|
||
* @param addRedDots 是否显示红点
|
||
*/
|
||
public void saveAndUpdateConversationMsg(WKMsg wkMsg, boolean addRedDots) {
|
||
int refreshType = 0;
|
||
if (!TextUtils.isEmpty(wkMsg.clientMsgNO)) {
|
||
WKMsg tempMsg = MsgDbManager.getInstance().queryWithClientMsgNo(wkMsg.clientMsgNO);
|
||
if (tempMsg != null) {
|
||
refreshType = 1;
|
||
}
|
||
}
|
||
if (wkMsg.orderSeq == 0) {
|
||
long tempOrderSeq = getMessageOrderSeq(0, wkMsg.channelID, wkMsg.channelType);
|
||
wkMsg.orderSeq = tempOrderSeq + 1;
|
||
}
|
||
wkMsg.clientSeq = MsgDbManager.getInstance().insert(wkMsg);
|
||
if (refreshType == 0)
|
||
pushNewMsg(wkMsg);
|
||
else setRefreshMsg(wkMsg, true);
|
||
WKUIConversationMsg msg = ConversationDbManager.getInstance().insertOrUpdateWithMsg(wkMsg, addRedDots ? 1 : 0);
|
||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(msg, true, "insertAndUpdateConversationMsg");
|
||
}
|
||
|
||
/**
|
||
* 查询某个频道的固定类型消息
|
||
*
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道列席
|
||
* @param oldestOrderSeq 最后一次消息大orderSeq
|
||
* @param limit 每次获取数量
|
||
* @param contentTypes 消息内容类型
|
||
* @return List<WKMsg>
|
||
*/
|
||
public List<WKMsg> searchMsgWithChannelAndContentTypes(String channelID, byte channelType, long oldestOrderSeq, int limit, int[] contentTypes) {
|
||
return MsgDbManager.getInstance().searchWithChannelAndContentTypes(channelID, channelType, oldestOrderSeq, limit, contentTypes);
|
||
}
|
||
|
||
/**
|
||
* 搜索某个频道到消息
|
||
*
|
||
* @param searchKey 关键字
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道类型
|
||
* @return List<WKMsg>
|
||
*/
|
||
public List<WKMsg> searchWithChannel(String searchKey, String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().searchWithChannel(searchKey, channelID, channelType);
|
||
}
|
||
|
||
public List<WKMessageSearchResult> search(String searchKey) {
|
||
return MsgDbManager.getInstance().search(searchKey);
|
||
}
|
||
|
||
/**
|
||
* 修改语音是否已读
|
||
*
|
||
* @param clientMsgNo 客户端ID
|
||
* @param isReaded 1:已读
|
||
*/
|
||
public boolean updateVoiceReadStatus(String clientMsgNo, int isReaded, boolean isRefreshUI) {
|
||
return MsgDbManager.getInstance().updateFieldWithClientMsgNo(clientMsgNo, WKDBColumns.WKMessageColumns.voice_status, String.valueOf(isReaded), isRefreshUI);
|
||
}
|
||
|
||
/**
|
||
* 清空某个会话信息
|
||
*
|
||
* @param channelId 频道ID
|
||
* @param channelType 频道类型
|
||
*/
|
||
public boolean clearWithChannel(String channelId, byte channelType) {
|
||
boolean result = MsgDbManager.getInstance().deleteWithChannel(channelId, channelType);
|
||
if (result) {
|
||
if (clearMsgMap != null && !clearMsgMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, IClearMsgListener> entry : clearMsgMap.entrySet()) {
|
||
entry.getValue().clear(channelId, channelType, "");
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
public boolean clearWithChannelAndFromUID(String channelId, byte channelType, String fromUID) {
|
||
boolean result = MsgDbManager.getInstance().deleteWithChannelAndFromUID(channelId, channelType, fromUID);
|
||
if (result) {
|
||
if (clearMsgMap != null && !clearMsgMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, IClearMsgListener> entry : clearMsgMap.entrySet()) {
|
||
entry.getValue().clear(channelId, channelType, fromUID);
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
public boolean updateContentAndRefresh(String clientMsgNo, WKMessageContent messageContent, boolean isRefreshUI) {
|
||
return MsgDbManager.getInstance().updateFieldWithClientMsgNo(clientMsgNo, WKDBColumns.WKMessageColumns.content, messageContent.encodeMsg().toString(), isRefreshUI);
|
||
}
|
||
|
||
public void updateViewedAt(int viewed, long viewedAt, String clientMsgNo) {
|
||
MsgDbManager.getInstance().updateViewedAt(viewed, viewedAt, clientMsgNo);
|
||
}
|
||
|
||
/**
|
||
* 获取某个类型的聊天数据
|
||
*
|
||
* @param type 消息类型
|
||
* @param oldestClientSeq 最后一次消息客户端ID
|
||
* @param limit 数量
|
||
* @return list
|
||
*/
|
||
public List<WKMsg> getWithContentType(int type, long oldestClientSeq, int limit) {
|
||
return MsgDbManager.getInstance().queryWithContentType(type, oldestClientSeq, limit);
|
||
}
|
||
|
||
public void saveAndUpdateConversationMsg(WKMsg msg) {
|
||
int refreshType = 0;
|
||
if (!TextUtils.isEmpty(msg.clientMsgNO)) {
|
||
WKMsg tempMsg = MsgDbManager.getInstance().queryWithClientMsgNo(msg.clientMsgNO);
|
||
if (tempMsg != null) {
|
||
refreshType = 1;
|
||
}
|
||
}
|
||
if (msg.orderSeq == 0) {
|
||
long tempOrderSeq = getMessageOrderSeq(0, msg.channelID, msg.channelType);
|
||
msg.orderSeq = tempOrderSeq + 1;
|
||
}
|
||
MsgDbManager.getInstance().insert(msg);
|
||
if (refreshType == 0)
|
||
pushNewMsg(msg);
|
||
else setRefreshMsg(msg, true);
|
||
ConversationDbManager.getInstance().insertOrUpdateWithMsg(msg, 0);
|
||
}
|
||
|
||
|
||
public long getMsgExtraMaxVersionWithChannel(String channelID, byte channelType) {
|
||
return MsgDbManager.getInstance().queryMsgExtraMaxVersionWithChannel(channelID, channelType);
|
||
}
|
||
|
||
public WKMsg getWithClientMsgNO(String clientMsgNo) {
|
||
return MsgDbManager.getInstance().queryWithClientMsgNo(clientMsgNo);
|
||
}
|
||
|
||
|
||
public void saveRemoteExtraMsg(WKChannel channel, List<WKSyncExtraMsg> list) {
|
||
if (WKCommonUtils.isEmpty(list)) return;
|
||
List<WKMsgExtra> extraList = new ArrayList<>();
|
||
List<String> messageIds = new ArrayList<>();
|
||
List<String> deleteMsgIds = new ArrayList<>();
|
||
for (int i = 0, size = list.size(); i < size; i++) {
|
||
if (TextUtils.isEmpty(list.get(i).message_id)) {
|
||
continue;
|
||
}
|
||
WKMsgExtra extra = WKSyncExtraMsg2WKMsgExtra(channel.channelID, channel.channelType, list.get(i));
|
||
extraList.add(extra);
|
||
messageIds.add(list.get(i).message_id);
|
||
if (extra.isMutualDeleted == 1) {
|
||
deleteMsgIds.add(list.get(i).message_id);
|
||
}
|
||
}
|
||
List<WKMsg> updatedMsgList = MsgDbManager.getInstance().insertOrReplaceExtra(extraList);
|
||
if (!deleteMsgIds.isEmpty()) {
|
||
boolean isSuccess = MsgDbManager.getInstance().deleteWithMessageIDs(deleteMsgIds);
|
||
if (!isSuccess) {
|
||
WKLoggerUtils.getInstance().e(TAG, "saveRemoteExtraMsg delete message error");
|
||
}
|
||
String deletedMsgId = "";
|
||
WKConversationMsg conversationMsg = ConversationDbManager.getInstance().queryWithChannel(channel.channelID, channel.channelType);
|
||
if (conversationMsg != null && !TextUtils.isEmpty(conversationMsg.lastClientMsgNO)) {
|
||
WKMsg msg = getWithClientMsgNO(conversationMsg.lastClientMsgNO);
|
||
if (msg != null && !TextUtils.isEmpty(msg.messageID) && msg.messageSeq != 0) {
|
||
for (String msgId : deleteMsgIds) {
|
||
if (msg.messageID.equals(msgId)) {
|
||
deletedMsgId = msgId;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (!TextUtils.isEmpty(deletedMsgId) && conversationMsg != null) {
|
||
int rowNo = WKIM.getInstance().getMsgManager().getRowNoWithMessageID(channel.channelID, channel.channelType, deletedMsgId);
|
||
if (rowNo < conversationMsg.unreadCount) {
|
||
conversationMsg.unreadCount--;
|
||
}
|
||
WKIM.getInstance().getConversationManager().updateWithMsg(conversationMsg);
|
||
WKUIConversationMsg wkuiConversationMsg = WKIM.getInstance().getConversationManager().getUIConversationMsg(channel.channelID, channel.channelType);
|
||
WKIM.getInstance().getConversationManager().setOnRefreshMsg(wkuiConversationMsg, true, TAG + " saveRemoteExtraMsg");
|
||
}
|
||
}
|
||
getMsgReactionsAndRefreshMsg(messageIds, updatedMsgList);
|
||
}
|
||
|
||
public void addOnSyncOfflineMsgListener(ISyncOfflineMsgListener iOfflineMsgListener) {
|
||
this.iOfflineMsgListener = iOfflineMsgListener;
|
||
}
|
||
|
||
//添加删除消息监听
|
||
public void addOnDeleteMsgListener(String key, IDeleteMsgListener iDeleteMsgListener) {
|
||
if (iDeleteMsgListener == null || TextUtils.isEmpty(key)) return;
|
||
if (deleteMsgListenerMap == null) deleteMsgListenerMap = new ConcurrentHashMap<>();
|
||
deleteMsgListenerMap.put(key, iDeleteMsgListener);
|
||
}
|
||
|
||
public void removeDeleteMsgListener(String key) {
|
||
if (TextUtils.isEmpty(key)) return;
|
||
if (deleteMsgListenerMap != null) deleteMsgListenerMap.remove(key);
|
||
}
|
||
|
||
//设置删除消息
|
||
public void setDeleteMsg(WKMsg msg) {
|
||
if (deleteMsgListenerMap != null && !deleteMsgListenerMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, IDeleteMsgListener> entry : deleteMsgListenerMap.entrySet()) {
|
||
entry.getValue().onDeleteMsg(msg);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
void saveMsgReactions(List<WKMsgReaction> list) {
|
||
MsgDbManager.getInstance().insertMsgReactions(list);
|
||
}
|
||
|
||
|
||
public void setSyncOfflineMsg(ISyncOfflineMsgBack iSyncOfflineMsgBack) {
|
||
syncOfflineMsg(iSyncOfflineMsgBack);
|
||
}
|
||
|
||
private void syncOfflineMsg(ISyncOfflineMsgBack iSyncOfflineMsgBack) {
|
||
if (iOfflineMsgListener != null) {
|
||
runOnMainThread(() -> {
|
||
long max_message_seq = getMaxMessageSeq();
|
||
iOfflineMsgListener.getOfflineMsgs(max_message_seq, (isEnd, list) -> {
|
||
//保存同步消息
|
||
saveSyncMsg(list);
|
||
if (isEnd) {
|
||
iSyncOfflineMsgBack.onBack(isEnd, null);
|
||
} else {
|
||
syncOfflineMsg(iSyncOfflineMsgBack);
|
||
}
|
||
});
|
||
});
|
||
} else iSyncOfflineMsgBack.onBack(true, null);
|
||
}
|
||
|
||
|
||
public void setSendMsgCallback(WKMsg msg) {
|
||
if (sendMsgCallBackListenerHashMap != null && !sendMsgCallBackListenerHashMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, ISendMsgCallBackListener> entry : sendMsgCallBackListenerHashMap.entrySet()) {
|
||
entry.getValue().onInsertMsg(msg);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
public void addOnSendMsgCallback(String key, ISendMsgCallBackListener iSendMsgCallBackListener) {
|
||
if (TextUtils.isEmpty(key)) return;
|
||
if (sendMsgCallBackListenerHashMap == null) {
|
||
sendMsgCallBackListenerHashMap = new ConcurrentHashMap<>();
|
||
}
|
||
sendMsgCallBackListenerHashMap.put(key, iSendMsgCallBackListener);
|
||
}
|
||
|
||
public void removeSendMsgCallBack(String key) {
|
||
if (sendMsgCallBackListenerHashMap != null) {
|
||
sendMsgCallBackListenerHashMap.remove(key);
|
||
}
|
||
}
|
||
|
||
|
||
//监听同步频道消息
|
||
public void addOnSyncChannelMsgListener(ISyncChannelMsgListener listener) {
|
||
this.iSyncChannelMsgListener = listener;
|
||
}
|
||
|
||
public void setSyncChannelMsgListener(String channelID, byte channelType, long startMessageSeq, long endMessageSeq, int limit, int pullMode, ISyncChannelMsgBack iSyncChannelMsgBack) {
|
||
if (this.iSyncChannelMsgListener != null) {
|
||
runOnMainThread(() -> iSyncChannelMsgListener.syncChannelMsgs(channelID, channelType, startMessageSeq, endMessageSeq, limit, pullMode, syncChannelMsg -> {
|
||
if (syncChannelMsg != null && WKCommonUtils.isNotEmpty(syncChannelMsg.messages)) {
|
||
saveSyncChannelMSGs(syncChannelMsg.messages);
|
||
}
|
||
iSyncChannelMsgBack.onBack(syncChannelMsg);
|
||
}));
|
||
}
|
||
}
|
||
|
||
public void saveSyncChannelMSGs(List<WKSyncRecent> list) {
|
||
if (WKCommonUtils.isEmpty(list)) return;
|
||
List<WKMsg> msgList = new ArrayList<>();
|
||
List<WKMsgExtra> msgExtraList = new ArrayList<>();
|
||
List<WKMsgReaction> reactionList = new ArrayList<>();
|
||
List<String> msgIds = new ArrayList<>();
|
||
for (int j = 0, len = list.size(); j < len; j++) {
|
||
WKMsg wkMsg = WKSyncRecent2WKMsg(list.get(j));
|
||
if (wkMsg.type == WKMsgContentType.WK_INSIDE_MSG) {
|
||
continue;
|
||
}
|
||
msgList.add(wkMsg);
|
||
if (!TextUtils.isEmpty(wkMsg.messageID)) {
|
||
msgIds.add(wkMsg.messageID);
|
||
}
|
||
if (list.get(j).message_extra != null) {
|
||
WKMsgExtra extra = WKSyncExtraMsg2WKMsgExtra(wkMsg.channelID, wkMsg.channelType, list.get(j).message_extra);
|
||
msgExtraList.add(extra);
|
||
}
|
||
if (WKCommonUtils.isNotEmpty(wkMsg.reactionList)) {
|
||
reactionList.addAll(wkMsg.reactionList);
|
||
}
|
||
}
|
||
if (WKCommonUtils.isNotEmpty(msgExtraList)) {
|
||
MsgDbManager.getInstance().insertOrReplaceExtra(msgExtraList);
|
||
}
|
||
if (WKCommonUtils.isNotEmpty(msgList)) {
|
||
MsgDbManager.getInstance().insertMsgs(msgList);
|
||
}
|
||
if (WKCommonUtils.isNotEmpty(reactionList)) {
|
||
MsgDbManager.getInstance().insertMsgReactions(reactionList);
|
||
}
|
||
// List<WKMsg> saveList = MsgDbManager.getInstance().queryWithMsgIds(msgIds);
|
||
// getMsgReactionsAndRefreshMsg(msgIds, saveList);
|
||
}
|
||
|
||
public void addOnSendMsgAckListener(String key, ISendACK iSendACKListener) {
|
||
if (iSendACKListener == null || TextUtils.isEmpty(key)) return;
|
||
if (sendAckListenerMap == null) sendAckListenerMap = new ConcurrentHashMap<>();
|
||
sendAckListenerMap.put(key, iSendACKListener);
|
||
}
|
||
|
||
public void setSendMsgAck(WKMsg msg) {
|
||
if (sendAckListenerMap != null && !sendAckListenerMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, ISendACK> entry : sendAckListenerMap.entrySet()) {
|
||
entry.getValue().msgACK(msg);
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
|
||
public void removeSendMsgAckListener(String key) {
|
||
if (!TextUtils.isEmpty(key) && sendAckListenerMap != null) {
|
||
sendAckListenerMap.remove(key);
|
||
}
|
||
}
|
||
|
||
public void addOnUploadAttachListener(IUploadAttachmentListener iUploadAttachmentListener) {
|
||
this.iUploadAttachmentListener = iUploadAttachmentListener;
|
||
}
|
||
|
||
public void setUploadAttachment(WKMsg msg, IUploadAttacResultListener resultListener) {
|
||
if (iUploadAttachmentListener != null) {
|
||
runOnMainThread(() -> {
|
||
iUploadAttachmentListener.onUploadAttachmentListener(msg, resultListener);
|
||
});
|
||
}
|
||
}
|
||
|
||
public void addMessageStoreBeforeIntercept(IMessageStoreBeforeIntercept iMessageStoreBeforeInterceptListener) {
|
||
messageStoreBeforeIntercept = iMessageStoreBeforeInterceptListener;
|
||
}
|
||
|
||
public boolean setMessageStoreBeforeIntercept(WKMsg msg) {
|
||
return messageStoreBeforeIntercept == null || messageStoreBeforeIntercept.isSaveMsg(msg);
|
||
}
|
||
|
||
//添加消息修改
|
||
public void addOnRefreshMsgListener(String key, IRefreshMsg listener) {
|
||
if (TextUtils.isEmpty(key) || listener == null) return;
|
||
if (refreshMsgListenerMap == null) refreshMsgListenerMap = new ConcurrentHashMap<>();
|
||
refreshMsgListenerMap.put(key, listener);
|
||
}
|
||
|
||
|
||
public void removeRefreshMsgListener(String key) {
|
||
if (!TextUtils.isEmpty(key) && refreshMsgListenerMap != null) {
|
||
refreshMsgListenerMap.remove(key);
|
||
}
|
||
}
|
||
|
||
public void setRefreshMsg(WKMsg msg, boolean left) {
|
||
if (refreshMsgListenerMap != null && !refreshMsgListenerMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, IRefreshMsg> entry : refreshMsgListenerMap.entrySet()) {
|
||
entry.getValue().onRefresh(msg, left);
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
|
||
public void addOnNewMsgListener(String key, INewMsgListener iNewMsgListener) {
|
||
if (TextUtils.isEmpty(key) || iNewMsgListener == null) return;
|
||
if (newMsgListenerMap == null)
|
||
newMsgListenerMap = new ConcurrentHashMap<>();
|
||
newMsgListenerMap.put(key, iNewMsgListener);
|
||
}
|
||
|
||
public void removeNewMsgListener(String key) {
|
||
if (TextUtils.isEmpty(key)) return;
|
||
if (newMsgListenerMap != null) newMsgListenerMap.remove(key);
|
||
}
|
||
|
||
public void addOnClearMsgListener(String key, IClearMsgListener iClearMsgListener) {
|
||
if (TextUtils.isEmpty(key) || iClearMsgListener == null) return;
|
||
if (clearMsgMap == null) clearMsgMap = new ConcurrentHashMap<>();
|
||
clearMsgMap.put(key, iClearMsgListener);
|
||
}
|
||
|
||
public void removeClearMsg(String key) {
|
||
if (TextUtils.isEmpty(key)) return;
|
||
if (clearMsgMap != null) clearMsgMap.remove(key);
|
||
}
|
||
|
||
|
||
WKMsgExtra WKSyncExtraMsg2WKMsgExtra(String channelID, byte channelType, WKSyncExtraMsg extraMsg) {
|
||
WKMsgExtra extra = new WKMsgExtra();
|
||
extra.channelID = channelID;
|
||
extra.channelType = channelType;
|
||
extra.unreadCount = extraMsg.unread_count;
|
||
extra.readedCount = extraMsg.readed_count;
|
||
extra.readed = extraMsg.readed;
|
||
extra.messageID = extraMsg.message_id;
|
||
extra.isMutualDeleted = extraMsg.is_mutual_deleted;
|
||
extra.isPinned = extraMsg.is_pinned;
|
||
extra.extraVersion = extraMsg.extra_version;
|
||
extra.revoke = extraMsg.revoke;
|
||
extra.revoker = extraMsg.revoker;
|
||
extra.needUpload = 0;
|
||
if (extraMsg.content_edit != null) {
|
||
JSONObject jsonObject = new JSONObject(extraMsg.content_edit);
|
||
extra.contentEdit = jsonObject.toString();
|
||
}
|
||
|
||
extra.editedAt = extraMsg.edited_at;
|
||
return extra;
|
||
}
|
||
|
||
WKMsg WKSyncRecent2WKMsg(WKSyncRecent wkSyncRecent) {
|
||
WKMsg msg = new WKMsg();
|
||
msg.channelID = wkSyncRecent.channel_id;
|
||
msg.channelType = wkSyncRecent.channel_type;
|
||
msg.messageID = wkSyncRecent.message_id;
|
||
msg.messageSeq = wkSyncRecent.message_seq;
|
||
msg.clientMsgNO = wkSyncRecent.client_msg_no;
|
||
msg.fromUID = wkSyncRecent.from_uid;
|
||
msg.timestamp = wkSyncRecent.timestamp;
|
||
msg.orderSeq = msg.messageSeq * wkOrderSeqFactor;
|
||
msg.voiceStatus = wkSyncRecent.voice_status;
|
||
msg.isDeleted = wkSyncRecent.is_deleted;
|
||
msg.status = WKSendMsgResult.send_success;
|
||
msg.remoteExtra = new WKMsgExtra();
|
||
msg.remoteExtra.revoke = wkSyncRecent.revoke;
|
||
msg.remoteExtra.revoker = wkSyncRecent.revoker;
|
||
msg.remoteExtra.unreadCount = wkSyncRecent.unread_count;
|
||
msg.remoteExtra.readedCount = wkSyncRecent.readed_count;
|
||
msg.remoteExtra.readed = wkSyncRecent.readed;
|
||
msg.expireTime = wkSyncRecent.expire;
|
||
msg.expireTimestamp = msg.expireTime + msg.timestamp;
|
||
// msg.reactionList = wkSyncRecent.reactions;
|
||
// msg.receipt = wkSyncRecent.receipt;
|
||
msg.remoteExtra.extraVersion = wkSyncRecent.extra_version;
|
||
//处理消息设置
|
||
byte[] setting = WKTypeUtils.getInstance().intToByte(wkSyncRecent.setting);
|
||
msg.setting = WKTypeUtils.getInstance().getMsgSetting(setting[0]);
|
||
//如果是单聊先将channelId改成发送者ID
|
||
if (!TextUtils.isEmpty(msg.channelID)
|
||
&& !TextUtils.isEmpty(msg.fromUID)
|
||
&& msg.channelType == WKChannelType.PERSONAL
|
||
&& msg.channelID.equals(WKIMApplication.getInstance().getUid())) {
|
||
msg.channelID = msg.fromUID;
|
||
}
|
||
|
||
if (wkSyncRecent.payload != null) {
|
||
JSONObject jsonObject = new JSONObject(wkSyncRecent.payload);
|
||
msg.content = jsonObject.toString();
|
||
}
|
||
// 处理消息回应
|
||
if (WKCommonUtils.isNotEmpty(wkSyncRecent.reactions)) {
|
||
msg.reactionList = getMsgReaction(wkSyncRecent);
|
||
}
|
||
msg = MessageHandler.getInstance().parsingMsg(msg);
|
||
return msg;
|
||
}
|
||
|
||
private List<WKMsgReaction> getMsgReaction(WKSyncRecent wkSyncRecent) {
|
||
List<WKMsgReaction> list = new ArrayList<>();
|
||
for (int i = 0, size = wkSyncRecent.reactions.size(); i < size; i++) {
|
||
WKMsgReaction reaction = new WKMsgReaction();
|
||
reaction.channelID = wkSyncRecent.reactions.get(i).channel_id;
|
||
reaction.channelType = wkSyncRecent.reactions.get(i).channel_type;
|
||
reaction.uid = wkSyncRecent.reactions.get(i).uid;
|
||
reaction.name = wkSyncRecent.reactions.get(i).name;
|
||
reaction.emoji = wkSyncRecent.reactions.get(i).emoji;
|
||
reaction.seq = wkSyncRecent.reactions.get(i).seq;
|
||
reaction.isDeleted = wkSyncRecent.reactions.get(i).is_deleted;
|
||
reaction.messageID = wkSyncRecent.reactions.get(i).message_id;
|
||
reaction.createdAt = wkSyncRecent.reactions.get(i).created_at;
|
||
list.add(reaction);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public void saveSyncMsg(List<WKSyncMsg> wkSyncMsgs) {
|
||
if (WKCommonUtils.isEmpty(wkSyncMsgs)) return;
|
||
for (int i = 0, size = wkSyncMsgs.size(); i < size; i++) {
|
||
wkSyncMsgs.get(i).wkMsg = MessageHandler.getInstance().parsingMsg(wkSyncMsgs.get(i).wkMsg);
|
||
if (wkSyncMsgs.get(i).wkMsg.timestamp != 0)
|
||
wkSyncMsgs.get(i).wkMsg.orderSeq = wkSyncMsgs.get(i).wkMsg.timestamp;
|
||
else
|
||
wkSyncMsgs.get(i).wkMsg.orderSeq = getMessageOrderSeq(wkSyncMsgs.get(i).wkMsg.messageSeq, wkSyncMsgs.get(i).wkMsg.channelID, wkSyncMsgs.get(i).wkMsg.channelType);
|
||
}
|
||
MessageHandler.getInstance().saveSyncMsg(wkSyncMsgs);
|
||
}
|
||
|
||
|
||
public void updateMsgEdit(String msgID, String channelID, byte channelType, String content) {
|
||
WKMsgExtra wkMsgExtra = MsgDbManager.getInstance().queryMsgExtraWithMsgID(msgID);
|
||
if (wkMsgExtra == null) {
|
||
wkMsgExtra = new WKMsgExtra();
|
||
}
|
||
wkMsgExtra.messageID = msgID;
|
||
wkMsgExtra.channelID = channelID;
|
||
wkMsgExtra.channelType = channelType;
|
||
wkMsgExtra.editedAt = DateUtils.getInstance().getCurrentSeconds();
|
||
wkMsgExtra.contentEdit = content;
|
||
wkMsgExtra.needUpload = 1;
|
||
List<WKMsgExtra> list = new ArrayList<>();
|
||
list.add(wkMsgExtra);
|
||
List<WKMsg> wkMsgList = MsgDbManager.getInstance().insertOrReplaceExtra(list);
|
||
List<String> messageIds = new ArrayList<>();
|
||
messageIds.add(msgID);
|
||
if (WKCommonUtils.isNotEmpty(wkMsgList)) {
|
||
getMsgReactionsAndRefreshMsg(messageIds, wkMsgList);
|
||
setUploadMsgExtra(wkMsgExtra);
|
||
}
|
||
}
|
||
|
||
private synchronized void startCheckTimer() {
|
||
if (checkMsgNeedUploadTimer == null) {
|
||
checkMsgNeedUploadTimer = new Timer();
|
||
}
|
||
checkMsgNeedUploadTimer.schedule(new TimerTask() {
|
||
@Override
|
||
public void run() {
|
||
List<WKMsgExtra> list = MsgDbManager.getInstance().queryMsgExtraWithNeedUpload(1);
|
||
if (WKCommonUtils.isNotEmpty(list)) {
|
||
for (WKMsgExtra extra : list) {
|
||
if (iUploadMsgExtraListener != null) {
|
||
iUploadMsgExtraListener.onUpload(extra);
|
||
}
|
||
}
|
||
} else {
|
||
checkMsgNeedUploadTimer.cancel();
|
||
checkMsgNeedUploadTimer.purge();
|
||
checkMsgNeedUploadTimer = null;
|
||
}
|
||
}
|
||
}, 1000 * 5, 1000 * 5);
|
||
}
|
||
|
||
private void setUploadMsgExtra(WKMsgExtra extra) {
|
||
if (iUploadMsgExtraListener != null) {
|
||
iUploadMsgExtraListener.onUpload(extra);
|
||
}
|
||
startCheckTimer();
|
||
}
|
||
|
||
public void addOnUploadMsgExtraListener(IUploadMsgExtraListener iUploadMsgExtraListener) {
|
||
this.iUploadMsgExtraListener = iUploadMsgExtraListener;
|
||
}
|
||
|
||
public void pushNewMsg(List<WKMsg> wkMsgList) {
|
||
if (newMsgListenerMap != null && !newMsgListenerMap.isEmpty()) {
|
||
runOnMainThread(() -> {
|
||
for (Map.Entry<String, INewMsgListener> entry : newMsgListenerMap.entrySet()) {
|
||
entry.getValue().newMsg(wkMsgList);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* push新消息
|
||
*
|
||
* @param msg 消息
|
||
*/
|
||
public void pushNewMsg(WKMsg msg) {
|
||
if (msg == null) return;
|
||
List<WKMsg> msgs = new ArrayList<>();
|
||
msgs.add(msg);
|
||
pushNewMsg(msgs);
|
||
}
|
||
|
||
/**
|
||
* Deprecated 后续版本将会移除
|
||
*
|
||
* @param messageContent 消息体
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道类型
|
||
*/
|
||
@Deprecated
|
||
public void sendMessage(WKMessageContent messageContent, String channelID, byte channelType) {
|
||
send(messageContent, new WKChannel(channelID, channelType));
|
||
}
|
||
|
||
/**
|
||
* Deprecated 后续版本将会移除
|
||
*
|
||
* @param messageContent 消息体
|
||
* @param setting 消息设置
|
||
* @param channelID 频道ID
|
||
* @param channelType 频道类型
|
||
*/
|
||
@Deprecated
|
||
public void sendMessage(WKMessageContent messageContent, WKMsgSetting setting, String channelID, byte channelType) {
|
||
WKSendOptions options = new WKSendOptions();
|
||
options.setting = setting;
|
||
WKChannel channel = WKIM.getInstance().getChannelManager().getChannel(channelID, channelType);
|
||
if (channel == null) {
|
||
channel = new WKChannel(channelID, channelType);
|
||
}
|
||
sendWithOptions(messageContent, channel, options);
|
||
}
|
||
|
||
/**
|
||
* 发送消息
|
||
*
|
||
* @param msg 消息对象
|
||
*/
|
||
public void sendMessage(@NonNull WKMsg msg) {
|
||
WKConnection.getInstance().sendMessage(msg);
|
||
}
|
||
|
||
/**
|
||
* 发送消息
|
||
*
|
||
* @param contentModel 消息体
|
||
* @param channel 频道
|
||
*/
|
||
public void send(@NonNull WKMessageContent contentModel, @NonNull WKChannel channel) {
|
||
sendWithOptions(contentModel, channel, new WKSendOptions());
|
||
}
|
||
|
||
/**
|
||
* 发送消息
|
||
*
|
||
* @param contentModel 消息体
|
||
* @param channel 频道
|
||
* @param options 高级设置
|
||
*/
|
||
public void sendWithOptions(@NonNull WKMessageContent contentModel, @NonNull WKChannel channel, @NonNull WKSendOptions options) {
|
||
final WKMsg wkMsg = new WKMsg();
|
||
wkMsg.type = contentModel.type;
|
||
wkMsg.channelID = channel.channelID;
|
||
wkMsg.channelType = channel.channelType;
|
||
wkMsg.baseContentMsgModel = contentModel;
|
||
wkMsg.flame = options.flame;
|
||
wkMsg.flameSecond = options.flameSecond;
|
||
wkMsg.expireTime = options.expire;
|
||
if (!TextUtils.isEmpty(options.topicID)) {
|
||
wkMsg.topicID = options.topicID;
|
||
}
|
||
if (!TextUtils.isEmpty(options.robotID)) {
|
||
wkMsg.robotID = options.robotID;
|
||
}
|
||
wkMsg.setting = options.setting;
|
||
wkMsg.header = options.header;
|
||
sendMessage(wkMsg);
|
||
}
|
||
|
||
public String createClientMsgNO() {
|
||
String deviceId = WKIM.getInstance().getDeviceID();
|
||
if (TextUtils.isEmpty(deviceId)) {
|
||
deviceId = "unknown";
|
||
}
|
||
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
|
||
return uuid + "_" + deviceId + "_1";
|
||
}
|
||
}
|