(转载)https://blog.csdn.net/u012908087/article/details/75425907

最近项目用到了环信即时通讯,需要实现发送富文本消息功能。刚开始接触也是一点思路也没有。后来经过官方的文档终于实现了这个功能,所以打算在此做一下笔记,顺便给那些想要实现这种需求而没有思路的同学一点提示。

1、首先我们先看一下官方文档给出的思路。

[java] view plain copy
  1. EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername); // 增加自己特定的属性  
  2. message.setAttribute("attribute1""value");  
  3. message.setAttribute("attribute2"true);  
  4. ...  
  5. EMClient.getInstance().chatManager().sendMessage(message);  
[java] view plain copy
  1. //接收消息的时候获取到扩展属性//获取自定义的属性,第2个参数为没有此定义的属性时返回的默认值  
  2. message.getStringAttribute("attribute1",null);  
[java] view plain copy
  1. <span style="font-family:Arial, Helvetica, sans-serif;">message.getBooleanAttribute("attribute2"false);</span>  
[java] view plain copy
  1.   

可以看出我们需要通过创建一个txt类型的消息然后通过message.setAttribute("key","value")给这个消息增加一些属性来实现这个功能,其中这里的key和value是键值对。当然只是用这个是远远不够的。

2、自定义EaseChatMessageList的item(ChatRow)

[java] view plain copy
  1. <span style="font-size:10px;">private final class CustomChatRowProvider implements EaseCustomChatRowProvider {  
  2.     @Override  
  3.     public int getCustomChatRowTypeCount() {  
  4.         //音、视频通话发送、接收共4种  
  5.         return 4;  
  6.     }  
  7.   
  8.     @Override  
  9.     public int getCustomChatRowType(EMMessage message) {  
  10.         if(message.getType() == EMMessage.Type.TXT){  
  11.             //语音通话类型  
  12.             if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)){  
  13.                 return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE_CALL : MESSAGE_TYPE_SENT_VOICE_CALL;  
  14.             }else if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)){  
  15.                 //视频通话  
  16.                 return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO_CALL : MESSAGE_TYPE_SENT_VIDEO_CALL;  
  17.             }  
  18.         }  
  19.         return 0;  
  20.     }  
  21.   
  22.     @Override  
  23.     public EaseChatRow getCustomChatRow(EMMessage message, int position, BaseAdapter adapter) {  
  24.         if(message.getType() == EMMessage.Type.TXT){  
  25.             // 语音通话、视频通话  
  26.             if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false) ||  
  27.                 message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)){  
  28.                 //ChatRowVoiceCall为一个继承自EaseChatRow的类  
  29.                 return new ChatRowVoiceCall(getActivity(), message, position, adapter);  
  30.             }  
  31.         }  
  32.         return null;  
  33.     }  
  34. }  
  35. //初始化的时候把 provider 传入  
  36. messageList.init(toChatUsername, chatType, new CustomChatRowProvider());</span>  
把写好的自定义ChatRow 通过chatRowprooider()来展示在会话页面中

以下是我自己项目中实现的方式(进入会话页面就发送富文本消息),具体需求请做相应修改,这里只做参考。
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 ;

[java] view plain copy
  1.  EMMessage message = EMMessage.createTxtSendMessage(message_title, toChatUsername);  
  2.    message.setAttribute(EaseConstant.MESSAGE_TITLE,message_title);  
  3.    message.setAttribute(EaseConstant.MESSAGE_JOB_PIC_URL,message_pic_url);  
  4.    message.setAttribute(EaseConstant.MESSAGE_URL,message_url);  
  5.    message.setAttribute(EaseConstant.MESSAGE_JOB_CONTENT,message_content);  
  6.    String userName = UserInfoKeeper.getEaseName();  
  7.    String userPic = UserInfoKeeper.getEaseUrl();  
  8.    if (!TextUtils.isEmpty(userPic)) {  
  9.        message.setAttribute(Constants.MESSAGE_USER_AVATAR, userPic); //这里也需要传入自己的头像和昵称以便接收方可以显示你的头像  
  10.    }  
  11.    if (!TextUtils.isEmpty(userName)) {  
  12.        message.setAttribute(Constants.MESSAGE_USER_NAME, userName);  
  13.    }  
  14.    message.setAttribute(EaseConstant.MESSAGE_JOB_TYPE, true); //这里是为了区分是否是富文本消息(发送富文本消息对应的value一定要为true)  
  15. 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。



相关文章: