Android实现聊天记录上传本地服务器(即时通讯)
即时通讯功能,使用SDK里封装的方法,获取聊天记录,接口请求成功,但获取不到数据。使用本地的服务器保存聊天记录,实现方法如下:
1. ChatFragment.java中请求聊天记录:
public class ChatFragment extends EaseChatFragment implements EaseChatFragmentHelper { @Override protected void setUpView() { setChatFragmentHelper(this); String userName = DemoHelper.getInstance().getCurrentUsernName(); conversation = EMClient.getInstance().chatManager().getConversation(toChatUsername, EaseCommonUtils.getConversationType(chatType), true); Log.e(TAG,"conversation.getAllMsgCount()="+conversation.getAllMsgCount()); if (conversation.getAllMsgCount() != 0 && conversation.getAllMsgCount() != 1) { setLisener(); } else { conversation.clearAllMessages(); conversation.clear(); showWaitDialog("数据加载中……").show(); getHistoryMsg(userName,toChatUsername); } } private void setLisener() { if (chatType == Constant.CHATTYPE_SINGLE) { Map<String, RobotUser> robotMap = DemoHelper.getInstance().getRobotList(); if(robotMap!=null && robotMap.containsKey(toChatUsername)){ isRobot = true; } } super.setUpView(); …… setOnRefresh1Listener(new OnRefresh1Listener() { @Override public boolean refresh(int page) { pageNo = page; getHistoryMsg(DemoHelper.getInstance().getCurrentUsernName(),toChatUsername); return false; } }); } List<EMMessage> emMessages = new ArrayList<>(); List<RemoteMessage> remoteMessages = new ArrayList<>(); int pageNo = 1; private void getHistoryMsg(String sendUser, String receiveUser) { HashMap<String, Object> baseParam = new HashMap<>(4); baseParam.put("pageNo",pageNo); baseParam.put("pageSize",10); if (chatType == EaseConstant.CHATTYPE_GROUP) { baseParam.put("sendUser",receiveUser); baseParam.put("receiveUser",receiveUser); } else { baseParam.put("sendUser",sendUser); baseParam.put("receiveUser",receiveUser); } OkHttpUtil.post(TAG, WebApi.MSN_CHAT_LIST, baseParam, new StringCallback() { @Override public void onError(Call call, Exception e, int id) { Log.e(TAG,"getHistoryMsg e="+ e); } @Override public void onResponse(String response, int id) { Log.e(TAG,"getHistoryMsg response="+ response); try { JSONObject object = new JSONObject(response); if (object.getInt("code") == 200) { JSONObject object1 = object.getJSONObject("data"); Gson gson = new Gson(); if (pageNo == 1) { remoteMessages.clear(); } ListPageBean listPageBean = gson.fromJson(object1.toString(),ListPageBean.class); if (listPageBean.isLastPage()) { isLastPage = true; } else { isLastPage = false; } JSONArray array = object1.getJSONArray("list"); for (int i = 0;i<array.length();i++) { RemoteMessage remoteMessage = gson.fromJson(array.get(i).toString(),RemoteMessage.class); convertMsg(remoteMessage); } Log.e(TAG,"emMessages.size()="+emMessages.size()); //下拉加载 if (emMessages.size()< 10) { haveMoreData = false; } else { haveMoreData = true; } importDataBase(emMessages); } } catch (JSONException e) { e.printStackTrace(); hideWaitDialog(); } } }); } /* * 将从接口获取的数据转换成EMMessage对象 * */ private void convertMsg(RemoteMessage remoteMessage) { EMMessage message = null; Log.e(TAG,"getHistoryMsg Message="+ remoteMessage.getMessage()+","+remoteMessage.getSendTime()+","+remoteMessage.getCreateDate()); if (remoteMessage.getMesType().equals("1")) { message = EMMessage.createTxtSendMessage(remoteMessage.getMessage(), remoteMessage.getReceiveUser()); } else if (remoteMessage.getMesType().equals("2")) { message = EMMessageUtils.createLocationMsg(remoteMessage); } else if (remoteMessage.getMesType().equals("3")) {//语音 message = createVoiceMsg(remoteMessage); } else if (remoteMessage.getMesType().equals("4")) {//视频 message = EMMessageUtils.createVideoMsg(remoteMessage); getFile(message,remoteMessage.getMesType(),remoteMessage.getFileUrl(),((EMVideoMessageBody)message.getBody()).getFileName()); } else if (remoteMessage.getMesType().equals("5")) {//图片 message = createImageMsg(remoteMessage); } else if (remoteMessage.getMesType().equals("6")) {//文件 message = createFileMsg(remoteMessage); } else if (remoteMessage.getMesType().equals("7")) {//语音 message = EMMessage.createTxtSendMessage(remoteMessage.getMessage(), remoteMessage.getReceiveUser()); message.setAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL,true); } else if (remoteMessage.getMesType().equals("8")) {//视频电话 message = EMMessage.createTxtSendMessage(remoteMessage.getMessage(), remoteMessage.getReceiveUser()); message.setAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL,true); } else if (remoteMessage.getMesType().equals("9")) { message = EMMessage.createTxtSendMessage(remoteMessage.getMessage(), remoteMessage.getReceiveUser()); message.setAttribute("is_office",true); } if (remoteMessage.getSendUser().equals(DemoHelper.getInstance().getCurrentUsernName())) { message.setDirection(EMMessage.Direct.SEND); } else { message.setDirection(EMMessage.Direct.RECEIVE); } if (remoteMessage.getReceiveType().equals("0")) { message.setChatType(EMMessage.ChatType.Chat); } else { message.setChatType(EMMessage.ChatType.GroupChat); } // message.setChatType(EMMessage.ChatType.Chat); message.setFrom(remoteMessage.getSendUser()); message.setMsgId(remoteMessage.getMsgId()); message.setMsgTime(Long.valueOf(remoteMessage.getSendTime())); message.setStatus(EMMessage.Status.SUCCESS); conversation.insertMessage(message); // updateMsg(message); emMessages.add(message); } private EMMessage createFileMsg(RemoteMessage remoteMessage) { EMMessage message = null; String msgStr = remoteMessage.getMessage(); String[] msgArr = msgStr.split(","); String localurl=""; for (int j=0;j<msgArr.length;j++) { String[] lat = msgArr[j].split(":"); if (lat[0].contains("localUrl")) { localurl = lat[1].trim(); } } message = EMMessageUtils.createFileSendMessage(remoteMessage.getSendUser(),localurl, remoteMessage.getReceiveUser()); getFile(message,remoteMessage.getMesType(),remoteMessage.getFileUrl(),((EMFileMessageBody)message.getBody()).getFileName()); ((EMFileMessageBody)message.getBody()).setRemoteUrl(remoteMessage.getFileUrl()); return message; } private EMMessage createImageMsg(RemoteMessage remoteMessage) { EMMessage message = null; String msgStr = remoteMessage.getMessage(); String[] msgArr = msgStr.split(","); String localurl=""; for (int j=0;j<msgArr.length;j++) { String[] lat = msgArr[j].split(":"); if (lat[0].contains("localurl")) { localurl = lat[1].trim(); } } message = EMMessageUtils.createImageSendMessage(remoteMessage.getSendUser(),localurl, false, remoteMessage.getReceiveUser()); getFile(message,remoteMessage.getMesType(),remoteMessage.getFileUrl(),((EMImageMessageBody)message.getBody()).getFileName()); ((EMImageMessageBody)message.getBody()).setRemoteUrl(remoteMessage.getFileUrl()); return message; } private EMMessage createVoiceMsg(RemoteMessage remoteMessage) { EMMessage message = null; int size = 0; if (!StringUtils.isEmpty(remoteMessage.getSize())) { size = Integer.valueOf(remoteMessage.getSize()); } String msgStr = remoteMessage.getMessage(); String[] msgArr = msgStr.split(","); String localurl=""; for (int j=0;j<msgArr.length;j++) { String[] lat = msgArr[j].split(":"); if (lat[0].contains("localurl")) { localurl = lat[1].trim(); } } message = EMMessageUtils.createVoiceSendMessage(localurl, size, remoteMessage.getReceiveUser()); ((EMVoiceMessageBody)message.getBody()).setRemoteUrl(remoteMessage.getFileUrl()); getFile(message,remoteMessage.getMesType(),remoteMessage.getFileUrl(),((EMVoiceMessageBody)message.getBody()).getFileName()); return message; } /* * 下载文件 * */ HttpURLConnection con; private void downLoad(EMMessage emMessage,String type,String path, String fileName) { try { URL url = new URL(path); con = (HttpURLConnection) url.openConnection(); con.setReadTimeout(5000); con.setConnectTimeout(5000); con.setRequestProperty("Charset", "UTF-8"); con.setRequestMethod("GET"); if (con.getResponseCode() == 200) { InputStream is = con.getInputStream();//获取输入流 FileOutputStream fileOutputStream = null;//文件输出流 if (is != null) { String toUser = ""; if (emMessage.direct() == EMMessage.Direct.RECEIVE) { toUser = emMessage.getFrom(); } File file = FileLoadUtils.createFileEm(type,fileName,toUser); fileOutputStream = new FileOutputStream(file);//指定文件保存路径,代码看下一步 byte[] buf = new byte[1024]; int ch; while ((ch = is.read(buf)) != -1) { fileOutputStream.write(buf, 0, ch);//将获取到的流写入文件中 } } if (fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } if (type.equals("4")) { String thum = FileLoadUtils.getThumnailPath(emMessage.getFrom(),((EMVideoMessageBody)emMessage.getBody()).getLocalUrl()); Log.e(TAG,"downLoad thum="+thum); ((EMVideoMessageBody)emMessage.getBody()).setLocalThumb(thum); } Log.d(TAG,"下载成功"); // getActivity().runOnUiThread(new Runnable() { // @Override // public void run() { // Toast.makeText(getActivity(),"下载成功"+fileName,Toast.LENGTH_SHORT).show(); // } // }); } else { Log.d(TAG,"下载失败"); // getActivity().runOnUiThread(new Runnable() { // @Override // public void run() { // Toast.makeText(getActivity(),"下载失败",Toast.LENGTH_SHORT).show(); // } // }); } } catch (Exception e) { e.printStackTrace(); }finally { //最后将conn断开连接 if (con != null) { con.disconnect(); con = null; } } } private void getFile(EMMessage message,String type,String path, String fileName) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { downLoad(message,type,path,fileName); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); Log.e(TAG,"getFile"+result); } }.execute(); } /* * 将数据导入数据库 * */ private void importDataBase(List<EMMessage> messages) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { EMClient.getInstance().chatManager().importMessages(emMessages); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); handler.postDelayed(new Runnable() { @Override public void run() { setLisener(); hideWaitDialog(); } },3000); Log.e(TAG,"importMessages"+result); } }.execute(); } /* * 附加功能,语音电话和视频电话 * 增加了发送企业名片的功能 * */ @Override protected void registerExtendMenuItem() { //use the menu in base class super.registerExtendMenuItem(); //extend menu items inputMenu.registerExtendMenuItem(R.string.attach_video, R.drawable.em_chat_video_selector, ITEM_VIDEO, extendMenuItemClickListener); inputMenu.registerExtendMenuItem(R.string.attach_file, R.drawable.em_chat_file_selector, ITEM_FILE, extendMenuItemClickListener); if(chatType == Constant.CHATTYPE_SINGLE){ inputMenu.registerExtendMenuItem(R.string.attach_voice_call, R.drawable.em_chat_voice_call_selector, ITEM_VOICE_CALL, extendMenuItemClickListener); inputMenu.registerExtendMenuItem(R.string.attach_video_call, R.drawable.em_chat_video_call_selector, ITEM_VIDEO_CALL, extendMenuItemClickListener); inputMenu.registerExtendMenuItem("企业名片", R.drawable.em_chat_video_call_selector, ITEM_OFFICE_CARD, extendMenuItemClickListener); } else if (chatType == Constant.CHATTYPE_GROUP) { // 音视频会议 inputMenu.registerExtendMenuItem(R.string.voice_and_video_conference, R.drawable.em_chat_video_call_selector, ITEM_CONFERENCE_CALL, extendMenuItemClickListener); // inputMenu.registerExtendMenuItem(R.string.title_live, R.drawable.em_chat_video_call_selector, ITEM_LIVE, extendMenuItemClickListener); } } /* * 点击附加功能 * * */ @Override public boolean onExtendMenuItemClick(int itemId, View view) { switch (itemId) { case ITEM_VIDEO: Log.e(TAG,"onExtendMenuItemClick ITEM_VIDEO"); Intent intent = new Intent(getActivity(), ImageGridActivity.class); startActivityForResult(intent, REQUEST_CODE_SELECT_VIDEO); break; …… case ITEM_OFFICE_CARD: Log.e(TAG,"onExtendMenuItemClick ITEM_OFFICE_CARD"); startOfficeCard(); break; default: break; } //keep exist extend menu return false; } /* * 获取企业详情 * 增加了发送企业名片的功能 * */ private void startOfficeCard() { HashMap<String, Object> baseParam = WebFrontUtil.getBaseParam(); baseParam.put("id", SavePreferences.getString(Const.OFFICE_ID)); OkHttpUtil.post(TAG, WebApi.PUNISH_OFFICE_DETAIL, baseParam, new StringCallback() { @Override public void onError(Call call, Exception e, int id) { Log.e(TAG,"startOfficeCard e="+e); } @Override public void onResponse(String response, int id) { Log.e(TAG,"startOfficeCard response="+response); try { JSONObject object = new JSONObject(response); Gson gson = new Gson(); if ((int)object.get("code") == 200) { JSONObject object1 = object.getJSONObject("data"); OfficeBean officeBean = gson.fromJson(object1.toString(),OfficeBean.class); String content = "officeId:"+officeBean.getId()+",公司名称:"+officeBean.getName()+",地址:"+officeBean.getAddr()+",联系电话:"+officeBean.getOfficeTel(); EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername); message.setAttribute("is_office",true); sendMessage(message); } } catch (JSONException e) { e.printStackTrace(); } } }); } /** * chat row provider * 发送企业名片时,修改过此处,否则还是文本格式 * */ private final class CustomChatRowProvider implements EaseCustomChatRowProvider { @Override public int getCustomChatRowTypeCount() { //here the number is the message type in EMMessage::Type //which is used to count the number of different chat row return 14; } @Override public int getCustomChatRowType(EMMessage message) { if(message.getType() == EMMessage.Type.TXT){ //voice call if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)){ return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE_CALL : MESSAGE_TYPE_SENT_VOICE_CALL; }else if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)){ //video call return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO_CALL : MESSAGE_TYPE_SENT_VIDEO_CALL; } //messagee recall else if(message.getBooleanAttribute(Constant.MESSAGE_TYPE_RECALL, false)){ return MESSAGE_TYPE_RECALL; } else if (!"".equals(message.getStringAttribute(Constant.MSG_ATTR_CONF_ID,""))) { return MESSAGE_TYPE_CONFERENCE_INVITE; } else if (Constant.OP_INVITE.equals(message.getStringAttribute(Constant.EM_CONFERENCE_OP, ""))) { return MESSAGE_TYPE_LIVE_INVITE; }else if (message.getBooleanAttribute("is_office",false)) { return message.direct() == EMMessage.Direct.RECEIVE? MESSAGE_TYPE_RECV_CARD: MESSAGE_TYPE_SEND_CARD; } } return 0; } @Override @Override public EaseChatRowPresenter getCustomChatRow(EMMessage message, int position, BaseAdapter adapter) { if(message.getType() == EMMessage.Type.TXT){ // voice call or video call if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) || message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)){ EaseChatRowPresenter presenter = new EaseChatVoiceCallPresenter(); return presenter; } if (message.getBooleanAttribute("is_office",false)) { Log.e(TAG,"getCustomChatRow is_office"); EaseChatRowPresenter presenter = new EaseChatCardPresenter(); return presenter; } //recall message else if(message.getBooleanAttribute(Constant.MESSAGE_TYPE_RECALL, false)){ EaseChatRowPresenter presenter = new EaseChatRecallPresenter(); return presenter; } else if (!"".equals(message.getStringAttribute(Constant.MSG_ATTR_CONF_ID,""))) { return new ChatRowConferenceInvitePresenter(); } else if (Constant.OP_INVITE.equals(message.getStringAttribute(Constant.EM_CONFERENCE_OP, ""))) { return new ChatRowLivePresenter(); } } return null; } } private Dialog mWaitDialog; public Dialog showWaitDialog(String text) { if (mWaitDialog == null) { mWaitDialog = DialogManager.getWaitDialog(getActivity(), text); } if (mWaitDialog != null) { TextView textView = mWaitDialog.findViewById(R.id.tv_message); textView.setText(text); mWaitDialog.show(); } return mWaitDialog; } public void hideWaitDialog() { try { if (mWaitDialog != null) { mWaitDialog.dismiss(); } mWaitDialog = null; } catch (Exception ex) { ex.printStackTrace(); } } }
2. EaseChatFragment.java: 发送消息,加载更多,定义了发送接口,以便activity页面调用;
public class EaseChatFragment extends EaseBaseFragment implements EMMessageListener { …… …… protected void setRefreshLayoutListener() { swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { handler.postDelayed(new Runnable() { @Override public void run() { if (!isRoaming) { loadMoreLocalMessage(); } else { loadMoreRoamingMessages(); } } }, 600); } }); } /** * 加载更多,haveMoreData的变化 */ private void loadMoreLocalMessage() { Log.e(TAG,"loadMoreLocalMessage isloading="+isloading+",haveMoreData="+haveMoreData+","+listView.getFirstVisiblePosition()); if (listView.getFirstVisiblePosition() == 0 && !isloading && haveMoreData) { List<EMMessage> messages; try { messages = conversation.loadMoreMsgFromDB(conversation.getAllMessages().size() == 0 ? "" : conversation.getAllMessages().get(0).getMsgId(), pagesize); } catch (Exception e1) { swipeRefreshLayout.setRefreshing(false); return; } if (messages.size() > 0) { messageList.refreshSeekTo(messages.size() - 1); if (messages.size() != pagesize) { haveMoreData = false; } } else { haveMoreData = false; if (onRefreshListener != null) { int size = conversation.getAllMessages().size(); Log.e(TAG,"size="+size); int pageNo = size/10+1; onRefreshListener.refresh(pageNo); } } isloading = false; } else { Toast.makeText(getActivity(), getResources().getString(R.string.no_more_messages), Toast.LENGTH_SHORT).show(); } swipeRefreshLayout.setRefreshing(false); } …… /** * 发送消息,并调用向本地服务器发送消息的接口 */ protected void sendMessage(EMMessage message){ if (message == null) { return; } Log.e(TAG,"sendMessage username="+message.getUserName()+",to="+message.getTo()+",from="+message.getFrom() +",status="+message.status()+",direct="+message.direct()+",keySet="+message.ext().keySet() +",type="+message.getType()+",MsgId="+message.getMsgId() +",body="+message.getBody().toString()); if(chatFragmentHelper != null){ //set extension chatFragmentHelper.onSetMessageAttributes(message); } if (chatType == EaseConstant.CHATTYPE_GROUP){ message.setChatType(ChatType.GroupChat); }else if(chatType == EaseConstant.CHATTYPE_CHATROOM){ message.setChatType(ChatType.ChatRoom); } message.setMessageStatusCallback(messageStatusCallback); // Send message. EMClient.getInstance().chatManager().sendMessage(message); //调用向本地服务器发送消息的接口 if (onClickSendListener != null) { onClickSendListener.onSendClick(message); } //refresh ui if(isMessageListInited) { messageList.refreshSelectLast(); } } /** * 向本地服务器发送消息,需要在ChatActivity中调用 */ public OnClickSendListener onClickSendListener; public void setOnItemClickListener(OnClickSendListener onClickBottomListener) { this.onClickSendListener = onClickBottomListener; } public interface OnClickSendListener{ /** * 发送消息事件 */ public void onSendClick(EMMessage message); } /** * 下拉加载,在ChatFragment中调用 */ public OnRefresh1Listener onRefreshListener; public void setOnRefresh1Listener(OnRefresh1Listener onClickBottomListener) { this.onRefreshListener = onClickBottomListener; } public interface OnRefresh1Listener{ /** * 下拉加载事件 */ public boolean refresh(int page); }
3. ChatActivity.java:调用fragment的发送接口,以向本地服务器发送消息;
public class ChatActivity extends BaseActivity{ …… @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); setContentView(R.layout.em_activity_chat); activityInstance = this; //get user id or group id toChatUsername = getIntent().getExtras().getString("userId"); //use EaseChatFratFragment chatFragment = new ChatFragment(); //pass parameters to chat fragment chatFragment.setArguments(getIntent().getExtras()); getSupportFragmentManager().beginTransaction().add(R.id.container, chatFragment).commit(); chatFragment.setOnItemClickListener(new EaseChatFragment.OnClickSendListener() { @Override public void onSendClick(EMMessage message) { sendRemoteMsg(message); } }); } …… private void sendRemoteMsg(EMMessage message) { Map<String, String> baseParam = new HashMap<>(); baseParam.put("id",""); baseParam.put("msgId",message.getMsgId()); baseParam.put("sendUser",message.getFrom()); baseParam.put("receiveUser",message.getTo()); Log.e(TAG,"receiveType="+message.getChatType().name()); String chatType =""; if (message.getChatType() == EMMessage.ChatType.Chat) { chatType = "0"; } else { chatType = "1"; } baseParam.put("receiveType",chatType); int type = 1; File file = null,file1 = null; int size = 0; Log.e(TAG,"type="+message.getType().name()); if (message.getType().name().toString().equals("TXT")) { if (message.getBooleanAttribute("is_office",false)) { type = 9; } else { type = 1; } EMTextMessageBody emTextMessageBody = ((EMTextMessageBody) message.getBody()); baseParam.put("message",emTextMessageBody.getMessage()); } else if (message.getType().name().toString().equals("LOCATION")) { type = 2; baseParam.put("message",message.getBody().toString()); } else if (message.getType().name().toString().equals("VOICE")) { type = 3; EMVoiceMessageBody emVoiceMessageBody = ((EMVoiceMessageBody) message.getBody()); String filePath = emVoiceMessageBody.getLocalUrl(); file = new File(filePath); baseParam.put("size",emVoiceMessageBody.getLength()+""); baseParam.put("message",message.getBody().toString()); } else if (message.getType().name().toString().equals("VIDEO")) { type = 4; EMVideoMessageBody emVideoMessageBody = ((EMVideoMessageBody) message.getBody()); String filePath = emVideoMessageBody.getLocalUrl(); file = new File(filePath); baseParam.put("size",emVideoMessageBody.getDuration()+""); String thumbnail = emVideoMessageBody.getLocalThumb(); Log.e(TAG,"thumbnail="+thumbnail+","+emVideoMessageBody.getLocalThumb()+",size="+emVideoMessageBody.getDuration()+","+emVideoMessageBody.getVideoFileLength()); file1 = new File(thumbnail); baseParam.put("message",message.getBody().toString()); } else if(message.getType().name().toString().equals("IMAGE")) { type = 5; String filePath = ((EMImageMessageBody) message.getBody()).getLocalUrl(); file = new File(filePath); baseParam.put("message",message.getBody().toString()); } else if (message.getType().name().toString().equals("FILE")) { type = 6; String filePath = ((EMFileMessageBody) message.getBody()).getLocalUrl(); file = new File(filePath); baseParam.put("message",message.getBody().toString()); } else { type = 1; baseParam.put("message",message.getBody().toString()); } baseParam.put("mesType",String.valueOf(type)); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); baseParam.put("sendTime",format.format(new Date(message.getMsgTime()))); Log.e(TAG,"baseParam="+ baseParam); FileLoadUtils.postFile(WebApi.MSN_CHAT_SAVE, baseParam, "mesFile", file,"thuFile",file1, new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG,"sendRemoteMsg e="+ e); } @Override public void onResponse(Call call, Response response) throws IOException { String result = FileLoadUtils.getResponseBody(response); Log.e(TAG,"sendRemoteMsg response="+ result+","+response); } }); } }
4. EMMessageUtils.java: ChatFragment.java中获取聊天记录后,将各种类型的聊天记录转化成相应的格式:
public class EMMessageUtils { private static final String TAG = "EMMessageUtils"; public static EMMessage createImageSendMessage(String fromUser, String var0, boolean var1, String var2) { File file = new File(var0); String path = ""; if (!file.exists()) { String fileName = file.getName(); path = FileLoadUtils.BASE_PATH + fromUser + "/image/"+fileName; file = new File(path); } else { path = var0; } EMMessage var3 = EMMessage.createSendMessage(EMMessage.Type.IMAGE); var3.setTo(var2); EMImageMessageBody var4 = new EMImageMessageBody(file); var4.setSendOriginalImage(var1); var3.addBody(var4); return var3; } public static EMMessage createVoiceSendMessage(String var0, int var1, String var2) { File file = new File(var0); File pathFile = new File(file.getParent()); if (!pathFile.exists()) { pathFile.mkdirs(); } if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } EMMessage var3 = EMMessage.createSendMessage(EMMessage.Type.VOICE); EMVoiceMessageBody var4 = new EMVoiceMessageBody(file, var1); var3.addBody(var4); var3.setTo(var2); return var3; // } } public static EMMessage createVideoSendMessage(String fromUser,String var0, String var1, int var2, String var3) { File file = new File(var0); String path = ""; if (!file.exists()) { String fileName = file.getName(); path = FileLoadUtils.BASE_PATH + fromUser + "/video/"+fileName; file = new File(path); } else { path = var0; } Log.e(TAG,"createVideoSendMessage path="+path); EMMessage var5 = EMMessage.createSendMessage(EMMessage.Type.VIDEO); var5.setTo(var3); EMVideoMessageBody var6 = new EMVideoMessageBody(path, var1, var2, file.length()); var5.addBody(var6); return var5; } /* * 修改SDK中的创建文件类型的消息,改成使用自己的路径 * */ public static EMMessage createFileSendMessage(String fromUser,String var0, String var1) { File file = new File(var0); Log.e(TAG,"createFileSendMessage var0="+var0); String path = ""; if (!file.exists()) { String fileName = file.getName(); path = FileLoadUtils.BASE_PATH + fromUser + "/file/"+fileName; file = new File(path); } else { path = var0; } EMMessage var3 = EMMessage.createSendMessage(EMMessage.Type.FILE); var3.setTo(var1); EMNormalFileMessageBody var4 = new EMNormalFileMessageBody(file); var3.addBody(var4); return var3; } /* * 创建视频类型的消息 * */ public static EMMessage createVideoMsg(RemoteMessage remoteMessage) { EMMessage message = null; int size = 0; if (!StringUtils.isEmpty(remoteMessage.getSize())) { size = Integer.valueOf(remoteMessage.getSize()); } String msgStr = remoteMessage.getMessage(); String[] msgArr = msgStr.split(","); String localurl=""; String thumbnailUrl= ""; for (int j=0;j<msgArr.length;j++) { String[] lat = msgArr[j].split(":"); if (lat[0].contains("localUrl")) { localurl = lat[1].trim(); } else if (lat[0].equals("thumbnailUrl")) { if (lat.length>1) { thumbnailUrl = lat[1].trim(); } } } message = createVideoSendMessage(remoteMessage.getSendUser(),localurl, remoteMessage.getThuImg(), size, remoteMessage.getReceiveUser()); ((EMVideoMessageBody)message.getBody()).setRemoteUrl(remoteMessage.getFileUrl()); return message; } /* * 创建地址类型的消息 * */ public static EMMessage createLocationMsg(RemoteMessage remoteMessage) { EMMessage message = null; String locStr = remoteMessage.getMessage(); String[] locArr = locStr.split(","); double latitude=0,longitude=0; String locationAddress=""; for (int j=0;j<locArr.length;j++) { String[] lat = locArr[j].split(":"); if (lat[0].equals("location")) { locationAddress = lat[1]; } else if (lat[0].equals("lat")) { latitude = Double.valueOf(lat[1]); } else if (lat[0].equals("lng")) { longitude = Double.valueOf(lat[1]); } } message = EMMessage.createLocationSendMessage(latitude, longitude, locationAddress, remoteMessage.getReceiveUser()); return message; } }
5. FileLoadUtils.java:向本地服务器上传数据
public class FileLoadUtils { private static final String TAG = "FileLoadUtils"; public FileLoadUtils() { } …… /** * 上传消息到服务器,表单形式上传 */ public static void postFile(final String url, final Map<String, String> map,String imgStr, File file,String param1,File file1, Callback callback) { OkHttpClient client = new OkHttpClient(); // form 表单形式上传 MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM); if (file != null) { Log.e("FileLoadUtils","file="+file.getPath()+","+file.getName()); // MediaType.parse() 里面是上传的文件类型。 RequestBody body = RequestBody.create(MediaType.parse("image/*"), file); String filename = file.getName(); // 参数分别为, 请求key ,文件名称 , RequestBody requestBody.addFormDataPart(imgStr, filename, body); } if (file1 != null) { Log.e("FileLoadUtils","file="+file1.getPath()+","+file1.getName()); // MediaType.parse() 里面是上传的文件类型。 RequestBody body = RequestBody.create(MediaType.parse("image/*"), file1); String filename = file1.getName(); // 参数分别为, 请求key ,文件名称 , RequestBody requestBody.addFormDataPart(param1, filename, body); } if (map != null) { // map 里面是请求中所需要的 key 和 value Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry entry : entries) { String key = String.valueOf(entry.getKey()); String value = String.valueOf(entry.getValue()); Log.d("HttpUtils", "key=="+key+",value=="+value); requestBody.addFormDataPart(key,value); } } String token = SavePreferences.getString(Const.TOKEN_KEY); Request request = new Request.Builder().url(url).header("token", token).post(requestBody.build()).build(); // readTimeout("请求超时时间" , 时间单位); client.newBuilder().readTimeout(5000, TimeUnit.MILLISECONDS).build() .newCall(request).enqueue(callback); } /** * 获取文件保存地址,toUser指发送消息过来的好友名称 */ public static File createFileEm(String type,String FileName,String toUser) { String path = null; if (toUser != null && !toUser.equals("") ) { if (type.equals("3")) { path = BASE_PATH + toUser + "/voice/" ; } else if (type.equals("4")) { path = BASE_PATH + toUser + "/video/"; }else if (type.equals("6")) { path = BASE_PATH + toUser + "/file/"; } else { path = BASE_PATH + toUser + "/image/"; } } else { if (type.equals("3")) { path = PathUtil.getInstance().getVoicePath() + "/" ; } else if (type.equals("4")) { path = PathUtil.getInstance().getVideoPath() + "/"; }else if (type.equals("6")) { path = PathUtil.getInstance().getFilePath() + "/"; } else { path = PathUtil.getInstance().getImagePath() + "/"; } } File file = new File(path); /** *如果文件夹不存在就创建 */ if (!file.exists()) { file.mkdirs(); } return new File(path, FileName); } /** * 获取视频的缩略图路径 */ public static String getThumnailPath(String fromUser,String videoPath) { String fileName = "thvideo" + System.currentTimeMillis(); createFileEm("5",fileName,fromUser); // File file = new File(getMSNBasePath("5",fromUser), fileName); File file = createFileEm("5",fileName,fromUser); try { FileOutputStream fos = new FileOutputStream(file); Bitmap ThumbBitmap = ThumbnailUtils.createVideoThumbnail(videoPath, 3); ThumbBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.close(); } catch (Exception e) { e.printStackTrace(); } return file.getAbsolutePath(); }
6. 发送企业名片后的显示:
发送完信息后,有个UI刷新的过程messageList.refreshSelectLast();----> messageAdapter.refreshSelectLast();
EaseMessageAdapter.java
public class EaseMessageAdapter extends BaseAdapter{ private final static String TAG = "EaseMessageAdapter"; private Context context; private static final int HANDLER_MESSAGE_REFRESH_LIST = 0; private static final int HANDLER_MESSAGE_SELECT_LAST = 1; private static final int HANDLER_MESSAGE_SEEK_TO = 2; private static final int MESSAGE_TYPE_RECV_TXT = 0; private static final int MESSAGE_TYPE_SENT_TXT = 1; private static final int MESSAGE_TYPE_SENT_IMAGE = 2; private static final int MESSAGE_TYPE_SENT_LOCATION = 3; private static final int MESSAGE_TYPE_RECV_LOCATION = 4; private static final int MESSAGE_TYPE_RECV_IMAGE = 5; private static final int MESSAGE_TYPE_SENT_VOICE = 6; private static final int MESSAGE_TYPE_RECV_VOICE = 7; private static final int MESSAGE_TYPE_SENT_VIDEO = 8; private static final int MESSAGE_TYPE_RECV_VIDEO = 9; private static final int MESSAGE_TYPE_SENT_FILE = 10; private static final int MESSAGE_TYPE_RECV_FILE = 11; private static final int MESSAGE_TYPE_SENT_EXPRESSION = 12; private static final int MESSAGE_TYPE_RECV_EXPRESSION = 13; private static final int MESSAGE_TYPE_SEND_CARD = 14; private static final int MESSAGE_TYPE_RECV_CARD = 15; private EMConversation conversation; EMMessage[] messages = null; private String toChatUsername; private MessageListItemClickListener itemClickListener; private EaseCustomChatRowProvider customRowProvider; private ListView listView; private EaseMessageListItemStyle itemStyle; public EaseMessageAdapter(Context context, String username, int chatType, ListView listView) { this.context = context; this.listView = listView; toChatUsername = username; this.conversation = EMClient.getInstance().chatManager().getConversation(username, EaseCommonUtils.getConversationType(chatType), true); } Handler handler = new Handler() { private void refreshList() { // you should not call getAllMessages() in UI thread // otherwise there is problem when refreshing UI and there is new message arrive java.util.List<EMMessage> var = conversation.getAllMessages(); Log.e(TAG,"EMMessage.size="+var.size()); messages = var.toArray(new EMMessage[var.size()]); conversation.markAllMessagesAsRead(); notifyDataSetChanged(); } @Override public void handleMessage(android.os.Message message) { switch (message.what) { case HANDLER_MESSAGE_REFRESH_LIST: refreshList(); break; case HANDLER_MESSAGE_SELECT_LAST: if (messages != null && messages.length > 0) { listView.setSelection(messages.length - 1); } break; case HANDLER_MESSAGE_SEEK_TO: int position = message.arg1; listView.setSelection(position); break; default: break; } } }; public void refresh() { if (handler.hasMessages(HANDLER_MESSAGE_REFRESH_LIST)) { return; } android.os.Message msg = handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST); handler.sendMessage(msg); } /** * refresh and select the last */ public void refreshSelectLast() { final int TIME_DELAY_REFRESH_SELECT_LAST = 100; handler.removeMessages(HANDLER_MESSAGE_REFRESH_LIST); handler.removeMessages(HANDLER_MESSAGE_SELECT_LAST); handler.sendEmptyMessageDelayed(HANDLER_MESSAGE_REFRESH_LIST, TIME_DELAY_REFRESH_SELECT_LAST); handler.sendEmptyMessageDelayed(HANDLER_MESSAGE_SELECT_LAST, TIME_DELAY_REFRESH_SELECT_LAST); } /** * refresh and seek to the position */ public void refreshSeekTo(int position) { handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST)); } public EMMessage getItem(int position) { if (messages != null && position < messages.length) { return messages[position]; } return null; } public long getItemId(int position) { return position; } /** * get count of messages */ public int getCount() { return messages == null ? 0 : messages.length; } /** * get number of message type, here 14 = (EMMessage.Type) * 2 */ public int getViewTypeCount() { if(customRowProvider != null && customRowProvider.getCustomChatRowTypeCount() > 0){ return customRowProvider.getCustomChatRowTypeCount() + 14; } return 14; } /** * get type of item */ public int getItemViewType(int position) { EMMessage message = getItem(position); if (message == null) { return -1; } if(customRowProvider != null && customRowProvider.getCustomChatRowType(message) > 0){ return customRowProvider.getCustomChatRowType(message) + 13; } if (message.getType() == EMMessage.Type.TXT) { if(message.getBooleanAttribute(EaseConstant.MESSAGE_ATTR_IS_BIG_EXPRESSION, false)){ return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_EXPRESSION : MESSAGE_TYPE_SENT_EXPRESSION; } //企业名片 if (message.getBooleanAttribute("is_office",false)) { return message.direct() == EMMessage.Direct.RECEIVE? MESSAGE_TYPE_RECV_CARD: MESSAGE_TYPE_SEND_CARD; } return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_TXT : MESSAGE_TYPE_SENT_TXT; } if (message.getType() == EMMessage.Type.IMAGE) { return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_IMAGE : MESSAGE_TYPE_SENT_IMAGE; } if (message.getType() == EMMessage.Type.LOCATION) { return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_LOCATION : MESSAGE_TYPE_SENT_LOCATION; } if (message.getType() == EMMessage.Type.VOICE) { return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE : MESSAGE_TYPE_SENT_VOICE; } if (message.getType() == EMMessage.Type.VIDEO) { return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO : MESSAGE_TYPE_SENT_VIDEO; } if (message.getType() == EMMessage.Type.FILE) { return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_FILE : MESSAGE_TYPE_SENT_FILE; } return -1;// invalid } //重点 protected EaseChatRowPresenter createChatRowPresenter(EMMessage message, int position) { Log.e(TAG,"createChatRowPresenter"); if(customRowProvider != null && customRowProvider.getCustomChatRow(message, position, this) != null){ return customRowProvider.getCustomChatRow(message, position, this); } EaseChatRowPresenter presenter = null; switch (message.getType()) { case TXT: if(message.getBooleanAttribute(EaseConstant.MESSAGE_ATTR_IS_BIG_EXPRESSION, false)){ presenter = new EaseChatBigExpressionPresenter(); }else{ Log.e(TAG,"TXT is_office"); if (message.getBooleanAttribute("is_office",false)) { Log.e(TAG,"TXT is_office true"); presenter = new EaseChatCardPresenter(); } else { presenter = new EaseChatTextPresenter(); } } break; case LOCATION: presenter = new EaseChatLocationPresenter(); break; case FILE: presenter = new EaseChatFilePresenter(); break; case IMAGE: presenter = new EaseChatImagePresenter(); break; case VOICE: presenter = new EaseChatVoicePresenter(); break; case VIDEO: presenter = new EaseChatVideoPresenter(); break; default: break; } return presenter; } @SuppressLint("NewApi") public View getView(final int position, View convertView, ViewGroup parent) { EMMessage message = getItem(position); EaseChatRowPresenter presenter = null; Log.e(TAG,""+message.getBooleanAttribute("is_office",false)+","+message.getBody()); if (convertView == null) { presenter = createChatRowPresenter(message, position); convertView = presenter.createChatRow(context, message, position, this); convertView.setTag(presenter); } else { presenter = (EaseChatRowPresenter) convertView.getTag(); } presenter.setup(message, position, itemClickListener, itemStyle); return convertView; } public void setItemStyle(EaseMessageListItemStyle itemStyle){ this.itemStyle = itemStyle; } public void setItemClickListener(MessageListItemClickListener listener){ itemClickListener = listener; } public void setCustomChatRowProvider(EaseCustomChatRowProvider rowProvider){ customRowProvider = rowProvider; } }
7. EaseChatCardPresenter.java
public class EaseChatCardPresenter extends EaseChatRowPresenter { private static final String TAG = "EaseChatFilePresenter"; @Override protected EaseChatRow onCreateChatRow(Context cxt, EMMessage message, int position, BaseAdapter adapter) { return new EaseChatRowCard(cxt, message, position, adapter); } @Override public void onBubbleClick(EMMessage message) { EMTextMessageBody fileMessageBody = (EMTextMessageBody) message.getBody(); //点击发送完后的企业名片需要的操作,还没有处理 …… if (message.direct() == EMMessage.Direct.RECEIVE && !message.isAcked() && message.getChatType() == EMMessage.ChatType.Chat) { try { EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId()); } catch (HyphenateException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
8.EaseChatRowCard.java
public class EaseChatRowCard extends EaseChatRow{ private static final String TAG = "EaseChatRowCard"; protected TextView fileNameView; protected TextView fileSizeView; protected TextView fileStateView; protected TextView tvOfficeAddr; protected TextView tvOfficeTel; private EMTextMessageBody fileMessageBody; public EaseChatRowCard(Context context, EMMessage message, int position, BaseAdapter adapter) { super(context, message, position, adapter); } @Override protected void onInflateView() { inflater.inflate(message.direct() == EMMessage.Direct.RECEIVE ? R.layout.ease_row_received_card : R.layout.ease_row_sent_card, this); } @Override protected void onFindViewById() { fileNameView = (TextView) findViewById(R.id.tv_file_name); fileSizeView = (TextView) findViewById(R.id.tv_file_size); fileStateView = (TextView) findViewById(R.id.tv_file_state); percentageView = (TextView) findViewById(R.id.percentage); tvOfficeAddr = (TextView) findViewById(R.id.tv_officeAddr); tvOfficeTel = (TextView) findViewById(R.id.tv_officeTel); } @Override protected void onSetUpView() { fileMessageBody = (EMTextMessageBody) message.getBody(); String content = fileMessageBody.getMessage(); Log.e(TAG,"content="+content); if (message.getBooleanAttribute("is_office",false)) { String[] contentArr = content.split(","); OfficeCard card = new OfficeCard(); card.setOfficeId(contentArr[0]); card.setOfficeName(contentArr[1]); card.setAddr(contentArr[2]); card.setTel(contentArr[3]); fileNameView.setText(card.getOfficeName()); tvOfficeAddr.setText(card.getAddr()); tvOfficeTel.setText(card.getTel()); } } @Override protected void onViewUpdate(EMMessage msg) { switch (msg.status()) { case CREATE: onMessageCreate(); break; case SUCCESS: onMessageSuccess(); break; case FAIL: onMessageError(); break; case INPROGRESS: onMessageInProgress(); break; } } private void onMessageCreate() { progressBar.setVisibility(View.VISIBLE); if (percentageView != null) percentageView.setVisibility(View.INVISIBLE); if (statusView != null) statusView.setVisibility(View.INVISIBLE); } private void onMessageSuccess() { progressBar.setVisibility(View.INVISIBLE); if (percentageView != null) percentageView.setVisibility(View.INVISIBLE); if (statusView != null) statusView.setVisibility(View.INVISIBLE); } private void onMessageError() { progressBar.setVisibility(View.INVISIBLE); if (percentageView != null) percentageView.setVisibility(View.INVISIBLE); if (statusView != null) statusView.setVisibility(View.VISIBLE); } private void onMessageInProgress() { progressBar.setVisibility(View.VISIBLE); if (percentageView != null) { percentageView.setVisibility(View.VISIBLE); percentageView.setText(message.progress() + "%"); } if (statusView != null) statusView.setVisibility(View.INVISIBLE); } }
栏 目:Android代码
下一篇:Android使用贝塞尔曲线仿QQ聊天消息气泡拖拽效果
本文标题:Android实现聊天记录上传本地服务器(即时通讯)
本文地址:http://www.codeinn.net/misctech/176699.html