欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

环信IM即时通讯集成-遇到问题及创建默认会话+默认欢迎语

程序员文章站 2022-11-01 16:58:25
环信IM--创建默认会话+默认欢迎语第一步:接入环信UI--ease-im-kit集成版本3.7.3环信demo中遇到的问题第一步:接入环信UI–ease-im-kit登录环信后台,找到开发者集成文档,按照提示集成,具体步骤就不再说了。我集成是选择把源码下载下来了(便于代码编辑和查看具体实现方法)。首先简单说下我在集成过程中遇到的问题吧。如果不想看的可以直接扒拉到最下边看标题相关内容。集成版本3.7.3接入环信IM即时聊天功能,环信的demo是必须要借鉴的。demo里功能点是相当全的。这点还是挺值得...

第一步:接入环信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();
        }
    }

然后展示下最终实现的效果:
环信IM即时通讯集成-遇到问题及创建默认会话+默认欢迎语

本文地址:https://blog.csdn.net/kuixiaoba/article/details/112482284