android即时通讯,基于环信3.3.4版本,基础功能开发详解,一步一步带你实现。

近期,由于公司新开项目,涉及即时通讯,几经对比,选择了环信平台。话不多说,进入正题。

大纲:

1.环信SDK集成,http://docs.easemob.com/im/200androidclientintegration/10androidsdkimport,打开链接,完成最基础的sdk集成,并且初始化SDK,这一步我就略过了。

2.聊天准备,注册,登录,退出登录,设置环信服务连接监听,设置消息接收监听

3.添加好友

4.好友消息列表处理(根据最后聊天发送时间排序)

5.聊天界面消息发送,接收处理

以下是项目中使用环信sdk完成的功能清单:

聊天界面(1对1好友聊天):

发送消息类别:文字,语音,图片,位置。

好友列表:聊天好友会话列表。

好友消息列表效果图

2.聊天准备,注册,登录,退出登录,设置环信服务连接监听,设置消息接收监听

2.1-注册

注册环信聊天账号,密码,用于app客户端基于环信服务器聊天。这一块,本项目是由后台接口注册,登录后返回,也就是说环信聊天账号的注册交由后台创建,客户端只需在登录成功后返回接收即可。当然可以根据自身需求,也可自己创建。

环信sdk文档是这样描述的:

注册模式分两种,开放注册和授权注册。只有开放注册时,才可以客户端注册。

开放注册是为了测试使用,正式环境中不推荐使用该方式注册环信账号;

授权注册的流程应该是您服务器通过环信提供的 RESTAPI注册,之后保存到您的服务器或返回给客户端。

注册用户名会自动转为小写字母,所以建议用户名均以小写注册。(强烈建议开发者通过后台调用 REST 接口去注册环信 ID,客户端注册方法不提倡使用。)

//注册失败会抛出HyphenateException

EMClient.getInstance().createAccount(username, pwd);//同步方法 (不推荐客户端注册)

2.2-登录

app登录成功之后,获取后台创建好的username,password。值得注意的是,回调的三个方法都是位于子线程,不能够在方法体内做ui操作。

调用环信api,EMClient.getInstance().login(userName,password,new EMCallBack());进行环信账号登录。

调用环信登录

EMClient.getInstance().groupManager().loadAllGroups();

EMClient.getInstance().chatManager().loadAllConversations();

以上两个方法是为了保证进入主页面后本地会话和群组都 load 完毕,根据自身业务调用,除登录api成功回调使用,建议每次启动app都在启动页调用一次。

退出登录,直接调用 EMClient.getInstance().logout(true)即可;

环信登录成功后,默认为自动登录,可按需求取消自动登录options.setAutoLogin(false)。

EMClient.getInstance().isLoggedInBefore(),判断环信账号登录状态

2.3-(成功登录环信后)设置环信服务连接监听

注册连接监听,可用作监听设备登录唯一,发生多点登录,作出提示。只需在注册一次即可,建议在应用首页注册,这样首页不销毁就可以做到全局监听的效果,进入app注册监听。

退出app时,调用EMClient.getInstance().removeConnectionListener(MyConnectionListener);销毁监听。MyConnectionListener类实现了EMConnectionListener接口

2.3-(成功登录环信后)设置环信消息接收监听

EMClient.getInstance().chatManager().addMessageListener(msgListener);只需在注册一次即可,建议在应用首页注册,这样首页不销毁就可以做到全局监听的效果,进入app注册监听,退出app调用EMClient.getInstance().chatManager().removeMessageListener(msgListener);

值得注意的是,EMMessageListener的众多回调方法中, onMessageReceived(List messages)是最重要的方法,所有消息接收都在此方法中,但是看方法的参数,竟然是list集合,这里面我们只需要获取list里面的第一个数据即可,List<EMMessage> message = messages.get(0);,这条是最新的消息。EMMessageListener的回调方法依然是在子线程中,所以需要配合handler进行ui操作。

