环信聊天开发总结
1.集成环信sdk
http://docs.easemob.com/im/200androidclientintegration/10androidsdkimport#android_sdk_介绍及导入
2.初始化环信(我用的 EaseUI,初始化都放在全局里)
EaseUI.getInstance().init(this, initOptions());
mEaseUI = EaseUI.getInstance();
//设置用户配置文件提供者
mEaseUI.setUserProfileProvider(new EaseUI.EaseUserProfileProvider() {
@Override
public EaseUser getUser(String username) {
return getUserInfo(username);
}
});
/**
* 初始化
* @return
*/
private EMOptions initOptions() {
// 设置Appkey,如果配置文件已经配置,这里可以不用设置
// options.setAppKey("lzan13#hxsdkdemo");
// 设置自动登录
EMOptions options = new EMOptions();
// 默认添加好友时,是不需要验证的,改成需要验证
options.setAcceptInvitationAlways(false);
options.setAutoLogin(true);
// 设置是否需要发送回执,
options.setRequireDeliveryAck(true);
// 设置是否需要发送已读回执
options.setRequireAck(true);
return options;
}
3.getUserInfo里写的获取用户头像(这里需要注意),因为我整个项目没有用到环信的bean类,自己也没有根据需要改成自己项目的bean类,所以我的头像存取值都是用SharedPreferences,具体的可以参照环信给的demo
自定义消息通知
mEaseUI.getNotifier().setNotificationInfoProvider(new EaseNotifier.EaseNotificationInfoProvider() {
@Override
public String getDisplayedText(EMMessage message) {
//收到通知
String ticker = EaseCommonUtils.getMessageDigest(message, mContext);
if (message.getType() == EMMessage.Type.TXT) {
ticker = ticker.replaceAll("\\[.{2,3}\\]", "[表情]");
}
EaseUser user = getUserInfo(message.getFrom());
if (user != null) {
if (EaseAtMessageHelper.get().isAtMeMsg(message)) {
return String.format("", user.getNick());
}
return user.getNick() + ": " + ticker;
} else {
if (EaseAtMessageHelper.get().isAtMeMsg(message)) {
return String.format("", message.getFrom());
}
return message.getFrom() + ": " + ticker;
}
}
@Override
public String getLatestText(EMMessage message, int fromUsersNum, int messageNum) {
//收到通知的条目数,你可以自定义话语
return "您的好友发来一条新消息";
}
@Override
public String getTitle(EMMessage message) {
return null;
}
@Override
public int getSmallIcon(EMMessage message) {
return 0;
}
@Override
public Intent getLaunchIntent(EMMessage message) {
//点击通知执行的操作
Intent intent = new Intent(mContext, ChatActivity.class);
Bundle bundle = new Bundle();
EMMessage.ChatType chatType = message.getChatType();
if (chatType == EMMessage.ChatType.Chat) {
// single chat message
intent.putExtra("userId", message.getFrom());
bundle.putString(EaseConstant.EXTRA_USER_ID, message.getFrom());
bundle.putInt(EaseConstant.EXTRA_CHAT_TYPE, EaseConstant.CHATTYPE_SINGLE);
bundle.putInt("type", 2);
intent.putExtras(bundle);
} else {
// group chat message
// message.getTo() is the group id
intent.putExtra("userId", message.getTo());
if (chatType == EMMessage.ChatType.GroupChat) {
intent.putExtra("chatType", EaseConstant.CHATTYPE_GROUP);
} else {
intent.putExtra("chatType", EaseConstant.CHATTYPE_CHATROOM);
}
}
return intent;
}
});
- 前面说我没有用bean类,我的聊天列表没有用环信的是自己定义的,我的聊天列表从自己服务器获取后就做了一个存库的操作,关于头像这块,在收到消息通知这需要做个处理(如果你的做法或者需求和我相像,这里需要注意,如果这里不处理,当你点击通知栏消息,往往头像是上一个人的,因为是用SharedPreferences,所以在这来消息的时候根据环信名和你这边的环信名做个匹配,然后重新给SharedPreferences保存下即可)
环信登录与退出
1.我现在写的项目有自己的登录,所以环信的登录在我自己的登录请求成功后登录(登录退出有俩种方法,异步与同步,具体参照环信文档)
2.环信被迫登出(在全局里设置)
- 这里需要注意的是你在被迫登出的地方执行的方法,我这里传到主activty接收值执行操作
我的主activity中启动模式是设置为singleTask(singleTask的含义只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法)
'我的主activity中启动模式是设置为singleTask(singleTask的含义只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。) '
接收消息
1、绑定消息监听
解除消息监听
2、收到消息刷新列表以及消息红点或者数字(我是用红点的)
- 步骤
刷新红点
要被刷新列表的处理(写一个公开方法,来消息需要调用这个方法刷新列表,具体见环信demo)
我在来消息这块遇到的对我来说坑是:对于新用户我需要在接收消息的方法里拿到环信给我的环信id去跟我聊天数据表里的匹配,要是没有这个人就需要通过环信id请求我自己服务器搜索这个用户,然后建立聊天关系,但是有时候自己服务器响应速度很慢,但是环信消息接收很快,红点已经亮起,但是列表人还没显示出来,所以我在更新消息红点的那个方法里用了一个tag来判断,看上图
需要请求自己服务器展示列表时,不用环信的聊天列表,需要注意的是,你需要手动的去给每一个人创建一次会话,否则后期会出现第二次进入聊天人的列表没有聊天记录等问题
关于消息列表一些数据基本展示
1、获取最新的一条消息展示
初始化conversation
- 判断消息内容是否为空,进而获取相关数据
这里遇到了使用RecyclerView时会不小心入的坑,(我使用的是notifyItemRemoved)删除列表时列表数据会出现错乱以及聊天记录会错乱,解决方法:
因为我用的RecyclerView添加了俩个头布局,在删除时要注意mList.remove(position); notifyItemRemoved(position + 2); Log.e("123", "onResponse: " + mList.size()); if (position != mList.size()) { // 如果移除的是最后一个,忽略 notifyItemRangeChanged(position + 2, mList.size() - position); }
删除完之后 notifyItemRangeChanged更新下数据
注:如果我没有点进去直接看详情聊天列表,直接删除会话列表这个人,删除时要更新未读红点或者消息数显示的那个方法