package com.fanxin.huangfangyi.main.fragment;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSONArray;
import com.easemob.redpacketui.RedPacketConstant;
import com.easemob.redpacketui.utils.RedPacketUtil;
import com.easemob.redpacketui.widget.ChatRowRedPacket;
import com.easemob.redpacketui.widget.ChatRowRedPacketAck;
import com.fanxin.huangfangyi.DemoApplication;
import com.fanxin.huangfangyi.main.activity.ChatSettingGroupActivity;
import com.fanxin.huangfangyi.main.activity.ChatSettingSingleActivity;
import com.fanxin.huangfangyi.main.FXConstant;
import com.fanxin.huangfangyi.main.activity.UserDetailsActivity;
import com.fanxin.huangfangyi.main.db.ACache;
import com.fanxin.huangfangyi.ui.ChatRoomDetailsActivity;
import com.fanxin.huangfangyi.ui.ContextMenuActivity;
import com.fanxin.huangfangyi.ui.ForwardMessageActivity;
import com.fanxin.huangfangyi.ui.GroupDetailsActivity;
import com.fanxin.huangfangyi.ui.ImageGridActivity;
import com.fanxin.huangfangyi.ui.PickAtUserActivity;
import com.fanxin.huangfangyi.ui.VideoCallActivity;
import com.fanxin.huangfangyi.ui.VoiceCallActivity;
import com.fanxin.huangfangyi.widget.ChatRowVoiceCall;
import com.fanxin.easeui.controller.EaseUI;
import com.fanxin.easeui.widget.chatrow.EaseChatRow;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMCmdMessageBody;
import com.hyphenate.chat.EMGroup;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;
import com.fanxin.huangfangyi.Constant;
import com.fanxin.huangfangyi.DemoHelper;
import com.fanxin.huangfangyi.R;
import com.fanxin.huangfangyi.domain.EmojiconExampleGroupData;
import com.fanxin.huangfangyi.domain.RobotUser;
import com.fanxin.easeui.EaseConstant;
import com.fanxin.easeui.ui.EaseChatFragment;
import com.fanxin.easeui.ui.EaseChatFragment.EaseChatFragmentHelper;
import com.fanxin.easeui.widget.chatrow.EaseCustomChatRowProvider;
import com.fanxin.easeui.widget.emojicon.EaseEmojiconMenu;
import com.hyphenate.exceptions.HyphenateException;
import com.hyphenate.util.PathUtil;
public class ChatFragment extends EaseChatFragment implements EaseChatFragmentHelper {
// constant start from 11 to avoid conflict with constant in base class
private static final int ITEM_VIDEO = 11;
private static final int ITEM_FILE = 12;
private static final int ITEM_VOICE_CALL = 13;
private static final int ITEM_VIDEO_CALL = 14;
private static final int REQUEST_CODE_SELECT_VIDEO = 11;
private static final int REQUEST_CODE_SELECT_FILE = 12;
private static final int REQUEST_CODE_GROUP_DETAIL = 13;
private static final int REQUEST_CODE_CONTEXT_MENU = 14;
private static final int REQUEST_CODE_SELECT_AT_USER = 15;
private static final int REQUEST_CODE_SEND_MONEY = 16;
private static final int MESSAGE_TYPE_SENT_VOICE_CALL = 1;
private static final int MESSAGE_TYPE_RECV_VOICE_CALL = 2;
private static final int MESSAGE_TYPE_SENT_VIDEO_CALL = 3;
private static final int MESSAGE_TYPE_RECV_VIDEO_CALL = 4;
//red packet code : 红包功能使用的常量
private static final int MESSAGE_TYPE_RECV_RED_PACKET = 5;
private static final int MESSAGE_TYPE_SEND_RED_PACKET = 6;
private static final int MESSAGE_TYPE_SEND_RED_PACKET_ACK = 7;
private static final int MESSAGE_TYPE_RECV_RED_PACKET_ACK = 8;
private static final int REQUEST_CODE_SEND_RED_PACKET = 16;
private static final int ITEM_RED_PACKET = 16;
private EMMessage rpMessage;
/**
* if it is chatBot
*/
private boolean isRobot;
private TextView tvName;
private MyBroadcastReceiver broadcastReceiver;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fx_fragment_chat, container, false);
}
@Override
protected void setUpView() {
setChatFragmentListener(this);
tvName = (TextView) getView().findViewById(R.id.name);
if (chatType == Constant.CHATTYPE_SINGLE) {
Map<String, RobotUser> robotMap = DemoHelper.getInstance().getRobotList();
if (robotMap != null && robotMap.containsKey(toChatUsername)) {
isRobot = true;
}
getView().findViewById(R.id.iv_setting_single).setVisibility(View.VISIBLE);
getView().findViewById(R.id.iv_setting_single).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getActivity(), ChatSettingSingleActivity.class).putExtra("userId", toChatUsername));
}
});
getView().findViewById(R.id.iv_setting_group).setVisibility(View.GONE);
if (DemoHelper.getInstance().getContactList().containsKey(toChatUsername)) {
tvName.setText(DemoHelper.getInstance().getContactList().get(toChatUsername).getNick());
}
}
super.setUpView();
hideTitleBar();
((EaseEmojiconMenu) inputMenu.getEmojiconMenu()).addEmojiconGroup(EmojiconExampleGroupData.getData());
if (chatType == EaseConstant.CHATTYPE_GROUP) {
getView().findViewById(R.id.iv_setting_group).setVisibility(View.VISIBLE);
getView().findViewById(R.id.iv_setting_group).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getActivity(), ChatSettingGroupActivity.class).putExtra("groupId", toChatUsername));
}
});
getView().findViewById(R.id.iv_setting_single).setVisibility(View.GONE);
inputMenu.getPrimaryMenu().getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count == 1 && "@".equals(String.valueOf(s.charAt(start)))) {
startActivityForResult(new Intent(getActivity(), PickAtUserActivity.class).
putExtra("groupId", toChatUsername), REQUEST_CODE_SELECT_AT_USER);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
EMGroup group = EMClient.getInstance().groupManager().getGroup(toChatUsername);
if (group == null || group.getAffiliationsCount() <= 0) {
new Thread(new Runnable() {
@Override
public void run() {
try {
EMClient.getInstance().groupManager().getGroupFromServer(toChatUsername);
} catch (HyphenateException e) {
e.printStackTrace();
}
}
}).start();
//获取群成员信息
}
tvName.setText("群聊");
}
broadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(EaseConstant.ACTION_DELETE_MSG);
getActivity().registerReceiver(broadcastReceiver, filter);
}
class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("receive-->", "broadcast");
messageList.refresh();
}
}
@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);
}
//no red packet in chatroom
if (chatType != Constant.CHATTYPE_CHATROOM) {
inputMenu.registerExtendMenuItem(R.string.attach_red_packet, R.drawable.em_chat_red_packet_selector, ITEM_RED_PACKET, extendMenuItemClickListener);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CONTEXT_MENU) {
switch (resultCode) {
case ContextMenuActivity.RESULT_CODE_COPY: // copy
clipboard.setPrimaryClip(ClipData.newPlainText(null,
((EMTextMessageBody) contextMenuMessage.getBody()).getMessage()));
break;
case ContextMenuActivity.RESULT_CODE_DELETE: // delete
conversation.removeMessage(contextMenuMessage.getMsgId());
messageList.refresh();
break;
case ContextMenuActivity.RESULT_CODE_FORWARD: // forward
Intent intent = new Intent(getActivity(), ForwardMessageActivity.class);
intent.putExtra("forward_msg_id", contextMenuMessage.getMsgId());
startActivity(intent);
break;
default:
break;
}
}
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case REQUEST_CODE_SELECT_VIDEO: //send the video
if (data != null) {
int duration = data.getIntExtra("dur", 0);
String videoPath = data.getStringExtra("path");
File file = new File(PathUtil.getInstance().getImagePath(), "thvideo" + System.currentTimeMillis());
try {
FileOutputStream fos = new FileOutputStream(file);
Bitmap ThumbBitmap = ThumbnailUtils.createVideoThumbnail(videoPath, 3);
ThumbBitmap.compress(CompressFormat.JPEG, 100, fos);
fos.close();
sendVideoMessage(videoPath, file.getAbsolutePath(), duration);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case REQUEST_CODE_SELECT_FILE: //send the file
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
sendFileByUri(uri);
}
}
break;
case REQUEST_CODE_SELECT_AT_USER:
if (data != null) {
String username = data.getStringExtra("username");
inputAtUsername(username, false);
}
break;
case REQUEST_CODE_SEND_MONEY:
if (data != null) {
sendMessage(RedPacketUtil.createRPMessage(getActivity(), data, toChatUsername));
}
break;
default:
break;
}
}
}
@Override
public void onSetMessageAttributes(EMMessage message) {
if (isRobot) {
//set message extension
message.setAttribute("em_robot_message", isRobot);
}
message.setAttribute(FXConstant.KEY_USER_INFO, DemoApplication.getInstance().getUserJson().toJSONString());
}
@Override
public EaseCustomChatRowProvider onSetCustomChatRowProvider() {
return new CustomChatRowProvider();
}
@Override
public void onEnterToChatDetails() {
if (chatType == Constant.CHATTYPE_GROUP) {
EMGroup group = EMClient.getInstance().groupManager().getGroup(toChatUsername);
if (group == null) {
Toast.makeText(getActivity(), R.string.gorup_not_found, Toast.LENGTH_SHORT).show();
return;
}
startActivityForResult(
(new Intent(getActivity(), GroupDetailsActivity.class).putExtra("groupId", toChatUsername)),
REQUEST_CODE_GROUP_DETAIL);
} else if (chatType == Constant.CHATTYPE_CHATROOM) {
startActivityForResult(new Intent(getActivity(), ChatRoomDetailsActivity.class).putExtra("roomId", toChatUsername), REQUEST_CODE_GROUP_DETAIL);
}
}
@Override
public void onAvatarClick(String username) {
//handling when user click avatar
Intent intent = new Intent(getActivity(), UserDetailsActivity.class);
intent.putExtra(FXConstant.JSON_KEY_HXID, username);
startActivity(intent);
}
@Override
public void onAvatarLongClick(String username) {
inputAtUsername(username);
}
@Override
public boolean onMessageBubbleClick(EMMessage message) {
//red packet code : 拆红包页面
if (message.getBooleanAttribute(RedPacketConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)){
RedPacketUtil.openRedPacket(getActivity(), chatType, message, toChatUsername, messageList);
return true;
}
//end of red packet code
return false;
}
@Override
public void onMessageBubbleLongClick(EMMessage message) {
// no message forward when in chat room
startActivityForResult((new Intent(getActivity(), ContextMenuActivity.class)).putExtra("message", message)
.putExtra("ischatroom", chatType == EaseConstant.CHATTYPE_CHATROOM),
REQUEST_CODE_CONTEXT_MENU);
}
@Override
public boolean onExtendMenuItemClick(int itemId, View view) {
switch (itemId) {
case ITEM_VIDEO:
Intent intent = new Intent(getActivity(), ImageGridActivity.class);
startActivityForResult(intent, REQUEST_CODE_SELECT_VIDEO);
break;
case ITEM_FILE: //file
selectFileFromLocal();
break;
case ITEM_VOICE_CALL:
startVoiceCall();
break;
case ITEM_VIDEO_CALL:
startVideoCall();
break;
case ITEM_RED_PACKET:
JSONArray jsonArray = null;
if (chatType == EaseConstant.CHATTYPE_GROUP) {
jsonArray = ACache.get(getActivity()).getAsJSONArray(toChatUsername);
}
RedPacketUtil.startRedPacketActivityForResult(this, chatType, toChatUsername, REQUEST_CODE_SEND_MONEY,jsonArray);
break;
default:
break;
}
//keep exist extend menu
return false;
}
/**
* select file
*/
protected void selectFileFromLocal() {
Intent intent = null;
if (Build.VERSION.SDK_INT < 19) { //api 19 and later, we can't use this way, demo just select from images
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
} else {
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(intent, REQUEST_CODE_SELECT_FILE);
}
/**
* make a voice call
*/
protected void startVoiceCall() {
if (!EMClient.getInstance().isConnected()) {
Toast.makeText(getActivity(), R.string.not_connect_to_server, Toast.LENGTH_SHORT).show();
} else {
startActivity(new Intent(getActivity(), VoiceCallActivity.class).putExtra("username", toChatUsername)
.putExtra("isComingCall", false));
// voiceCallBtn.setEnabled(false);
inputMenu.hideExtendMenuContainer();
}
}
/**
* make a video call
*/
protected void startVideoCall() {
if (!EMClient.getInstance().isConnected())
Toast.makeText(getActivity(), R.string.not_connect_to_server, Toast.LENGTH_SHORT).show();
else {
startActivity(new Intent(getActivity(), VideoCallActivity.class).putExtra("username", toChatUsername)
.putExtra("isComingCall", false));
// videoCallBtn.setEnabled(false);
inputMenu.hideExtendMenuContainer();
}
}
/**
* 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 8;
}
@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;
}
//red packet code : 红包消息和红包回执消息的chat row type
else if (message.getBooleanAttribute(RedPacketConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)) {
//发送红包消息
return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_RED_PACKET : MESSAGE_TYPE_SEND_RED_PACKET;
} else if (message.getBooleanAttribute(RedPacketConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {
//领取红包消息
return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_RED_PACKET_ACK : MESSAGE_TYPE_SEND_RED_PACKET_ACK;
}
//end of red packet code
}
return 0;
}
@Override
public EaseChatRow 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)){
return new ChatRowVoiceCall(getActivity(), message, position, adapter);
}
//red packet code : 红包消息和红包回执消息的chat row
else if (message.getBooleanAttribute(RedPacketConstant.MESSAGE_ATTR_IS_RED_PACKET_MESSAGE, false)) {//发送红包消息
return new ChatRowRedPacket(getActivity(), message, position, adapter);
} else if (message.getBooleanAttribute(RedPacketConstant.MESSAGE_ATTR_IS_RED_PACKET_ACK_MESSAGE, false)) {//open redpacket message
return new ChatRowRedPacketAck(getActivity(), message, position, adapter);
}
//end of red packet code
}
return null;
}
}
public EMMessageListener messageListener = new EMMessageListener() {
// implement methods in EMMessageListener
@Override
public void onMessageReceived(List<EMMessage> messages) {
for (EMMessage message : messages) {
String username = null;
// group message
if (message.getChatType() == EMMessage.ChatType.GroupChat || message.getChatType() == EMMessage.ChatType.ChatRoom) {
username = message.getTo();
} else {
// single chat message
username = message.getFrom();
}
// if the message is for current conversation
if (username.equals(toChatUsername)) {
messageList.refreshSelectLast();
EaseUI.getInstance().getNotifier().vibrateAndPlayTone(message);
} else {
EaseUI.getInstance().getNotifier().onNewMsg(message);
}
}
}
@Override
public void onCmdMessageReceived(List<EMMessage> messages) {
for (EMMessage message : messages) {
EMCmdMessageBody cmdMsgBody = (EMCmdMessageBody) message.getBody();
String action = cmdMsgBody.action();//get user defined action
if (action.equals(RedPacketConstant.REFRESH_GROUP_RED_PACKET_ACTION)) {
RedPacketUtil.receiveRedPacketAckMessage(message);
messageList.refresh();
}
}
}
@Override
public void onMessageReadAckReceived(List<EMMessage> messages) {
if(isMessageListInited) {
messageList.refresh();
}
}
@Override
public void onMessageDeliveryAckReceived(List<EMMessage> messages) {
if(isMessageListInited) {
messageList.refresh();
}
}
@Override
public void onMessageChanged(EMMessage emMessage, Object change) {
if(isMessageListInited) {
messageList.refresh();
}
}
};
@Override
public void onStop() {
super.onStop();
// unregister this event listener when this activity enters the
// background
EMClient.getInstance().chatManager().removeMessageListener(messageListener);
// remove activity from foreground activity list
EaseUI.getInstance().popActivity(getActivity());
}
@Override
public void onResume() {
super.onResume();
EMClient.getInstance().chatManager().addMessageListener(messageListener);
}
}