最近项目的聊天模块中增加了一个消息已读回执的功能,从技术上不是很难实现,但还是在这里记录一下,以便以后查阅。

所谓的消息已读回执,就是双方聊天时,如果对方看到了你新发的信息,这条消息在你这端就会标为“已读”,否则将是“未读”。

A发送一条消息给B,B接收了,如果B此时打开聊天主界面,查看了消息,B就再发一条“回执”(携带有B已读的消息Id)给A,A这时根据“回执”中的消息Id,标注已读。

那么根据整个功能流程,首先,我们要对消息model进行一下改造,增加一个状态位的属性toReadState,来区分消息是否被对方读了;还需要增加一个属性toReadMessageId,这个属性主要用在“回执”当中,用来告诉对方,我读了你的哪条消息,以便对方标注。

public int toReadStatus;public String toReadMessageId;

这样改造过后,如果消息带有toReadMessageId,那么它就不是一条消息,而是一条“回执”,而“回执”是不需要显示在会话列表或聊天面板中的,因此,我们需要在接收消息的时候判断一下,如果是“回执”,则不显示也不存储到数据库中。

接收消息主要有两个场景:1.会话列表 2.聊天主界面

如图:

    

因此在发送回执的时候也要根据场景分成两种情况,在会话列表中,我们肯定不能将消息状态置为已读,只有打开聊天主界面,并且此条消息在屏幕中时,才可以发送回执。因此,在我们打开主界面时,我们要判断一下有哪些消息是处于未读状态并且是处于当前屏幕上的,将这些状态的回执发给对方:

