环信IM即时通讯集成-遇到问题及创建默认会话+默认欢迎语
环信IM--创建默认会话+默认欢迎语
第一步:接入环信UI–ease-im-kit
登录环信后台,找到开发者集成文档,按照提示集成,具体步骤就不再说了。我集成是选择把源码下载下来了(便于代码编辑和查看具体实现方法)。首先简单说下我在集成过程中遇到的问题吧。如果不想看的可以直接扒拉到最下边看标题相关内容。
集成版本3.7.3
接入环信IM即时聊天功能,环信的demo是必须要借鉴的。demo里功能点是相当全的。这点还是挺值得夸奖的。稍有缺陷是有些注释方法已经过时????,由于公司项目是引用的android库,环信的demo和IM库都是androidx的了,这点需要注意下。如果公司项目已经很成熟了,就需要仔细考虑下是否要升级到androidx。最好在集成前就处理好,不然会有很多问题要处理。我就采坑了。刚开始想着把环信相关的方法转换成android的,改到一般着实进行不下去了,迫不得已还原代码。把项目整体迁移到androidx????。本来迁移androidx是下一步的计划,为了继承环信*提前了。好在最后全部处理完,当能发起聊天时给激动的啊????。
环信demo中遇到的问题
首先是最近要求越来越严格的权限问题了。一次性获取所有权限很明显不符合最新工信部的要求。所以要在特定的功能带你做权限判断,下边是项目中用到的图片消息和文件消息的权限获取。在重写的onChatExtendMenuItemClick
方法中判断相应的控件id做相关判断就行。
@Override
public void onChatExtendMenuItemClick(View view, int itemId) {
if(itemId == com.hyphenate.easeui.R.id.extend_item_take_picture) {
if (!cameraPermissions()) {
return;
}
} else if(itemId == com.hyphenate.easeui.R.id.extend_item_picture) {
if (!albumPermissions()) {
return;
}
} else if(itemId == com.hyphenate.easeui.R.id.extend_item_file) {
if (!albumPermissions()) {
return;
}
}
super.onChatExtendMenuItemClick(view, itemId);
}
如果用到语音消息的就要动态获取录音权限了,这个通过上边的方法就不再适合了。扒拉环信的代码就可以看到EaseChatInputMenu
中的
@Override
public boolean onPressToSpeakBtnTouch(View v, MotionEvent event) {
if(menuListener != null) {
return menuListener.onPressToSpeakBtnTouch(v, event);
}
return false;
}
回调了语音消息,继续查EaseChatLayout
找到
@Override
public boolean onPressToSpeakBtnTouch(View v, MotionEvent event) {
return voiceRecorder.onPressToSpeakBtnTouch(v, event, (this::sendVoiceMessage));
return false;
}
然后就发送语音了。如果要处理权限只能在这个地方做处理了。只要在这再加个回调判断就可以了:在OnChatLayoutListener
监听中添加
/**
* 用于监听语音消息的权限
* @return
*/
boolean onSpeakPermissions();`,然后修改上述方法为`@Override
public boolean onPressToSpeakBtnTouch(View v, MotionEvent event) {
if (listener.onSpeakPermissions()) {
return voiceRecorder.onPressToSpeakBtnTouch(v, event, (this::sendVoiceMessage));
}
return false;
}
最后在你自定义的聊天fragment中重写即可。
@Override
public boolean onSpeakPermissions() {
return audioPermissions();
}
创建默认会话+默认欢迎语
上边都是废话,该说正点了。需求中只用到了单聊功能,当会话列表为空时,需要默认给加一条会话并且发送一条默认欢迎语,并且这条默认欢迎语需要发送方看不到????,首先在环信的文档中找到插入消息方法:
//根据会话插入消息
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
conversation.insertMessage(message);
//直接插入消息
EMClient.getInstance().chatManager().saveMessage(message);
接下来尝试了,发现message构造怎么都加不进去,找到EMMessage
类中注释:
* <p>
* 构造一条文本发送消息
* <pre>
* EMMessage msg = EMMessage.createSendMessage(EMMessage.Type.TXT);
* msg.setTo("user1");
* TextMessageBody body = new TextMessageBody("hello from hyphenate sdk");
* msg.addBody(body);
* </pre>
尝试发现TextMessageBody
对象无法实例,和环信技术人员沟通后找到了一个方法,如下,可以创建出一条会话和一条欢迎语了,但是欢迎语是自己发出的,这不太符合需求:
/**
* \~chinese
* 创建一个文本发送消息
* @param content 文本内容
* @param username 消息接收人或群id
* @return
*
* \~english
* @param content text content
* @param username the recipient(user or group) id
* @return
*/
public static EMMessage createTxtSendMessage(String content, String username){
if (content.length() > 0) {
EMMessage msg = EMMessage.createSendMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody(content);
msg.addBody(txtBody);
msg.setTo(username);
return msg;
}
EMLog.e(TAG, "text content size must be greater than 0");
return null;
}
继续找环信技术人员沟通,告知可以采用REST方法,发送一条消息给自己。但环信官方文档是不建议app端使用REST方法的,那就要涉及到和自己的接口进行交易了,这也太麻烦了。本来准备放弃了,就按照他们说的方案实行。但想着聊天基本上都是从本地数据库读取的数据,没道理自己不能添加啊。继续翻看环信的SDK,终于不负苦心人,让我找到了一个绝佳的方法????
@Override
public void onMessageRecalled(List<EMMessage> messages) {
EaseEvent event = EaseEvent.create(EaseImConstant.MESSAGE_CHANGE_RECALL, EaseEvent.TYPE.MESSAGE);
messageChangeLiveData.with(EaseImConstant.MESSAGE_CHANGE_CHANGE).postValue(event);
for (EMMessage msg : messages) {
if(msg.getChatType() == EMMessage.ChatType.GroupChat && EaseAtMessageHelper.get().isAtMeMsg(msg)){
EaseAtMessageHelper.get().removeAtMeGroup(msg.getTo());
}
EMMessage msgNotification = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody(String.format(context.getString(R.string.msg_recall_by_user), msg.getFrom()));
msgNotification.addBody(txtBody);
msgNotification.setFrom(msg.getFrom());
msgNotification.setTo(msg.getTo());
msgNotification.setUnread(false);
msgNotification.setMsgTime(msg.getMsgTime());
msgNotification.setLocalTime(msg.getMsgTime());
msgNotification.setChatType(msg.getChatType());
msgNotification.setAttribute(EaseImConstant.MESSAGE_TYPE_RECALL, true);
msgNotification.setStatus(EMMessage.Status.SUCCESS);
EMClient.getInstance().chatManager().saveMessage(msgNotification);
}
}
如上所示,撤回消息时,会往本地插入一条消息,该消息是模拟的对方发送给自己的一条。只要把消息内容换成自己的,很明显符合需求了????。剩下的就是怎么知道会话列表为空,查到EaseConversationListLayout
中有一个方法:
@Override
public void loadConversationListNoData() {
if(loadListener != null) {
loadListener.loadDataFinish(new ArrayList<>());
}
}
当会话列表为空的时候会执行回调loadDataFinish
,剩下的就是在会话列表Fragment中复写loadDataFinish
方法,然后:
/**
* 加载完成回调
* @param data 加载完成的数据集合
*/
@Override
public void loadDataFinish(List<EaseConversationInfo> data) {
super.loadDataFinish(data);
if (data == null || data.size() <= 0) {
//根据会话插入消息
// EMMessage msg = EMMessage.createTxtSendMessage("hello from hyphenate sdk", "这个是发送id");
// EMClient.getInstance().chatManager().saveMessage(msg);
EMMessage msgNotification = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody("hello from hyphenate sdk");
msgNotification.addBody(txtBody);
msgNotification.setFrom("这个是发送id");
msgNotification.setTo("这个是接收id");
msgNotification.setUnread(true);
// msgNotification.setMsgTime(msg.getMsgTime());
// msgNotification.setLocalTime(msg.getMsgTime());
msgNotification.setChatType(EMMessage.ChatType.Chat);
msgNotification.setAttribute(EaseImConstant.MESSAGE_TYPE_RECALL, true);
msgNotification.setStatus(EMMessage.Status.SUCCESS);
EMClient.getInstance().chatManager().saveMessage(msgNotification);
conversationListLayout.loadDefaultData();
}
}
然后展示下最终实现的效果:
本文地址:https://blog.csdn.net/kuixiaoba/article/details/112482284
上一篇: Android 打包镜像对权限的管理
下一篇: 和幽默相视而笑