/* * Copyright (c) 2013 The CCP project authors. All Rights Reserved. * * Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license * that can be found in the LICENSE file in the root of the web site. * * http://www.yuntongxun.com * * An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ package nobugs.team.shopping.im; import android.util.Log; import com.google.gson.Gson; import com.yuntongxun.ecsdk.ECChatManager; import com.yuntongxun.ecsdk.ECDevice; import com.yuntongxun.ecsdk.ECError; import com.yuntongxun.ecsdk.ECMessage; import com.yuntongxun.ecsdk.OnChatReceiveListener; import com.yuntongxun.ecsdk.im.ECTextMessageBody; import com.yuntongxun.ecsdk.im.group.ECGroupNoticeMessage; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.List; import de.greenrobot.event.EventBus; import nobugs.team.shopping.event.IMEvent; import nobugs.team.shopping.event.RemoteOrderAddEvent; import nobugs.team.shopping.event.RemoteOrderDelEvent; import nobugs.team.shopping.event.RemoteShopSelectEvent; import nobugs.team.shopping.event.RemoteShoppingCartSubmitEvent; import nobugs.team.shopping.im.entity.IMAddOrder; import nobugs.team.shopping.im.entity.IMBase; import nobugs.team.shopping.im.entity.IMDelOrder; import nobugs.team.shopping.im.entity.IMSelectShop; import nobugs.team.shopping.im.entity.IMShoppingCartCommit; import nobugs.team.shopping.mvp.model.Order; import nobugs.team.shopping.mvp.model.Shop; import nobugs.team.shopping.mvp.model.User; import nobugs.team.shopping.repo.mapper.OrderMapper; import nobugs.team.shopping.repo.mapper.UserMapper; import nobugs.team.shopping.utils.CCPHelper; /** * @author Jorstin Chan@容联•云通讯 * @version 4.0 * @date 2014-12-12 */ public class IMChattingHelper implements OnChatReceiveListener /*, ECChatManager.OnDownloadMessageListener*/ { private static final String TAG = "ECSDK.IMChatHelper"; public static final String INTENT_ACTION_SYNC_MESSAGE = "com.yuntongxun.ecdemo_sync_message"; public static final String GROUP_PRIVATE_TAG = "@priategroup.com"; private static HashMap<String, SyncMsgEntry> syncMessage = new HashMap<>(); private static IMChattingHelper sInstance; private boolean isSyncOffline = false; public static IMChattingHelper getInstance() { if (sInstance == null) { sInstance = new IMChattingHelper(); } return sInstance; } /** * 云通讯SDK聊天功能接口 */ private ECChatManager mChatManager; /** * 全局处理所有的IM消息发送回调 */ // private ChatManagerListener mListener; /** * 是否是同步消息 */ private boolean isFirstSync = false; private IMChattingHelper() { mChatManager = CCPHelper.getECChatManager(); // mListener = new ChatManagerListener(); } private ECChatManager getChatManager() { if (mChatManager == null) { mChatManager = CCPHelper.getECChatManager(); } return mChatManager; } /** * 消息发送报告 */ public interface OnMessageReportCallback { void onMessageReport(ECError error, ECMessage message); void onPushMessage(String sessionId, List<ECMessage> msgs); } private OnMessageReportCallback mOnMessageReportCallback; public static void setOnMessageReportCallback(OnMessageReportCallback callback) { getInstance().mOnMessageReportCallback = callback; } /** * 发送Text 消息 * * @param from * @param to * @param txt * @param listener */ public static void sendECMessage(String from, String to, String txt, ECChatManager.OnSendMessageListener listener) { // 组建一个待发送的ECMessage ECMessage msg = ECMessage.createECMessage(ECMessage.Type.TXT); //设置消息的属性:发出者,接受者,发送时间等 msg.setForm(from); msg.setMsgTime(System.currentTimeMillis()); // 设置消息接收者 msg.setTo(to); msg.setSessionId(to); // 设置消息发送类型(发送或者接收) msg.setDirection(ECMessage.Direction.SEND); // 创建一个文本消息体,并添加到消息对象中 ECTextMessageBody msgBody = new ECTextMessageBody(txt); // 将消息体存放到ECMessage中 msg.setBody(msgBody); sendECMessage(msg, listener); } /** * 发送ECMessage 消息 * * @param msg */ public static void sendECMessage(ECMessage msg, ECChatManager.OnSendMessageListener listener) { // 获取一个聊天管理器 ECChatManager manager = getInstance().getChatManager(); if (manager != null) { // 调用接口发送IM消息 manager.sendMessage(msg, listener); // 保存发送的消息到数据库 } else { msg.setMsgStatus(ECMessage.MessageStatus.FAILED); } // return IMessageSqlManager.insertIMessage(msg, ECMessage.Direction.SEND.ordinal()); } public void destory() { if (syncMessage != null) { syncMessage.clear(); } // mListener = null; mChatManager = null; isFirstSync = false; sInstance = null; } /** * 消息重发 * * @return */ // public static long reSendECMessage(ECMessage msg) { // ECChatManager manager = getInstance().mChatManager; // if(manager != null) { // // 调用接口发送IM消息 // String oldMsgId = msg.getMsgId(); // manager.sendMessage(msg, getInstance().mListener); // if(msg.getType() == ECMessage.Type.IMAGE) { // ImgInfo imgInfo = ImgInfoSqlManager.getInstance().getImgInfo(oldMsgId); // if(imgInfo == null || TextUtils.isEmpty(imgInfo.getBigImgPath())) { // return -1; // } // String bigImagePath = new File(FileAccessor.getImagePathName(), imgInfo.getBigImgPath()).getAbsolutePath(); // imgInfo.setMsglocalid(msg.getMsgId()); // ECFileMessageBody body = (ECFileMessageBody) msg.getBody(); // body.setLocalUrl(bigImagePath); // BitmapFactory.Options options = DemoUtils.getBitmapOptions(new File(FileAccessor.IMESSAGE_IMAGE, imgInfo.getThumbImgPath()).getAbsolutePath()); // msg.setUserData("outWidth://" + options.outWidth + ",outHeight://" + options.outHeight + ",THUMBNAIL://" + msg.getMsgId()); // ImgInfoSqlManager.getInstance().updateImageInfo(imgInfo); // } // // 保存发送的消息到数据库 // return IMessageSqlManager.changeResendMsg(msg.getId(), msg); // } // return -1; // } // public static long sendImageMessage(ImgInfo imgInfo , ECMessage message) { // // ECChatManager manager = getInstance().mChatManager; // if(manager != null) { // // 调用接口发送IM消息 // manager.sendMessage(message, getInstance().mListener); // // if(TextUtils.isEmpty(message.getMsgId())) { // return -1; // } // imgInfo.setMsglocalid(message.getMsgId()); // BitmapFactory.Options options = DemoUtils.getBitmapOptions(new File(FileAccessor.IMESSAGE_IMAGE, imgInfo.getThumbImgPath()).getAbsolutePath()); // message.setUserData("outWidth://" + options.outWidth + ",outHeight://" + options.outHeight + ",THUMBNAIL://" + message.getMsgId() + ",PICGIF://" + imgInfo.isGif); // long row = IMessageSqlManager.insertIMessage(message, ECMessage.Direction.SEND.ordinal()); // if(row != -1) { // return ImgInfoSqlManager.getInstance().insertImageInfo(imgInfo); // } // } // return -1; // } // public void getPersonInfo() { // LogUtil.d(TAG , "[getPersonInfo] currentVersion :"); // final ClientUser clientUser = CCPAppManager.getClientUser(); // if(clientUser == null) { // return ; // } // LogUtil.d(TAG , "[getPersonInfo] currentVersion :" + clientUser.getpVersion() + " ,ServerVersion: " + mServicePersonVersion); // if(clientUser.getpVersion() < mServicePersonVersion) { // SDKCoreHelper.getECChatManager().getPersonInfo(new ECChatManager.OnGetPersonInfoListener() { // @Override // public void onGetPersonInfoComplete(ECError e, PersonInfo p) { // if(e.errorCode == SdkErrorCode.REQUEST_SUCCESS // && p != null) { // clientUser.setpVersion(p.getVersion()); // clientUser.setSex(p.getSex().ordinal() + 1); // clientUser.setUserName(p.getNickName()); // clientUser.setSignature(p.getSign()); // if(!TextUtils.isEmpty(p.getBirth())){ // clientUser.setBirth(DateUtil.getActiveTimelong(p.getBirth())); // } // String newVersion = clientUser.toString(); // LogUtil.d(TAG , "[getPersonInfo -result] ClientUser :" + newVersion); // try { // ECPreferences.savePreference(ECPreferenceSettings.SETTINGS_REGIST_AUTO, newVersion, true); // } catch (InvalidClassException e1) { // e1.printStackTrace(); // } // } // // } // }); // } // } /** * ----------- 发送回调--------------- */ // @Override // public void onSendMessageComplete(ECError error, ECMessage message) { // if (message == null) { // return; // } // // 处理ECMessage的发送状态 // if (message != null) { // if (message.getType() == ECMessage.Type.VOICE) { // // DemoUtils.playNotifycationMusic(CCPAppManager.getContext(), "sound/voice_message_sent.mp3"); // } //// IMessageSqlManager.setIMessageSendStatus(message.getMsgId(), message.getMsgStatus().ordinal()); //// IMessageSqlManager.notifyMsgChanged(message.getSessionId()); // if (mOnMessageReportCallback != null) { // mOnMessageReportCallback.onMessageReport(error, message); // } // return; // } // } // // @Override // public void onProgress(String msgId, int total, int progress) { // // 处理发送文件IM消息的时候进度回调 // Log.d(TAG, "[IMChattingHelper - onProgress] msgId:" + msgId + " ,total:" + total + " ,progress:" + progress); // } // private int getMaxVersion() { // int maxVersion = IMessageSqlManager.getMaxVersion(); // int maxVersion1 = GroupNoticeSqlManager.getMaxVersio(); // return maxVersion > maxVersion1 ? maxVersion : maxVersion1; // } /** * ----------- OnChatReceiveListener 回调,在param中注册--------------- */ /** * 收到新的IM文本和附件消息 */ @Override public void OnReceivedMessage(ECMessage msg) { Log.d(TAG, "[OnReceivedMessage] show notice true"); if (msg == null) { return; } // postReceiveMessage(msg, true); EventBus.getDefault().post(new IMEvent(msg)); handleReceiveMessage(msg); } public void handleReceiveMessage(ECMessage msg) { if (msg.getType() == ECMessage.Type.TXT) { ECTextMessageBody body = (ECTextMessageBody) msg.getBody(); String txt = body.getMessage(); try { Gson gson = new Gson(); JSONObject jsonObject = new JSONObject(txt); String type = jsonObject.getString("type"); switch (type){ case IMBase.TYPE_SELECT_SHOP: final IMSelectShop imshop = gson.fromJson(txt, IMSelectShop.class); Shop shop = new Shop(); shop.setId(imshop.getShopId()); User user = new UserMapper().toModel(imshop.getBuyer()); EventBus.getDefault().postSticky(new RemoteShopSelectEvent(shop, user)); break; case IMBase.TYPE_ADD_ORDER: final IMAddOrder imAddOrder = gson.fromJson(txt, IMAddOrder.class); Order orderAdd = new OrderMapper().toModel(imAddOrder.getOrder()); EventBus.getDefault().postSticky(new RemoteOrderAddEvent(orderAdd, msg)); break; case IMBase.TYPE_DEL_ORDER: final IMDelOrder imDelOrder = gson.fromJson(txt, IMDelOrder.class); EventBus.getDefault().postSticky(new RemoteOrderDelEvent(imDelOrder.getOrderId(), msg)); break; case IMBase.TYPE_SHOPPING_CART_COMMIT: final IMShoppingCartCommit imShoppingCartCommit = gson.fromJson(txt, IMShoppingCartCommit.class); EventBus.getDefault().postSticky(new RemoteShoppingCartSubmitEvent(imShoppingCartCommit.getProductTotal(), imShoppingCartCommit.getPriceTotal(), msg)); break; } } catch (JSONException e) { e.printStackTrace(); } } } /** * 处理接收消息 * * @param msg * @param showNotice */ // private synchronized void postReceiveMessage(ECMessage msg, boolean showNotice) { // 接收到的IM消息,根据IM消息类型做不同的处理 // IM消息类型:ECMessage.Type // if (msg.getType() != ECMessage.Type.TXT) { // ECFileMessageBody body = (ECFileMessageBody) msg.getBody(); // FileAccessor.initFileAccess(); // if(!TextUtils.isEmpty(body.getRemoteUrl())) { // boolean thumbnail = false; // String fileExt = DemoUtils.getExtensionName(body.getRemoteUrl()); // if(msg.getType() == ECMessage.Type.VOICE) { // body.setLocalUrl(new File(FileAccessor.getVoicePathName(), DemoUtils.md5(String.valueOf(System.currentTimeMillis())) + ".amr").getAbsolutePath()); // } else if (msg.getType() == ECMessage.Type.IMAGE) { // ECImageMessageBody imageBody = (ECImageMessageBody) body; // thumbnail = !TextUtils.isEmpty(imageBody.getThumbnailFileUrl()); // imageBody.setLocalUrl(new File(FileAccessor.getImagePathName() , DemoUtils.md5(thumbnail ? imageBody.getThumbnailFileUrl() :imageBody.getRemoteUrl()) + "." + fileExt).getAbsolutePath()); // } else { // body.setLocalUrl(new File(FileAccessor.getFilePathName() , DemoUtils.md5(String.valueOf(System.currentTimeMillis())) + "." + fileExt).getAbsolutePath()); // // } // if(syncMessage != null) { // syncMessage.put(msg.getMsgId(), new SyncMsgEntry(showNotice,thumbnail, msg)); // } // if(mChatManager != null) { // if(thumbnail) { // mChatManager.downloadThumbnailMessage(msg, this); // } else { // mChatManager.downloadMediaMessage(msg, this); // } // } // if(TextUtils.isEmpty(body.getFileName()) && !TextUtils.isEmpty(body.getRemoteUrl())) { // body.setFileName(FileAccessor.getFileName(body.getRemoteUrl())); // } // msg.setUserData("fileName=" + body.getFileName()); // if(IMessageSqlManager.insertIMessage(msg, msg.getDirection().ordinal()) > 0) { // return ; // } // } else { // Log.e(TAG, "ECMessage fileUrl: null"); // } // } // if(IMessageSqlManager.insertIMessage(msg, msg.getDirection().ordinal()) <= 0) { // return ; // } // if (mOnMessageReportCallback != null) { // ArrayList<ECMessage> msgs = new ArrayList<ECMessage>(); // msgs.add(msg); // mOnMessageReportCallback.onPushMessage(msg.getSessionId(), msgs); // } // 是否状态栏提示 // if(showNotice) showNotification(msg); // } // private static void showNotification(ECMessage msg) { // if(checkNeedNotification(msg.getSessionId())) { // ECNotificationManager.getInstance().forceCancelNotification(); // String lastMsg = ""; // if(msg.getType() == ECMessage.Type.TXT) { // lastMsg = ((ECTextMessageBody) msg.getBody()).getMessage(); // } // ECContacts contact = ContactSqlManager.getContact(msg.getForm()); // if(contact == null) { // return ; // } // ECNotificationManager.getInstance().showCustomNewMessageNotification(CCPAppManager.getContext(), // lastMsg, // contact.getNickname(), // msg.getSessionId(), // msg.getType().ordinal()); // } // } // public static void checkDownFailMsg() { // getInstance().postCheckDownFailMsg(); // } // private void postCheckDownFailMsg() { // List<ECMessage> downdFailMsg = IMessageSqlManager.getDowndFailMsg(); // if(downdFailMsg == null || downdFailMsg.isEmpty()) { // return ; // } // for(ECMessage msg : downdFailMsg) { // ECImageMessageBody body = (ECImageMessageBody) msg.getBody(); // body.setThumbnailFileUrl(body.getRemoteUrl() + "_thum"); // if(syncMessage != null) { // syncMessage.put(msg.getMsgId(), new SyncMsgEntry(false,true, msg)); // } // if(mChatManager != null) { // mChatManager.downloadThumbnailMessage(msg, this); // } // } // // } /** * 是否需要状态栏通知 */ // public static boolean checkNeedNotification(String contactId) { // String currentChattingContactId = ECPreferences.getSharedPreferences().getString( // ECPreferenceSettings.SETTING_CHATTING_CONTACTID.getId(), // (String) ECPreferenceSettings.SETTING_CHATTING_CONTACTID.getDefaultValue()); // if(contactId == null) { // return true; // } // // 当前聊天 // if(contactId.equals(currentChattingContactId)) { // return false; // } // //群组免打扰 // if(contactId.toUpperCase().startsWith("G")) { // return GroupSqlManager.isGroupNotify(contactId); // } // return true; // } @Override public void OnReceiveGroupNoticeMessage(ECGroupNoticeMessage notice) { if (notice == null) { return; } // // // 接收到的群组消息,根据群组消息类型做不同处理 // // 群组消息类型:ECGroupMessageType // GroupNoticeHelper.insertNoticeMessage(notice, new GroupNoticeHelper.OnPushGroupNoticeMessageListener() { // // @Override // public void onPushGroupNoticeMessage(DemoGroupNotice system) { // IMessageSqlManager.notifyMsgChanged(GroupNoticeSqlManager.CONTACT_ID); // // ECMessage msg = ECMessage.createECMessage(ECMessage.Type.TXT); // msg.setSessionId(system.getSender()); // msg.setForm(system.getSender()); // ECTextMessageBody tx = new ECTextMessageBody(system.getContent()); // msg.setBody(tx); // // 是否状态栏提示 // showNotification(msg); // } // }); } private int mHistoryMsgCount = 0; @Override public void onOfflineMessageCount(int count) { mHistoryMsgCount = count; } @Override public int onGetOfflineMessage() { // 获取全部的离线历史消息 return ECDevice.SYNC_OFFLINE_MSG_ALL; } private ECMessage mOfflineMsg = null; @Override public void onReceiveOfflineMessage(List<ECMessage> msgs) { // 离线消息的处理可以参考 void OnReceivedMessage(ECMessage msg)方法 // 处理逻辑完全一样 // 参考 IMChattingHelper.java Log.d(TAG, "[onReceiveOfflineMessage] show notice false"); // if(msgs != null && !msgs.isEmpty() && !isFirstSync)isFirstSync = true; // for(ECMessage msg : msgs) { // mOfflineMsg = msg; // postReceiveMessage(msg, false); // } } @Override public void onReceiveOfflineMessageCompletion() { if (mOfflineMsg == null) { return; } // SDK离线消息拉取完成之后会通过该接口通知应用 // 应用可以在此做类似于Loading框的关闭,Notification通知等等 // 如果已经没有需要同步消息的请求时候,则状态栏开始提醒 // ECMessage lastECMessage = mOfflineMsg; // try{ // if(lastECMessage != null && mHistoryMsgCount > 0 && isFirstSync) { // showNotification(lastECMessage); // lastECMessage.setSessionId(lastECMessage.getTo().startsWith("G")?lastECMessage.getTo():lastECMessage.getForm()); // } // } catch (Exception e) { // e.printStackTrace(); // } // isFirstSync = isSyncOffline = false; // 无需要同步的消息 // CCPAppManager.getContext().sendBroadcast(new Intent(INTENT_ACTION_SYNC_MESSAGE)); // mOfflineMsg = null; } public int mServicePersonVersion = 0; @Override public void onServicePersonVersion(int version) { mServicePersonVersion = version; } /** * 客服消息 * * @param msg */ @Override public void onReceiveDeskMessage(ECMessage msg) { Log.d(TAG, "[onReceiveDeskMessage] show notice true"); OnReceivedMessage(msg); } @Override public void onSoftVersion(String version, int sUpdateMode) { // SDKCoreHelper.setSoftUpdate(version , sUpdateMode); } public static boolean isSyncOffline() { return getInstance().isSyncOffline; } /** * 下载 */ // @Override // public void onDownloadMessageComplete(ECError e, ECMessage message) { // if(e.errorCode == SdkErrorCode.REQUEST_SUCCESS){ // if(message == null) return; // // 处理发送文件IM消息的时候进度回调 // LogUtil.d(TAG , "[onDownloadMessageComplete] msgId:" +message.getMsgId()); // postDowloadMessageResult(message); // } else { // // 重试下载3次 // SyncMsgEntry remove = syncMessage.remove(message.getMsgId()); // if(remove == null) { // return ; // } // LogUtil.d(TAG , "[onDownloadMessageComplete] download fail , retry :" +remove.retryCount); // retryDownload(remove); // } // } // @Override // public void onProgress(String msgId, int totalByte, int progressByte) { // // 处理发送文件IM消息的时候进度回调 // Log.d(TAG , "[IMChattingHelper - onProgress] msgId: " +msgId + " , totalByte: "+totalByte+" , progressByte:" + progressByte); // } // /** // * 重试下载3次 // * @param entry // */ // private void retryDownload(SyncMsgEntry entry) { // if(entry == null || entry.msg == null || entry.isRetryLimit()) { // return ; // } // entry.increase(); // // download .. // if(mChatManager != null) { // if(entry.thumbnail) { // mChatManager.downloadThumbnailMessage(entry.msg, this); // } else { // mChatManager.downloadMediaMessage(entry.msg, this); // } // } // syncMessage.put(entry.msg.getMsgId() , entry); // } // private synchronized void postDowloadMessageResult(ECMessage message) { // if(message == null) { // return ; // } // if(message.getType() == ECMessage.Type.VOICE) { // ECVoiceMessageBody voiceBody = (ECVoiceMessageBody) message.getBody(); // voiceBody.setDuration(DemoUtils.calculateVoiceTime(voiceBody.getLocalUrl())); // } else if (message.getType() == ECMessage.Type.IMAGE){ // ImgInfo thumbImgInfo = ImgInfoSqlManager.getInstance().getThumbImgInfo(message); // if(thumbImgInfo == null) { // return ; // } // ImgInfoSqlManager.getInstance().insertImageInfo(thumbImgInfo); // BitmapFactory.Options options = DemoUtils.getBitmapOptions(new File(FileAccessor.getImagePathName() , thumbImgInfo.getThumbImgPath()).getAbsolutePath()); // message.setUserData("outWidth://" + options.outWidth + ",outHeight://" + options.outHeight + ",THUMBNAIL://" + message.getMsgId() + ",PICGIF://" + thumbImgInfo.isGif); // } // if(IMessageSqlManager.updateIMessageDownload(message) <= 0) { // return ; // } // if(mOnMessageReportCallback != null) { // mOnMessageReportCallback.onMessageReport(null ,message); // } // boolean showNotice = true; // SyncMsgEntry remove = syncMessage.remove(message.getMsgId()); // if(remove != null) { // showNotice = remove.showNotice; // if(mOnMessageReportCallback != null && remove.msg != null) { // ArrayList<ECMessage> msgs = new ArrayList<ECMessage>(); // msgs.add(remove.msg); // mOnMessageReportCallback.onPushMessage(remove.msg.getSessionId() ,msgs); // } // } // if(showNotice)showNotification(message); // } public class SyncMsgEntry { // 是否是第一次初始化同步消息 boolean showNotice = false; boolean thumbnail = false; // 重试下载次数 private int retryCount = 1; ECMessage msg; public SyncMsgEntry(boolean showNotice, boolean thumbnail, ECMessage message) { this.showNotice = showNotice; this.msg = message; this.thumbnail = thumbnail; } public void increase() { retryCount++; } public boolean isRetryLimit() { return retryCount >= 3; } } }