(转载)https://blog.csdn.net/u012908087/article/details/75425907
最近项目用到了环信即时通讯,需要实现发送富文本消息功能。刚开始接触也是一点思路也没有。后来经过官方的文档终于实现了这个功能,所以打算在此做一下笔记,顺便给那些想要实现这种需求而没有思路的同学一点提示。
1、首先我们先看一下官方文档给出的思路。
- EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername); // 增加自己特定的属性
- message.setAttribute("attribute1", "value");
- message.setAttribute("attribute2", true);
- ...
- EMClient.getInstance().chatManager().sendMessage(message);
- //接收消息的时候获取到扩展属性//获取自定义的属性,第2个参数为没有此定义的属性时返回的默认值
- message.getStringAttribute("attribute1",null);
- <span style="font-family:Arial, Helvetica, sans-serif;">message.getBooleanAttribute("attribute2", false);</span>
可以看出我们需要通过创建一个txt类型的消息然后通过message.setAttribute("key","value")给这个消息增加一些属性来实现这个功能,其中这里的key和value是键值对。当然只是用这个是远远不够的。
2、自定义EaseChatMessageList的item(ChatRow)
- <span style="font-size:10px;">private final class CustomChatRowProvider implements EaseCustomChatRowProvider {
- @Override
- public int getCustomChatRowTypeCount() {
- //音、视频通话发送、接收共4种
- return 4;
- }
- @Override
- public int getCustomChatRowType(EMMessage message) {
- if(message.getType() == EMMessage.Type.TXT){
- //语音通话类型
- 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)){
- //视频通话
- return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO_CALL : MESSAGE_TYPE_SENT_VIDEO_CALL;
- }
- }
- return 0;
- }
- @Override
- public EaseChatRow getCustomChatRow(EMMessage message, int position, BaseAdapter adapter) {
- if(message.getType() == EMMessage.Type.TXT){
- // 语音通话、视频通话
- if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) ||
- message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)){
- //ChatRowVoiceCall为一个继承自EaseChatRow的类
- return new ChatRowVoiceCall(getActivity(), message, position, adapter);
- }
- }
- return null;
- }
- }
- //初始化的时候把 provider 传入
- messageList.init(toChatUsername, chatType, new CustomChatRowProvider());</span>
以下是我自己项目中实现的方式(进入会话页面就发送富文本消息),具体需求请做相应修改,这里只做参考。
3、具体代码实现
首先我们需要定义一些常量以便能统一调用(常量名字及解释只做参考,请按实际需求来定义)
public static final String MESSAGE_JOB_PIC_URL = "message_job_pic_url" ; //图片
public static final String MESSAGE_JOB_CONTENT = "message_job_content" ; //内容
public static final String MESSAGE_JOB_STAGE = "message_job_stage" ; //阶段
public static final String MESSAGE_JOB_ID = "message_job_id" ; //类型
public static final String MESSAGE_TITLE = "message_title"; //消息标题
public static final String MESSAGE_URL = "message_url" ; //消息Url
public final static String MESSAGE_USER_AVATAR ="message_user_avatar" ; //当前用户的头像
public final static String MESSAGE_USER_NAME ="message_user_name" ; //当前用户的昵称
public static final String MESSAGE_JOB_TYPE = "message_job_type"; //作为区分自己定义的消息
我们需要在会话页面ChatFragment.java中添加一下代码(这里)
private static final int MESSAGE_TYPE_SENT_RICH_JOB = 6 ;
private static final int MESSAGE_TYPE_RECV_RICH_JOB = 7 ;
- EMMessage message = EMMessage.createTxtSendMessage(message_title, toChatUsername);
- message.setAttribute(EaseConstant.MESSAGE_TITLE,message_title);
- message.setAttribute(EaseConstant.MESSAGE_JOB_PIC_URL,message_pic_url);
- message.setAttribute(EaseConstant.MESSAGE_URL,message_url);
- message.setAttribute(EaseConstant.MESSAGE_JOB_CONTENT,message_content);
- String userName = UserInfoKeeper.getEaseName();
- String userPic = UserInfoKeeper.getEaseUrl();
- if (!TextUtils.isEmpty(userPic)) {
- message.setAttribute(Constants.MESSAGE_USER_AVATAR, userPic); //这里也需要传入自己的头像和昵称以便接收方可以显示你的头像
- }
- if (!TextUtils.isEmpty(userName)) {
- message.setAttribute(Constants.MESSAGE_USER_NAME, userName);
- }
- message.setAttribute(EaseConstant.MESSAGE_JOB_TYPE, true); //这里是为了区分是否是富文本消息(发送富文本消息对应的value一定要为true)
- sendMessage(message);
这里的参数都是通过intent跳转带过来的比如 :直接new Intent(context,ChatActivity);
接下来我们需要去CustomChatRowProvider这个内部类里面去设置发送接收,大家需要注意getCustomChatRowTypeCount(){}方法里面必须要加上2,这个2的意思就是说发送和接收名片,当然我们需要在getCustomChatRowType()和getCustomChatRow()中添加以下代码(EaseChatRowRichJobText是富文本消息item)
然后我们需要在EaseMessageAdapter中添加相对应的信息(这些常量的值需要根据自己的需求变化而改变这里这做参考)
private static final int MESSAGE_TYPE_SENT_VOICE = 10;
private static final int MESSAGE_TYPE_RECV_VOICE = 11;
需要在对应的getViewTypeCount()、getItemViewType()和creatChatRow()方法添加代码片段其中getViewTypeCount()的返回值加上对应的总数,一定要对应,不然会报数组越界
当然具体的EaseChatRowRichJobText怎么实现,请参考环信中的ChatRowVoiceCall.java的实现方式
以上就是我得大致思路,当然这里也借鉴了一些前辈的经验 比如: http://www.imgeek.org/article/8253079
欢迎提供不同的实现方法。如果有问题请加QQ:2825292684。