消息接收处理
handler 消息接收

首先是注册监听,我是在MainActivity首页设置的,UserBiz.isLogin() && EMClient.getInstance().isLoggedInBefore()双重判断用户是否已登录,环信账号登录。EMReceiveBiz是我自己写一个处理消息接收的业务类,全局只在MainActivity注册一次监听,避免收到多次消息。

关于MyConnectionListener,上面已经有介绍。与消息监听同理。

设置消息监听,连接监听

然后是销毁监听,当退出app时,把注册的2个监听销毁

EMClient.getInstance().removeConnectionListener(eMConnectionListener);

EMClient.getInstance().chatManager().removeMessageListener(emReceiveBiz.msgListener);

EMReceiveBiz里面用到了handler,所以为了防止内存泄露,把handler监听销毁。

销毁监听

3.添加好友

EMClient.getInstance().contactManager().setContactListener(newEMContactListener()); 注册好友监听

//参数为要添加的好友的username和添加理由

EMClient.getInstance().contactManager().addContact(toAddUsername, reason);

一般添加好友除了环信平台添加好友,本地接口也需要添加到好友列表,所以reason根据需求设置参数,比如本地接口添加好友需要用户userId,那么可以将reason设置为自己的userId,发送成功后,对方将在onContactInvited方法中获取到你的环信账号,与你的userId,这样再处理接收好友请求,调用本地接口添加好友。

添加好友监听

4.好友消息列表处理(根据最后聊天发送时间排序)

我们看到QQ,微信也好,消息列表的排序,都是按发送时间为基准,发送时间距离当前时间越近排序越靠前。

这里面环信并没有直接提供这样的api。所以需要我们自己基于环信api做排序处理。

我把自己处理的代码发出来,List<UserFriend> dataList 是项目中调取本地好友接口获取的好友列表。

EMClientMsgBiz clientBiz1 =newEMClientMsgBiz();

clientBiz1.setImAccount(o1.getFriendImAccount());

List lastMsgInfo1 = clientBiz1.getMessage(1); 

o1.getFriendImAccount()是该好友的环信账号,然后 调取环信api,getMessage(pagerNum),pagerNum代表获取多少条数据,这里我们只需要获取最新的消息记录,所以设置为1即可获得与该好友的最后一条聊天EMMessage,如果没有一个消息记录,则conversation==null,所以new 一个集合返回,否则有空指针异常。

获取好友聊天记录api