/*** 批量发送回执给对方并更新界面和数据库* @param firstVisibleItem 屏幕中第一条可见消息*/private void sendToReadMessage(int firstVisibleItem) {if (messageInfos != null && messageInfos.size() != 0) {SQLiteDatabase db = DBHelper.getInstance(mContext).getReadableDatabase();MessageTable messageTable = new MessageTable(db);for (int i = firstVisibleItem; i < messageInfos.size(); i++) {MessageInfo messageInfo = messageInfos.get(i);// 状态位为0,并且不能是自己发的消息if (messageInfo.toReadState == 0 && !messageInfo.fromid.equals(ResearchCommon.getUserId(mContext))) {messageInfo.toReadState = 1;//发送回执sendReadState(messageInfo.id);
//保存到数据库中
messageTable.update(messageInfo);//更新显示mAdapter.notifyDataSetChanged();}}}}
/*** 发送回执给对方* @param id 已读的MessageId*/private void sendReadStatus(String id) {send();MessageInfo msg = new MessageInfo();msg.fromid = ResearchCommon.getUserId(mContext);msg.tag = UUID.randomUUID().toString();msg.fromname = mLogin.nickname;msg.fromurl = mLogin.headsmall;msg.toid = fCustomerVo.uid;msg.toname = getFromName();msg.tourl = fCustomerVo.headsmall;msg.typefile = MessageType.TEXT;msg.content = "";msg.typechat = mType;msg.time = System.currentTimeMillis();msg.readState = 1;
//告诉对方已读哪条信息
msg.toReadMessageId = id;sendBroad2Save(msg, false, true);}

在聊天主界面中发送回执则比较简单:

// 接受消息private void notifyMessage(final MessageInfo msg) {if (msg == null) {return;}handler.post(new Runnable() {@Overridepublic void run() {try {// 当该信息不来自好友就过滤掉!if (msg.getFromId().equals(ResearchCommon.getUserId(mContext))) {return;}//如果不是回执if (msg.toReadMessageId.equals("-1")) {messageInfos.add(msg);//更新头像updateUserHead(msg);mAdapter.notifyDataSetInvalidated();if (messageInfos.size() == 1|| (mListView.getLastVisiblePosition() == messageInfos.size() - 2)) {mListView.setSelection(messageInfos.size() - 1);}//发送已读回执sendReadStatus(msg.id);startDeleteTimer(msg);} else {//如果是回执的话就根据id更新已读状态updateReadState(msg.toReadMessageId);}} catch (Exception e) {}}});}
private void updateReadState(String id) {if (mType == GlobleType.SINGLE_CHAT) {for (int i = 0; i < messageInfos.size(); i++) {final MessageInfo messageInfo = messageInfos.get(i);if (id.equals(messageInfo.id)) {messageInfo.toReadStatus = 1;SQLiteDatabase db = DBHelper.getInstance(mContext).getReadableDatabase();MessageTable messageTable = new MessageTable(db);messageTable.update(messageInfo);mAdapter.notifyDataSetInvalidated();startDeleteTimer(messageInfo);}}}}

还有一点需要注意的是,在监听新消息广播的时候也要判断一下该消息的类型,如果是回执类型就不要存储或在系统通知栏进行提示。

#即时通讯#实现消息已读回执功能的思路与实现相关推荐

  1. IM消息重试机制Java实现_IM群聊消息的已读回执功能该怎么实现?

    本文引用了架构师之路公众号作者沈剑的文章,内容有改动,感谢原作者. 1.前言我们平时在使用即时通讯应用时候,每当发出一条聊天消息,都希望对方尽快看到,并尽快回复,但对方到底有没有真的看到?我却并不知道 ...

  2. 注册申请企业邮箱后如何使用,企业邮箱有已读回执功能吗?

    外贸公司的邮件使用量大,而且还有时差,所以大家已读回执功能可以很好的解决这一问题,了解到对方有没有查看自己发出的邮件.下面以TOM企业邮箱为例,介绍下已读回执怎么操作呢? 第一步:从企业邮箱用户入口登 ...

  3. im即时通讯开发:IM群聊消息的已读回执功能

    我们平时在使用即时通讯应用时候,每当发出一条聊天消息,都希望对方尽快看到,并尽快回复,但对方到底有没有真的看到?我却并不知道. 一个残酷的现实是,很多时候对方其实是早就已经看到了这条消息,但出出种种原 ...

  4. IM即时通讯开发群聊消息的已读回执功能该怎么实现?

    我们平时在使用即时通讯应用时候,每当发出一条聊天消息,都希望对方尽快看到,并尽快回复,但对方到底有没有真的看到?我却并不知道.一个残酷的现实是,很多时候对方其实是早就已经看到了这条消息,但出出种种原因 ...

  5. java 邮件 已读回执_java – 在Firebase群组消息传递应用中实施已读回执功能

    为此,您需要在名为seenBy的Firebase数据库中添加另一个节点,该节点必须嵌套在meassage部分中的每个messageId下.您的数据库应如下所示: Firebase-root | --- ...

  6. 消息已读,这件皇帝的新装,​脱掉算了

    文/明道云创始人任向晖 这两天看到钉钉负责人不穷的一个采访视频,勾起了我对往事的回忆.他说他最烦周末被人钉和写周报. 不穷作为钉钉管理层的继任者发表这样的言论我能够理解.毕竟钉钉的核心功能不是他设计的 ...

  7. IM热门功能讨论:为什么微信里没有消息“已读”功能?...

    本文原文由"狼和哈士奇"原创分享,本次内容有改动. 1.引言 张小龙说:微信消息不做"已读"和"未读"的功能,是因为要给人撒谎的机会,这才符 ...

  8. IM热门功能讨论:为什么微信里没有消息“已读”功能?

    本文原文由"狼和哈士奇"原创分享,本次内容有改动. 1.引言 张小龙说:微信消息不做"已读"和"未读"的功能,是因为要给人撒谎的机会,这才符 ...

  9. 群消息已读回执(这个屌),究竟是推还是拉?

    每当发出一条微信消息,都希望对方尽快看到,并尽快回复,但始终不知道对方是否阅读. 每当收到一条不能立马回复的微信消息,都默默返回,假装没看见. 画外音:不想回复的人,唉,你只是个好人. 微信用于个人社 ...

最新文章

  1. ueeditor 百度编译器使用onchange效果
  2. warning: directory not found for option“XXXXXX”
  3. SQL Server开发接口生成方法
  4. 论文小综 | 知识图谱中的复杂查询问答
  5. java接口文档生成工具_接口文档生成
  6. 信息学奥赛一本通 1131:基因相关性 | OpenJudge NOI 1.7 03
  7. python指定时间范围数据_Python提取特定时间段内数据的方法实例
  8. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_5_同步技术的原理...
  9. 【图像配准】基于matlab GUI互相关图像配准【含Matlab源码 853期】
  10. web开发必备的几个软件
  11. win10系统如何查找字体库位置+在matplotlib散点图中的应用+散点图中显示不了中文
  12. 如何做肌电信号手势识别?
  13. html怎么做一个动态广告图,用CSS3实现广告的展示动画特效
  14. ECHO、IF、REM等命令介绍
  15. Egret 使用Texture Merger制作美术字体
  16. 【MySql 数据库综合练习01 】
  17. ES module与commonjs的区别
  18. 电信传输_第六章_光纤接入网
  19. 记账本记录日常收支 如何查看某个时间段的明细
  20. 请问我接的宽带网线里面那些带颜色的线是什么顺序?

热门文章

  1. 如何撰写项目的解决方案
  2. C/C++ 实现内存特征码搜索
  3. valgrind 工具介绍和简单的使用
  4. DEFORM文本模式(4):后处理结果的提取
  5. 《源码阅读》专栏系列开篇 - 当Java工程师的这几年
  6. Arduino使用 旋转电位器
  7. 并行计算中的Fortran语言
  8. mac下安装cherrytree
  9. 因特网控制报文协议ICMP
  10. Photoshop cc 2017