Java tutorial
/** * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved. * <p/> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package maimeng.yodian.app.client.android.chat.adapter; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.AnimationDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; import android.text.Spannable; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.TextView.BufferType; import android.widget.Toast; import com.easemob.EMCallBack; import com.easemob.EMError; import com.easemob.chat.EMChatManager; import com.easemob.chat.EMConversation; import com.easemob.chat.EMMessage; import com.easemob.chat.EMMessage.ChatType; import com.easemob.chat.EMMessage.Type; import com.easemob.chat.FileMessageBody; import com.easemob.chat.ImageMessageBody; import com.easemob.chat.NormalFileMessageBody; import com.easemob.chat.TextMessageBody; import com.easemob.chat.VideoMessageBody; import com.easemob.chat.VoiceMessageBody; import com.easemob.exceptions.EaseMobException; import com.easemob.util.DensityUtil; import com.easemob.util.EMLog; import com.easemob.util.FileUtils; import com.easemob.util.TextFormater; import org.json.JSONArray; import org.json.JSONException; import java.io.File; import java.util.Date; import java.util.Hashtable; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import maimeng.yodian.app.client.android.R; import maimeng.yodian.app.client.android.chat.Constant; import maimeng.yodian.app.client.android.chat.activity.AlertDialog; import maimeng.yodian.app.client.android.chat.activity.ChatActivity; import maimeng.yodian.app.client.android.chat.activity.ContextMenu; import maimeng.yodian.app.client.android.chat.activity.ShowBigImage; import maimeng.yodian.app.client.android.chat.activity.ShowNormalFileActivity; import maimeng.yodian.app.client.android.chat.activity.ShowVideoActivity; import maimeng.yodian.app.client.android.chat.domain.User; import maimeng.yodian.app.client.android.chat.task.LoadImageTask; import maimeng.yodian.app.client.android.chat.task.LoadVideoImageTask; import maimeng.yodian.app.client.android.chat.utils.DateUtils; import maimeng.yodian.app.client.android.chat.utils.ImageCache; import maimeng.yodian.app.client.android.chat.utils.ImageUtils; import maimeng.yodian.app.client.android.chat.utils.SmileUtils; import maimeng.yodian.app.client.android.chat.utils.UserUtils; import maimeng.yodian.app.client.android.databings.ImageAdapter; import maimeng.yodian.app.client.android.view.chat.ContactPathActivity; import maimeng.yodian.app.client.android.view.user.UserHomeActivity; import maimeng.yodian.app.client.android.widget.YDView; public class MessageAdapter extends BaseAdapter { private final static String TAG = "msg"; 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_RECV_IMAGE = 3; private static final int MESSAGE_TYPE_SENT_VOICE = 4; private static final int MESSAGE_TYPE_RECV_VOICE = 5; private static final int MESSAGE_TYPE_SENT_VCARD = 6; private static final int MESSAGE_TYPE_RECV_VCARD = 7; public static final String IMAGE_DIR = "chat/image/"; private String username; private LayoutInflater inflater; private Activity activity; 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; // reference to conversation object in chatsdk private EMConversation conversation; EMMessage[] messages = null; private Context context; private long uid; public void setUid(long uid) { this.uid = uid; } private Map<String, Timer> timers = new Hashtable<String, Timer>(); public MessageAdapter(Context context, String username) { this.username = username; this.context = context; inflater = LayoutInflater.from(context); activity = (Activity) context; this.conversation = EMChatManager.getInstance().getConversation(username); } Handler handler = new Handler() { private void refreshList() { // UI?conversation.getAllMessages() // ?UI?? messages = (EMMessage[]) conversation.getAllMessages() .toArray(new EMMessage[conversation.getAllMessages().size()]); for (int i = 0; i < messages.length; i++) { // getMessage will set message as read status conversation.getMessage(i); } 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 (activity instanceof ChatActivity) { ListView listView = ((ChatActivity) activity).getListView(); if (messages.length > 0) { listView.setSelection(messages.length - 1); } } break; case HANDLER_MESSAGE_SEEK_TO: int position = message.arg1; if (activity instanceof ChatActivity) { ListView listView = ((ChatActivity) activity).getListView(); listView.setSelection(position); } break; default: break; } } }; /** * ?item */ public int getCount() { return messages == null ? 0 : messages.length; } /** * ? */ public void refresh() { if (handler.hasMessages(HANDLER_MESSAGE_REFRESH_LIST)) { return; } android.os.Message msg = handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST); handler.sendMessage(msg); } /** * ?, ? */ public void refreshSelectLast() { handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST)); handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_SELECT_LAST)); } /** * ?, Position */ public void refreshSeekTo(int position) { handler.sendMessage(handler.obtainMessage(HANDLER_MESSAGE_REFRESH_LIST)); android.os.Message msg = handler.obtainMessage(HANDLER_MESSAGE_SEEK_TO); msg.arg1 = position; handler.sendMessage(msg); } public EMMessage getItem(int position) { if (messages != null && position < messages.length) { return messages[position]; } return null; } public long getItemId(int position) { return position; } /** * ?item */ public int getViewTypeCount() { return 8; } /** * ?item */ public int getItemViewType(int position) { EMMessage message = getItem(position); if (message == null) { return -1; } if (message.getType() == EMMessage.Type.TXT) { if (isCard(message)) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VCARD : MESSAGE_TYPE_SENT_VCARD; } 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.VOICE) { return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE : MESSAGE_TYPE_SENT_VOICE; } return -1;// invalid } private View createViewByMessage(EMMessage message, int position) { switch (message.getType()) { case IMAGE: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_picture, null) : inflater.inflate(R.layout.row_sent_picture, null); case VOICE: return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_voice, null) : inflater.inflate(R.layout.row_sent_voice, null); default: if (getItemViewType(position) == MESSAGE_TYPE_SENT_VCARD) { return inflater.inflate(R.layout.row_sent_vcard, null); } else if (getItemViewType(position) == MESSAGE_TYPE_RECV_VCARD) { return inflater.inflate(R.layout.row_received_vcard, null); } else { return message.direct == EMMessage.Direct.RECEIVE ? inflater.inflate(R.layout.row_received_message, null) : inflater.inflate(R.layout.row_sent_message, null); } } } @SuppressLint("NewApi") public View getView(final int position, View convertView, ViewGroup parent) { final EMMessage message = getItem(position); ChatType chatType = message.getChatType(); final int itemViewType = getItemViewType(position); final ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = createViewByMessage(message, position); if (itemViewType == MESSAGE_TYPE_RECV_VCARD) { holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.iv_avatar = (YDView) convertView.findViewById(R.id.iv_userhead); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); holder.vcard_avatar = (YDView) convertView.findViewById(R.id.vcard_avatar); holder.vcard_nickname = (TextView) convertView.findViewById(R.id.vcard_nickname); holder.wechat_vcard_item = convertView.findViewById(R.id.vcard_wechat_item); } else if (itemViewType == MESSAGE_TYPE_SENT_VCARD) { holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.iv_avatar = (YDView) convertView.findViewById(R.id.iv_userhead); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); holder.vcard_avatar = (YDView) convertView.findViewById(R.id.vcard_avatar); holder.vcard_nickname = (TextView) convertView.findViewById(R.id.vcard_nickname); holder.wechat_vcard_item = convertView.findViewById(R.id.vcard_wechat_item); } else if (message.getType() == EMMessage.Type.IMAGE) { try { holder.iv = ((ImageView) convertView.findViewById(R.id.iv_sendPicture)); holder.iv_avatar = (YDView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.percentage); holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.TXT) { try { holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.iv_avatar = (YDView) convertView.findViewById(R.id.iv_userhead); // holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); } catch (Exception e) { } } else if (message.getType() == EMMessage.Type.VOICE) { try { holder.iv = ((ImageView) convertView.findViewById(R.id.iv_voice)); holder.iv_avatar = (YDView) convertView.findViewById(R.id.iv_userhead); holder.tv = (TextView) convertView.findViewById(R.id.tv_length); holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending); holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status); holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid); holder.iv_read_status = (ImageView) convertView.findViewById(R.id.iv_unread_voice); } catch (Exception e) { } } convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.iv_avatar.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (message.direct == EMMessage.Direct.RECEIVE) { try { String uid = message.getStringAttribute("uid"); if (!TextUtils.isEmpty(uid)) { UserHomeActivity.show(activity, Long.parseLong(uid)); } } catch (EaseMobException e) { e.printStackTrace(); } } } }); // ?????? if ((chatType == ChatType.GroupChat || chatType == chatType.ChatRoom) && message.direct == EMMessage.Direct.RECEIVE) { //demousername?nick holder.tv_usernick.setText(message.getFrom()); } // ??????textview if (!(chatType == ChatType.GroupChat || chatType == chatType.ChatRoom) && message.direct == EMMessage.Direct.SEND) { holder.tv_ack = (TextView) convertView.findViewById(R.id.tv_ack); holder.tv_delivered = (TextView) convertView.findViewById(R.id.tv_delivered); if (holder.tv_ack != null) { if (message.isAcked) { if (holder.tv_delivered != null) { holder.tv_delivered.setVisibility(View.INVISIBLE); } holder.tv_ack.setVisibility(View.VISIBLE); } else { holder.tv_ack.setVisibility(View.INVISIBLE); // check and display msg delivered ack status if (holder.tv_delivered != null) { if (message.isDelivered) { holder.tv_delivered.setVisibility(View.VISIBLE); } else { holder.tv_delivered.setVisibility(View.INVISIBLE); } } } } } else { // ??group messgae,chatroom message?? if ((message.getType() == Type.TXT || message.getType() == Type.LOCATION) && !message.isAcked && chatType != ChatType.GroupChat && chatType != ChatType.ChatRoom) { // ?? if (!message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)) { try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); // ?? message.isAcked = true; } catch (Exception e) { e.printStackTrace(); } } } } //? setUserAvatar(message, holder.iv_avatar); switch (message.getType()) { // ??typeitem case IMAGE: // handleImageMessage(message, holder, position, convertView); break; case TXT: // if (itemViewType == MESSAGE_TYPE_RECV_VCARD || itemViewType == MESSAGE_TYPE_SENT_VCARD) { try { String avatar = message.getStringAttribute("avatar"); String nickName = message.getStringAttribute("nickName"); holder.vcard_nickname.setText(nickName); if (avatar != null) { ImageAdapter.image(holder.vcard_avatar, avatar); } holder.wechat_vcard_item.setTag(message); holder.wechat_vcard_item.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { EMMessage msg = (EMMessage) v.getTag(); if (itemViewType == MESSAGE_TYPE_RECV_VCARD) { User user = User.parse(msg); final String contact = user.getMobile(); final String qq = user.getQq(); final String wechat = user.getWechat(); ContactPathActivity.show(activity, qq, contact, wechat); } else { final maimeng.yodian.app.client.android.model.user.User.Info user = maimeng.yodian.app.client.android.model.user.User .read(activity).getInfo(); final String contact = user.getContact(); final String qq = user.getQq(); final String wechat = user.getWechat(); ContactPathActivity.show(activity, qq, contact, wechat); } } }); if (message.direct == EMMessage.Direct.SEND) { switch (message.status) { case SUCCESS: // ??? holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: // ?? holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: // ?? holder.pb.setVisibility(View.VISIBLE); holder.staus_iv.setVisibility(View.GONE); break; default: // ??? sendMsgInBackground(message, holder); } } } catch (EaseMobException e) { e.printStackTrace(); } break; } handleTextMessage(message, holder, position); break; case VOICE: // handleVoiceMessage(message, holder, position, convertView); default: // not supported } if (message.direct == EMMessage.Direct.SEND) { View statusView = convertView.findViewById(R.id.msg_status); // ?? statusView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // ???alertdialog Intent intent = new Intent(activity, AlertDialog.class); intent.putExtra("msg", activity.getString(R.string.confirm_resend)); intent.putExtra("title", activity.getString(R.string.resend)); intent.putExtra("cancel", true); intent.putExtra("position", position); if (message.getType() == EMMessage.Type.TXT) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_TEXT); else if (message.getType() == EMMessage.Type.VOICE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VOICE); else if (message.getType() == EMMessage.Type.IMAGE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_PICTURE); else if (message.getType() == EMMessage.Type.LOCATION) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_LOCATION); else if (message.getType() == EMMessage.Type.FILE) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_FILE); else if (message.getType() == EMMessage.Type.VIDEO) activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VIDEO); } }); } else { final String st = context.getResources().getString(R.string.Into_the_blacklist); if (!((ChatActivity) activity).isRobot && chatType != ChatType.ChatRoom) { // ???? holder.iv_avatar.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { Intent intent = new Intent(activity, AlertDialog.class); intent.putExtra("msg", st); intent.putExtra("cancel", true); intent.putExtra("position", position); activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_ADD_TO_BLACKLIST); return true; } }); } } TextView timestamp = (TextView) convertView.findViewById(R.id.timestamp); if (position == 0) { timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime()))); timestamp.setVisibility(View.VISIBLE); } else { // ??? EMMessage prevMessage = getItem(position - 1); if (prevMessage != null && DateUtils.isCloseEnough(message.getMsgTime(), prevMessage.getMsgTime())) { timestamp.setVisibility(View.GONE); } else { timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime()))); timestamp.setVisibility(View.VISIBLE); } } return convertView; } /** * ? * * @param message * @param imageView */ private void setUserAvatar(EMMessage message, YDView imageView) { String from = message.getFrom(); UserUtils.setUserAvatar(context, from, imageView); } /** * ? * * @param message * @param holder * @param position */ private void handleTextMessage(EMMessage message, ViewHolder holder, final int position) { TextMessageBody txtBody = (TextMessageBody) message.getBody(); Spannable span = SmileUtils.getSmiledText(context, txtBody.getMessage()); // holder.tv.setText(span, BufferType.SPANNABLE); // ? holder.tv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { activity.startActivityForResult( (new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.TXT.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU, new Bundle()); return true; } }); if (message.direct == EMMessage.Direct.SEND) { switch (message.status) { case SUCCESS: // ??? holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: // ?? holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: // ?? holder.pb.setVisibility(View.VISIBLE); holder.staus_iv.setVisibility(View.GONE); break; default: // ??? sendMsgInBackground(message, holder); } } } private void setRobotMenuMessageLayout(LinearLayout parentView, JSONArray jsonArr) { try { parentView.removeAllViews(); for (int i = 0; i < jsonArr.length(); i++) { final String itemStr = jsonArr.getString(i); final TextView textView = new TextView(context); textView.setText(itemStr); textView.setTextSize(15); try { textView.setTextColor(context.getResources().getColor(R.color.menu_msg_text_color)); } catch (Exception e) { e.printStackTrace(); } textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((ChatActivity) context).sendText(itemStr); } }); LinearLayout.LayoutParams llLp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); llLp.bottomMargin = DensityUtil.dip2px(context, 3); llLp.topMargin = DensityUtil.dip2px(context, 3); parentView.addView(textView, llLp); } } catch (JSONException e) { e.printStackTrace(); } } private boolean isCard(EMMessage message) { TextMessageBody txtBody = (TextMessageBody) message.getBody(); if ("[??]".equals(txtBody.getMessage())) { return true; } return false; } /** * ? * * @param message * @param holder * @param position * @param convertView */ private void handleImageMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { holder.pb.setTag(position); holder.iv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { activity.startActivityForResult( (new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.IMAGE.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU, new Bundle()); return true; } }); // ?? if (message.direct == EMMessage.Direct.RECEIVE) { // "it is receive msg"; if (message.status == EMMessage.Status.INPROGRESS) { // "!!!! back receive"; holder.iv.setImageResource(R.mipmap.default_image); showDownloadImageProgress(message, holder); // downloadImage(message, holder); } else { // "!!!! not back receive, show image directly"); holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); holder.iv.setImageResource(R.mipmap.default_image); ImageMessageBody imgBody = (ImageMessageBody) message.getBody(); if (imgBody.getLocalUrl() != null) { // String filePath = imgBody.getLocalUrl(); String remotePath = imgBody.getRemoteUrl(); String filePath = ImageUtils.getImagePath(remotePath); String thumbRemoteUrl = imgBody.getThumbnailUrl(); if (TextUtils.isEmpty(thumbRemoteUrl) && !TextUtils.isEmpty(remotePath)) { thumbRemoteUrl = remotePath; } String thumbnailPath = ImageUtils.getThumbnailImagePath(thumbRemoteUrl); showImageView(thumbnailPath, holder.iv, filePath, imgBody.getRemoteUrl(), message); } } return; } // ??? // process send message // send pic, show the pic directly ImageMessageBody imgBody = (ImageMessageBody) message.getBody(); String filePath = imgBody.getLocalUrl(); if (filePath != null && new File(filePath).exists()) { showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, filePath, null, message); } else { showImageView(ImageUtils.getThumbnailImagePath(filePath), holder.iv, filePath, IMAGE_DIR, message); } switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: holder.staus_iv.setVisibility(View.GONE); holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); if (timers.containsKey(message.getMsgId())) return; // set a timer final Timer timer = new Timer(); timers.put(message.getMsgId(), timer); timer.schedule(new TimerTask() { @Override public void run() { activity.runOnUiThread(new Runnable() { public void run() { holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText(message.progress + "%"); if (message.status == EMMessage.Status.SUCCESS) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_SUCCESS); timer.cancel(); } else if (message.status == EMMessage.Status.FAIL) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_FAIL); // message.setProgress(0); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), Toast.LENGTH_SHORT).show(); timer.cancel(); } } }); } }, 0, 500); break; default: sendPictureMessage(message, holder); } } /** * ? * * @param message * @param holder * @param position * @param convertView */ private void handleVideoMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { VideoMessageBody videoBody = (VideoMessageBody) message.getBody(); // final File image=new File(PathUtil.getInstance().getVideoPath(), // videoBody.getFileName()); String localThumb = videoBody.getLocalThumb(); holder.iv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { activity.startActivityForResult( new Intent(activity, ContextMenu.class).putExtra("position", position).putExtra("type", EMMessage.Type.VIDEO.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU, new Bundle()); return true; } }); if (localThumb != null) { showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message); } if (videoBody.getLength() > 0) { String time = DateUtils.toTimeBySecond(videoBody.getLength()); holder.timeLength.setText(time); } holder.playBtn.setImageResource(R.mipmap.video_download_btn_nor); if (message.direct == EMMessage.Direct.RECEIVE) { if (videoBody.getVideoFileLength() > 0) { String size = TextFormater.getDataSize(videoBody.getVideoFileLength()); holder.size.setText(size); } } else { if (videoBody.getLocalUrl() != null && new File(videoBody.getLocalUrl()).exists()) { String size = TextFormater.getDataSize(new File(videoBody.getLocalUrl()).length()); holder.size.setText(size); } } if (message.direct == EMMessage.Direct.RECEIVE) { // System.err.println("it is receive msg"); if (message.status == EMMessage.Status.INPROGRESS) { // System.err.println("!!!! back receive"); holder.iv.setImageResource(R.mipmap.default_image); showDownloadImageProgress(message, holder); } else { // System.err.println("!!!! not back receive, show image directly"); holder.iv.setImageResource(R.mipmap.default_image); if (localThumb != null) { showVideoThumbView(localThumb, holder.iv, videoBody.getThumbnailUrl(), message); } } return; } holder.pb.setTag(position); // until here ,deal with send video msg switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: if (timers.containsKey(message.getMsgId())) return; // set a timer final Timer timer = new Timer(); timers.put(message.getMsgId(), timer); timer.schedule(new TimerTask() { @Override public void run() { activity.runOnUiThread(new Runnable() { @Override public void run() { holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText(message.progress + "%"); if (message.status == EMMessage.Status.SUCCESS) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_SUCCESS); timer.cancel(); } else if (message.status == EMMessage.Status.FAIL) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_FAIL); // message.setProgress(0); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), Toast.LENGTH_SHORT).show(); timer.cancel(); } } }); } }, 0, 500); break; default: // sendMsgInBackground(message, holder); sendPictureMessage(message, holder); } } /** * ? * * @param message * @param holder * @param position * @param convertView */ private void handleVoiceMessage(final EMMessage message, final ViewHolder holder, final int position, View convertView) { VoiceMessageBody voiceBody = (VoiceMessageBody) message.getBody(); int len = voiceBody.getLength(); if (len > 0) { holder.tv.setText(voiceBody.getLength() + "\""); holder.tv.setVisibility(View.VISIBLE); } else { holder.tv.setVisibility(View.INVISIBLE); } holder.iv.setOnClickListener( new VoicePlayClickListener(message, holder.iv, holder.iv_read_status, this, activity, username)); holder.iv.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { activity.startActivityForResult( (new Intent(activity, ContextMenu.class)).putExtra("position", position).putExtra("type", EMMessage.Type.VOICE.ordinal()), ChatActivity.REQUEST_CODE_CONTEXT_MENU, new Bundle()); return true; } }); if (((ChatActivity) activity).playMsgId != null && ((ChatActivity) activity).playMsgId.equals(message.getMsgId()) && VoicePlayClickListener.isPlaying) { AnimationDrawable voiceAnimation; if (message.direct == EMMessage.Direct.RECEIVE) { holder.iv.setImageResource(R.drawable.voice_from_icon); } else { holder.iv.setImageResource(R.drawable.voice_to_icon); } voiceAnimation = (AnimationDrawable) holder.iv.getDrawable(); voiceAnimation.start(); } else { if (message.direct == EMMessage.Direct.RECEIVE) { holder.iv.setImageResource(R.mipmap.chatfrom_voice_playing); } else { holder.iv.setImageResource(R.mipmap.chatto_voice_playing); } } if (message.direct == EMMessage.Direct.RECEIVE) { if (message.isListened()) { // ??? holder.iv_read_status.setVisibility(View.INVISIBLE); } else { holder.iv_read_status.setVisibility(View.VISIBLE); } EMLog.d(TAG, "it is receive msg"); if (message.status == EMMessage.Status.INPROGRESS) { holder.pb.setVisibility(View.VISIBLE); EMLog.d(TAG, "!!!! back receive"); ((FileMessageBody) message.getBody()).setDownloadCallback(new EMCallBack() { @Override public void onSuccess() { activity.runOnUiThread(new Runnable() { @Override public void run() { holder.pb.setVisibility(View.INVISIBLE); notifyDataSetChanged(); } }); } @Override public void onProgress(int progress, String status) { } @Override public void onError(int code, String message) { activity.runOnUiThread(new Runnable() { @Override public void run() { holder.pb.setVisibility(View.INVISIBLE); } }); } }); } else { holder.pb.setVisibility(View.INVISIBLE); } return; } // until here, deal with send voice msg switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.GONE); break; case FAIL: holder.pb.setVisibility(View.GONE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: holder.pb.setVisibility(View.VISIBLE); holder.staus_iv.setVisibility(View.GONE); break; default: sendMsgInBackground(message, holder); } } /** * ? * * @param message * @param holder * @param position * @param convertView */ private void handleFileMessage(final EMMessage message, final ViewHolder holder, int position, View convertView) { final NormalFileMessageBody fileMessageBody = (NormalFileMessageBody) message.getBody(); final String filePath = fileMessageBody.getLocalUrl(); holder.tv_file_name.setText(fileMessageBody.getFileName()); holder.tv_file_size.setText(TextFormater.getDataSize(fileMessageBody.getFileSize())); holder.ll_container.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { File file = new File(filePath); if (file != null && file.exists()) { // FileUtils.openFile(file, (Activity) context); } else { // context.startActivity( new Intent(context, ShowNormalFileActivity.class).putExtra("msgbody", fileMessageBody)); } if (message.direct == EMMessage.Direct.RECEIVE && !message.isAcked && message.getChatType() != ChatType.GroupChat && message.getChatType() != ChatType.ChatRoom) { try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); message.isAcked = true; } catch (EaseMobException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); String st1 = context.getResources().getString(R.string.Have_downloaded); String st2 = context.getResources().getString(R.string.Did_not_download); if (message.direct == EMMessage.Direct.RECEIVE) { // ? EMLog.d(TAG, "it is receive msg"); File file = new File(filePath); if (file != null && file.exists()) { holder.tv_file_download_state.setText(st1); } else { holder.tv_file_download_state.setText(st2); } return; } // until here, deal with send voice msg switch (message.status) { case SUCCESS: holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.INVISIBLE); break; case FAIL: holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.VISIBLE); break; case INPROGRESS: if (timers.containsKey(message.getMsgId())) return; // set a timer final Timer timer = new Timer(); timers.put(message.getMsgId(), timer); timer.schedule(new TimerTask() { @Override public void run() { activity.runOnUiThread(new Runnable() { @Override public void run() { holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText(message.progress + "%"); if (message.status == EMMessage.Status.SUCCESS) { holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); timer.cancel(); } else if (message.status == EMMessage.Status.FAIL) { holder.pb.setVisibility(View.INVISIBLE); holder.tv.setVisibility(View.INVISIBLE); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), Toast.LENGTH_SHORT).show(); timer.cancel(); } } }); } }, 0, 500); break; default: // ??? sendMsgInBackground(message, holder); } } /** * ??? * * @param message * @param holder */ public void sendMsgInBackground(final EMMessage message, final ViewHolder holder) { holder.staus_iv.setVisibility(View.GONE); holder.pb.setVisibility(View.VISIBLE); final long start = System.currentTimeMillis(); // sdk???? EMChatManager.getInstance().sendMessage(message, new EMCallBack() { @Override public void onSuccess() { updateSendedView(message, holder); } @Override public void onError(int code, String error) { updateSendedView(message, holder); } @Override public void onProgress(int progress, String status) { } }); } /* * chat sdk will automatic download thumbnail image for the image message we * need to register callback show the download progress */ private void showDownloadImageProgress(final EMMessage message, final ViewHolder holder) { EMLog.d(TAG, "!!! show download image progress"); // final ImageMessageBody msgbody = (ImageMessageBody) // message.getBody(); final FileMessageBody msgbody = (FileMessageBody) message.getBody(); if (holder.pb != null) holder.pb.setVisibility(View.VISIBLE); if (holder.tv != null) holder.tv.setVisibility(View.VISIBLE); msgbody.setDownloadCallback(new EMCallBack() { @Override public void onSuccess() { activity.runOnUiThread(new Runnable() { @Override public void run() { // message.setBackReceive(false); if (message.getType() == EMMessage.Type.IMAGE) { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); } notifyDataSetChanged(); } }); } @Override public void onError(int code, String message) { } @Override public void onProgress(final int progress, String status) { if (message.getType() == EMMessage.Type.IMAGE) { activity.runOnUiThread(new Runnable() { @Override public void run() { holder.tv.setText(progress + "%"); } }); } } }); } /* * send message with new sdk */ private void sendPictureMessage(final EMMessage message, final ViewHolder holder) { try { String to = message.getTo(); // before send, update ui holder.staus_iv.setVisibility(View.GONE); holder.pb.setVisibility(View.VISIBLE); holder.tv.setVisibility(View.VISIBLE); holder.tv.setText("0%"); final long start = System.currentTimeMillis(); // if (chatType == ChatActivity.CHATTYPE_SINGLE) { EMChatManager.getInstance().sendMessage(message, new EMCallBack() { @Override public void onSuccess() { Log.d(TAG, "send image message successfully"); activity.runOnUiThread(new Runnable() { public void run() { // send success holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); } }); } @Override public void onError(int code, String error) { activity.runOnUiThread(new Runnable() { public void run() { holder.pb.setVisibility(View.GONE); holder.tv.setVisibility(View.GONE); // message.setSendingStatus(Message.SENDING_STATUS_FAIL); holder.staus_iv.setVisibility(View.VISIBLE); Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), Toast.LENGTH_SHORT).show(); } }); } @Override public void onProgress(final int progress, String status) { activity.runOnUiThread(new Runnable() { public void run() { holder.tv.setText(progress + "%"); } }); } }); } catch (Exception e) { e.printStackTrace(); } } /** * ui???? * * @param message * @param holder */ private void updateSendedView(final EMMessage message, final ViewHolder holder) { activity.runOnUiThread(new Runnable() { @Override public void run() { // send success if (message.getType() == EMMessage.Type.VIDEO) { holder.tv.setVisibility(View.GONE); } EMLog.d(TAG, "message status : " + message.status); if (message.status == EMMessage.Status.SUCCESS) { // if (message.getType() == EMMessage.Type.FILE) { // holder.pb.setVisibility(View.INVISIBLE); // holder.staus_iv.setVisibility(View.INVISIBLE); // } else { // holder.pb.setVisibility(View.GONE); // holder.staus_iv.setVisibility(View.GONE); // } } else if (message.status == EMMessage.Status.FAIL) { // if (message.getType() == EMMessage.Type.FILE) { // holder.pb.setVisibility(View.INVISIBLE); // } else { // holder.pb.setVisibility(View.GONE); // } // holder.staus_iv.setVisibility(View.VISIBLE); if (message.getError() == EMError.MESSAGE_SEND_INVALID_CONTENT) { Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.error_send_invalid_content), Toast.LENGTH_SHORT).show(); } else if (message.getError() == EMError.MESSAGE_SEND_NOT_IN_THE_GROUP) { Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.error_send_not_in_the_group), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(activity, activity.getString(R.string.send_fail) + activity.getString(R.string.connect_failuer_toast), Toast.LENGTH_SHORT).show(); } } notifyDataSetChanged(); } }); } /** * start image into image view * * @param thumbernailPath * @param iv * @return the image exists or not */ private boolean showImageView(final String thumbernailPath, final ImageView iv, final String localFullSizePath, String remoteDir, final EMMessage message) { // String imagename = // localFullSizePath.substring(localFullSizePath.lastIndexOf("/") + 1, // localFullSizePath.length()); // final String remote = remoteDir != null ? remoteDir+imagename : // imagename; final String remote = remoteDir; EMLog.d("###", "local = " + localFullSizePath + " remote: " + remote); // first check if the thumbnail image already loaded into cache Bitmap bitmap = ImageCache.getInstance().get(thumbernailPath); if (bitmap != null && false) { // thumbnail image is already loaded, reuse the drawable iv.setImageBitmap(bitmap); iv.setClickable(true); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EMLog.d(TAG, "image view on click"); Intent intent = new Intent(activity, ShowBigImage.class); File file = new File(localFullSizePath); if (file.exists()) { Uri uri = Uri.fromFile(file); intent.putExtra("uri", uri); EMLog.d(TAG, "here need to check why download everytime"); } else { // The local full size pic does not exist yet. // ShowBigImage needs to download it from the server // first // intent.putExtra("", message.get); ImageMessageBody body = (ImageMessageBody) message.getBody(); intent.putExtra("secret", body.getSecret()); intent.putExtra("remotepath", remote); } if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked && message.getChatType() != ChatType.GroupChat && message.getChatType() != ChatType.ChatRoom) { try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); message.isAcked = true; } catch (Exception e) { e.printStackTrace(); } } Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, iv, "img") .toBundle(); ActivityCompat.startActivity(activity, intent, options); } }); return true; } else { new LoadImageTask().execute(thumbernailPath, localFullSizePath, remote, message.getChatType(), iv, activity, message, iv.getContext()); return true; } } /** * * * @param localThumb * @param iv * @param thumbnailUrl * @param message */ private void showVideoThumbView(String localThumb, ImageView iv, String thumbnailUrl, final EMMessage message) { // first check if the thumbnail image already loaded into cache Bitmap bitmap = ImageCache.getInstance().get(localThumb); if (bitmap != null) { // thumbnail image is already loaded, reuse the drawable iv.setImageBitmap(bitmap); iv.setClickable(true); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { VideoMessageBody videoBody = (VideoMessageBody) message.getBody(); EMLog.d(TAG, "video view is on click"); Intent intent = new Intent(activity, ShowVideoActivity.class); intent.putExtra("localpath", videoBody.getLocalUrl()); intent.putExtra("secret", videoBody.getSecret()); intent.putExtra("remotepath", videoBody.getRemoteUrl()); if (message != null && message.direct == EMMessage.Direct.RECEIVE && !message.isAcked && message.getChatType() != ChatType.GroupChat && message.getChatType() != ChatType.ChatRoom) { message.isAcked = true; try { EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId()); } catch (Exception e) { e.printStackTrace(); } } activity.startActivity(intent); } }); } else { new LoadVideoImageTask().execute(localThumb, thumbnailUrl, iv, activity, message, this); } } public static class ViewHolder { ImageView iv; TextView tv; ProgressBar pb; ImageView staus_iv; YDView iv_avatar; TextView tv_usernick; ImageView playBtn; TextView timeLength; TextView size; LinearLayout container_status_btn; LinearLayout ll_container; ImageView iv_read_status; // ? TextView tv_ack; // ?? TextView tv_delivered; TextView tv_file_name; TextView tv_file_size; TextView tv_file_download_state; TextView vcard_nickname; YDView vcard_avatar; View wechat_vcard_item; } }