EMMessage  环信聊天消息实体类,我们调用EMMessage.getMsgTime(,获取消息发送时间,然后把整个列表的会话排序即可。下面的方法便是比对消息发送时间的进行排序。Collections.sort(List list,Comparator c);是java.util中Collections类中的方法,不了解的可以去查看一下。这样好友消息会话列表的排序就处理好了

消息会话列表时间排序方法

接下来处理会话列表的显示问题。我这里的处理方式是在adapter里面处理的。

处理方式大同小异,通过UserFriend里面的friendImAccount,调取环信api,获取未读消息数量getUnreadMsgCount,获取最后消息发送时间getMsgTime(消息类型为long,时间戳为毫秒数,如何显示按需求处理),获取最后消息发送内容 EaseCommonUtils.getMessageDigest(lastMsgInfo1.get(0))。

好友消息列表显示处理

EaseCommonUtils环信easeui demo里面的工具类,专门处理环信消息类型简写。

消息类型处理显示

5.聊天界面消息发送,接收处理。

到了这一步,聊天准备工作都做好了,接下来可以选择聊天对象,发送聊天消息和接收聊天消息。

上一步说到UserFriend,这个好友实体,是本地接口返回的数据,这是我自己项目中定义的变量,下面三个是自己定义的,接口不返回这些数据,而是由环信api获取到的,用于好友消息列表展示

接口服务返回实体变量定义

有了UserFriend这个实体,我们带入聊天界面,就可以通过好友的环信账号,调用历史消息记录,未读消息数量清零,发送聊天消息环信api等等。接下来会讲到。

EMClientChatBiz 是专门处理聊天界面调用环信api的业务类,进入聊天界面显进行初始化,并且设置消息发送监听。OnSendMsgListener是自定义的回调接口。

chat聊天界面更新ui

emClientBiz.setChatUsernameId(userFriendInfo); 把好友的环信账号传入EMClientChatBiz,这样可以调用相关api方法。

5.1-EMClientChatBiz,聊天业务处理类,会一一详细介绍

现在,发送各类消息,MessageInfo实体是本地定义的,根据发送内容设置,并且转换成相应类型的EMMessage实体。

发送消息逻辑处理

各类消息的创建,其中发送地理位置,携带了定位截图,是以EMMessage.createImageSendMessage()方法创建的,因为环信api中创建位置消息,并不能携带图片,因此才通过创建图片消息,附带自定义属性将经纬度等信息发送。这个有点投巧,暂时没想出好的办法。

各类消息创建

首先设置消息发送监听,message.setMessageStatusCallback(newEMCallBack(){}); 每条消息的发送都需要设置消息监听,以便正确显示发送状态,显示相应的ui。

消息发送,并设立监听,设置消息为发送中

消息发送,并设立监听,设置消息为发送中

根据发送监听回调修改消息状态

修改消息状态

EMCallBack,其回调方法都是子线程,所以采用handler,更新ui

通过自定义监听,返回消息状态,更新ui

发送消息处理完,接下来就是聊天界面接收消息处理了。接收消息上面有说道,在首页设置了消息接收的全局监听,现在我们就利用消息监听,来处理聊天界面的消息接收。还是拿之前的图来讲。ActivityTask,FragmentTask是管理类,存放堆栈的实例,不理解的可以查看这篇博客

http://blog.csdn.net/u010635353/article/details/49681659

,sendDataToActivity类似于EventBus或者广播通知,携带参数。

消息分发处理

这里主要将收到的消息传递到三个地方,如果当前界面是在聊天界面,那么将EMMessage传递到聊天界面。这里只介绍聊天界面的消息接收。

收到消息后,取出EMMessage,然后emMessage.getFrom(),获取发送人的环信账号,与当前聊天对象的环信账号比对,一致则加入消息列表,这样处理主要防止好友消息乱入,比如你与A聊天,好友B发你的消息你也可以接收到,如果正在聊天界面,不做处理,这条消息就会插入到聊天界面的消息列表中。

msgId也是同样道理,如果出现同一时间收到多条重复消息,那么他的msgId必定是一致的,所以也做了过滤处理。

消息接收处理

6.消息展示处理

文字消息获取

图片消息获取

还可以获取图片宽高,这样可以固定控件尺寸,imgBody.getWidth(),imgBody.getHeight()

位置消息获取,由于位置消息是通过图片类型发送的,因此接收还是图片类型,但是先判断自定义的属性是否为null,null会产生异常,所以这个图片消息不是位置消息。

语音消息  

isListened()该条消息是否已读
获取语音地址,点击播放
播放时调用,设置消息为已读,一定要调用,否则不会更改未读状态

最后,还有几条实用的api,可以使用。

指定会话消息未读数清零
退出聊天界面,销毁监听,与该好友的未读消息清零
下拉加载更多,获取消息聊天记录
获取聊天历史
项目中用到的环信相关业务类

EMClientChatBiz:聊天界面使用,发送消息

EMClientFriendBiz:添加好友,好友相关api

EMClientLoginBiz:登录,退出环信账号

EMClientMsgBiz:环信消息相关api,未读,获取消息数,主要用于好友会话列表

EMClientReceiveBiz:聊天消息接收,消息分发

这样结合自身需求,一个基础聊天功能就出来了。还没有使用过环信并且有这方面需求的的朋友可以自己动手试试,有什么不明白的地方可以留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容