环信Android客户端集成文档

Posted kn923

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了环信Android客户端集成文档相关的知识,希望对你有一定的参考价值。

一、Android SDK简介

  1. 环信SDK为用户开发IM相关的应用提供的一套完善的开发框架。 包括以下几个部分:

    • SDK_Core为核心的消息同步协议实现,完成与服务器之间的信息交换。
    • SDK是基于核心协议实现的完整的IM功能,实现了不同类型消息的收发、会话管理、群组、好友、聊天室等功能。
    • EaseUI是一组IM相关的UI控件,旨在帮助开发者快速集成环信SDK。
  2. SDK采用模块化设计,每一模块的功能相对独立和完善,用户可以根据自己的需求选择使用下面的模块:

    • EMClient: SDK的入口,主要完成登录、退出、连接管理等功能。也是获取其他模块的入口。
    • EMChatManager: 管理消息的收发,完成会话管理等功能。
    • EMContactManager: 负责好友的添加删除,黑名单的管理。
    • EMGroupManager: 负责群组的管理,创建、删除群组,管理群组成员等功能。
    • EMChatroomManager: 负责聊天室的管理。

二、Android SDK集成

  1. 集成前准备:注册并创建应用

    • 注册环信开发者账号:
      • 在环信官网上点击“即时通讯云”,并点击“免费使用”,跳转到环信管理后台注册页面。
      • 在注册页面中填写详细资料,企业ID:只限于数字、字母、横线,且不能以横线开头和结尾。企业ID会存在于生成的AppKey中。如:测试Demo中AppKey为easemob-demo#chatdemo,则easemob-demo为填写的企业ID。
        注:如果是个人应用开发的话,企业ID直接写成自己定义的ID就可以。
      • 点击注册。注册成功后,我们会向您填写的邮箱中发送验证信息,请前往邮箱进行账号激活。
    • 创建应用:
      • 账号激活成功后,回到控制台登录页面登录到开发者后台,在我的应用中,点击创建应用按钮。
      • 填写创建应用的名称(内容只限于数字、大小写字母),(应用名称会存在于你生成的AppKey中,如:测试Demo中AppKey为easemob-demo#chatdemo,则chatdemo为填写的应用名称。注册授权根据需要自行选择。)
      • 填写好应用名称后,点确定。创建成功,系统会为你生成AppKey以及相关配置信息。
        之后我们需要将AppKey配置到工程里。
  2. 下载SDK :到环信官网下载环信SDK。

  3. SDK目录讲解:从官网下载的SDK目录包含了4个文件夹,如下:

    • doc文件夹:SDK相关API文档
    • examples文件夹:ChatDemoUI(老的Demo,不推荐使用)、ChatDemoUI3.0(3.0Demo依赖EaseUI库)、EaseUI
    • libs文件夹:包含IM和实时音视频功能所需要的jar和so文件
    • libs.without.audio文件夹:无实时语音、实时视频功能的SDK包,如果项目中只用到聊天功能,可以把项目里的jar和so文件替换成此文件夹里的
  4. 第三方类库介绍:

    • SDK中用到的第三方库:
      • android-support-v4.jar:这个可以说是每个APP中都是不可缺少的jar包,这里不多赘述
      • google-play-services.jar:GCM(Google云消息传递)的jar包,不需要GCM推送可以删除
      • MiPush_SDK_Client_2_2_19.jar:小米推送的jar包,不需要可以删除
      • org.apache.http.legacy.jar:Android6.0中默认移除了httpclient的代码,用这个库兼容,建议不要删除,否则在6.0系统中,SDK会有问题
    • EaseUI中用到的第三方库:
      • glide-3.6.1.jar:图片处理库,显示用户头像时用到
      • BaiduLBS_Android.jar:百度地图的jar包,相关so还有libBaiduMapSDK_base_v3_6_1.so、libBaiduMapSDK_map_v3_6_1.so、libBaiduMapSDK_util_v3_6_1.so及liblocSDK6a.so。如果不用百度可以把这些删除掉,删除掉后项目会报错,修改相应的报错(报错的代码很少,很容易就修改完成)
    • Demo中用到的第三方库:
      • android-support-multidex.jar:APP总方法数超过64k时,需要用这个库做分包处理,可以删除
      • 其他的不再进行介绍
  5. 配置工程:
    • 导入SDK:在自行开发的应用中,集成环信聊天需要把libs文件夹下的jar及so文件复制到你的项目的libs文件夹相应位置,如果不需要语音和视频通话功能,导入libs.without.audio下的文件即可。
    • 配置信息:在清单文件AndroidManifest.xml里加入以下权限,以及写上你注册的AppKey。
  6. APP打包混淆: 在ProGuard文件中加入以下keep。
    -keep class com.hyphenate.* {;}
    -dontwarn com.hyphenate.**

    注:清单文件的配置示例
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <!-- 设置环信应用的AppKey -->
    <meta-data android:name="EASEMOB_APPKEY" android:value="Your AppKey" />
    <!-- 声明SDK所需的service SDK核心功能-->
    <service android:name="com.hyphenate.chat.EMChatService" android:exported="true"/>
    <!-- 声明SDK所需的receiver -->
    <receiver android:name="com.hyphenate.chat.EMMonitorReceiver">
    <intent-filter>
    <action android:name="android.intent.action.PACKAGE_REMOVED"/>
    <data android:scheme="package"/>
    </intent-filter>
    <!-- 可选filter -->
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.USER_PRESENT" />
    </intent-filter>
    </receiver>

    三、SDK 中相关异步/同步处理方法介绍
    • 同步方法:SDK里大部分方法都为同步方法,即这个方法执行完毕,才会走后面的代码。
    • 异步方法:带有callback以及API注释里明确写明异步方法的方法,即不需要等这个方法走完,后边的代码就已经在执行了,通过callback得到方法执行的结果。
      注:具体是异步还是同步,也可以参考相关文档介绍的方法,每一个方法后边都有注释信息提示开发者,未注释的则认为同步执行。

四、初始化SDK

要求在application的oncreate方法中做初始化,初始化的时候需要传入设置好的options。

        EMOptions options = new EMOptions();  
        // 默认添加好友时,是不需要验证的,改成需要验证
        options.setAcceptInvitationAlways(false);
        ...
        //初始化
        EMClient.getInstance().init(applicationContext, options);
        //在做打包混淆时,关闭debug模式,避免消耗不必要的资源
        EMClient.getInstance().setDebugMode(true);

注:如果你的APP中有第三方的服务启动,请在初始化SDK(EMClient.getInstance().init(applicationContext, options))方法的前面添加以下相关代码(相应代码也可参考Demo的application),使用EaseUI库的就不用理会这个。

        appContext = this;
        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        // 如果APP启用了远程的service,此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次
        // 默认的APP会在以包名为默认的process name下运行,如果查到的process name不是APP的process name就立即返回

        if (processAppName == null ||!processAppName.equalsIgnoreCase(appContext.getPackageName())) {
            Log.e(TAG, "enter the service process!");

            // 则此application::onCreate 是被service 调用的,直接返回
            return;
        }


        如何获取processAppName请参考以下方法。
        private String getAppName(int pID) {
            String processName = null;
            ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
            List l = am.getRunningAppProcesses();
            Iterator i = l.iterator();
            PackageManager pm = this.getPackageManager();
            while (i.hasNext()) {
                ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
                try {
                    if (info.pid == pID) {
                        processName = info.processName;
                        return processName;
                    }
                } catch (Exception e) {
                    // Log.d("Process", "Error>> :"+ e.toString());
                }
            }
            return processName;
        }

五、注册

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

  • 开放注册是为了测试使用,正式环境中不推荐使用该方式注册环信账号;
  • 授权注册的流程应该是您服务器通过环信提供的REST API注册,之后保存到您的服务器或返回给客户端。
    注册用户名会自动转为小写字母,所以建议用户名均以小写注册。(强烈建议开发者通过后台调用REST接口去注册环信ID,客户端注册方法不提倡使用。)
    //注册失败会抛出HyphenateException
    EMClient.getInstance().createAccount(username, pwd);//同步方法

六、登录

EMClient.getInstance().login(userName,password,new EMCallBack() {//回调
    @Override
    public void onSuccess() {
        runOnUiThread(new Runnable() {
            public void run() {
                EMClient.getInstance().groupManager().loadAllGroups();
                EMClient.getInstance().chatManager().loadAllConversations();
                Log.d("main", "登录聊天服务器成功!");        
            }
        });
    }

    @Override
    public void onProgress(int progress, String status) {

    }

    @Override
    public void onError(int code, String message) {
        Log.d("main", "登录聊天服务器失败!");
    }
});
注意: 登录成功后需要调用EMClient.getInstance().chatManager().loadAllConversations(); 和EMClient.getInstance().groupManager().loadAllGroups();。
以上两个方法是为了保证进入主页面后本地会话和群组都load完毕。
另外如果登录过,APP长期在后台再进的时候也可能会导致加载到内存的群组和会话为空,可以在主页面的oncreate里也加上这两句代码,当然,更好的办法应该是放在程序的开屏页,可参考demo的SplashActivity。

七、自动登录

即首次登录成功后,不需要再次调用登录方法,在下次APP启动时,SDK会自动为您登录。并且如果您自动登录失败,也可以读取到之前的会话信息(以上情况是在未调用登出的情况下实现的)。
SDK中自动登录属性默认是true打开的,如果不需要自动登录,在初始化SDK初始化的时候,调用options.setAutoLogin(false);设置为false关闭。

自动登录在以下几种情况下会被取消:

  • 用户调用了SDK的登出动作;
  • 用户在别的设备上更改了密码,导致此设备上自动登录失败;
  • 用户的账号被从服务器端删除;
  • 用户从另一个设备登录,把当前设备上登录的用户踢出。

八、退出登录

EMClient.getInstance().logout(true);//此方法为同步方法,里面的参数true表示退出登录时解绑GCM或者小米推送的token
//此方法为异步方法
EMClient.getInstance().logout(true, new EMCallBack() {

    @Override
    public void onSuccess() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProgress(int progress, String status) {
     // TODO Auto-generated method stub

    }

    @Override
    public void onError(int code, String message) {
      // TODO Auto-generated method stub

    }
});

九、注册连接状态监听

当掉线时,Android SDK会自动重连,无需进行任何操作,通过注册连接监听来知道连接状态。

在聊天过程中难免会遇到网络问题,在此SDK为您提供了网络监听接口,实时监听
可以根据disconnect返回的error判断原因。若服务器返回的参数值为EMError.USER_LOGIN_ANOTHER_DEVICE,则认为是有同一个账号异地登录;若服务器返回的参数值为EMError.USER_REMOVED,则是账号在后台被删除。

        //注册一个监听连接状态的listener
        EMClient.getInstance().addConnectionListener(new MyConnectionListener());

        //实现ConnectionListener接口
         private class MyConnectionListener implements EMConnectionListener {

        @Override
        public void onConnected() {
        }

        @Override
        public void onDisconnected(final int error) {

            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    if(error == EMError.USER_REMOVED){

                        // 显示帐号已经被移除

                    }else if (error == EMError.USER_LOGIN_ANOTHER_DEVICE) {

                        // 显示帐号在其他设备登录


                    } else {
                    if (NetUtils.hasNetwork(MainActivity.this))

                        //连接不到聊天服务器
                    else
                        //当前网络不可用,请检查网络设置
                    }
                }
            });
        }
    }

十、消息
1. 发送消息:
* 发送文本消息:
“`

         //创建一条文本消息,content为消息文字内容,toChatUsername为对方用户或者群聊的id,后文皆是如此   
           EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername);

            //如果是群聊,设置chattype,默认是单聊  
            if (chatType == CHATTYPE_GROUP)  
                message.setChatType(ChatType.GroupChat);  

           //发送消息  
         EMClient.getInstance().chatManager().sendMessage(message);
```
  • 发送语音消息:

    ```
        //filePath为语音文件路径,length为录音时间(秒)  
        EMMessage message = EMMessage.createVoiceSendMessage(filePath, length, toChatUsername); 
    
        //如果是群聊,设置chattype,默认是单聊  
        if (chatType == CHATTYPE_GROUP)  
            message.setChatType(ChatType.GroupChat);  
    
        EMClient.getInstance().chatManager().sendMessage(message);  
    ```
    
  • 发送视频信息:
    “`
    //videoPath为视频本地路径,thumbPath为视频预览图路径,videoLength为视频时间长度
    EMMessage message = EMMessage.createVideoSendMessage(videoPath, thumbPath, videoLength, toChatUsername);

        //如果是群聊,设置chattype,默认是单聊  
        if (chatType == CHATTYPE_GROUP)  
            message.setChatType(ChatType.GroupChat);  
    
        EMClient.getInstance().chatManager().sendMessage(message);  
    ```
    
  • 发送图片信息:
    “`
    //imagePath为图片本地路径,false为不发送原图(默认超过100k的图片会压缩后发给对方),需要发送原图传true
    EMMessage.createImageSendMessage(imagePath, false, toChatUsername);

        //如果是群聊,设置chattype,默认是单聊  
         if (chatType == CHATTYPE_GROUP)  
            message.setChatType(ChatType.GroupChat);  
    
         EMClient.getInstance().chatManager().sendMessage(message); 
    ``` 
    
  • 发送地理位置信息:
    “`
    //latitude为纬度,longitude为经度,locationAddress为具体位置内容
    EMMessage message = EMMessage.createLocationSendMessage(latitude, longitude, locationAddress, toChatUsername);

        //如果是群聊,设置chattype,默认是单聊  
        if (chatType == CHATTYPE_GROUP)  
            message.setChatType(ChatType.GroupChat);
    
        EMClient.getInstance().chatManager().sendMessage(message);  
    ```
    
  • 发送文件消息:
    “`
    EMMessage message = EMMessage.createFileSendMessage(filePath, toChatUsername);

        // 如果是群聊,设置chattype,默认是单聊  
        if (chatType == CHATTYPE_GROUP)  
            message.setChatType(ChatType.GroupChat);  
    
        EMClient.getInstance().chatManager().sendMessage(message);  
    ```
    
  • 发送透传消息:
    “`
    透传消息能做什么:头像、昵称的更新等。可以把透传消息理解为一条指令,通过发送这条指令给对方,告诉对方要做的action,收到消息可以自定义处理的一种消息。(透传消息不会存入本地数据库中,所以在UI上是不会显示的)
    EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);

         //支持单聊和群聊,默认单聊,如果是群聊添加下面这行  
        cmdMsg.setChatType(ChatType.GroupChat)  
    
        String action="action1";//action可以自定义  
    
        EMCmdMessageBody cmdBody = new EMCmdMessageBody(action); 
    
        String toUsername = "test1";//发送给某个人  
    
        cmdMsg.setReceipt(toUsername);  
    
        cmdMsg.addBody(cmdBody);   
    
        EMClient.getInstance().chatManager().sendMessage(message);  
    ```
    
    1. 接收消息:

    通过注册消息监听来接收消息。

        EMClient.getInstance().chatManager().addMessageListener(msgListener);  
    
        EMMessageListener msgListener = new EMMessageListener() {  
    
            @Override  
            public void onMessageReceived(List<EMMessage> messages) {  
                //收到消息  
            }  
    
            @Override  
            public void onCmdMessageReceived(List<EMMessage> messages) {  
                //收到透传消息  
            }  
    
            @Override  
            public void onMessageReadAckReceived(List<EMMessage> messages) {  
                //收到已读回执  
            }  
    
            @Override  
            public void onMessageDeliveryAckReceived(List<EMMessage> message) {  
                //收到已送达回执  
            }  
    
            @Override  
            public void onMessageChanged(EMMessage message, Object change) {  
                //消息状态变动  
            }  
    
        };    

    记得在不需要的时候移除listener,如在activity的onDestroy()时EMClient.getInstance().chatManager().removeMessageListener(msgListener);

    1. 监听消息状态:

    通过message设置消息的发送及接收状态。

    message.setMessageStatusCallback(new EMCallBack(){});  
    1. 消息扩展:
      当SDK提供的消息类型不满足需求时,开发者可以通过扩展自SDK提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。
      这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。

      EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername);  
      
       // 增加自己特定的属性  
      message.setAttribute("attribute1", "value");  
      message.setAttribute("attribute2", true);  
      ...  
      EMClient.getInstance().chatManager().sendMessage(message);  
      
      //接收消息的时候获取到扩展属性  
      //获取自定义的属性,第2个参数为没有此定义的属性时返回的默认值  
      message.getStringAttribute("attribute1",null);  
      message.getBooleanAttribute("attribute2", false);  
      ...  
    2. 获取聊天记录:

      EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username); 
      
      //获取此会话的所有消息  
      List<EMMessage> messages = conversation.getAllMessages();  
      
      //SDK初始化加载的聊天记录为20条,到顶时需要去DB里获取更多  
      //获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中  
      List<EMMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize);  
      
      建议初始化SDK的时候设置成每个会话默认load一条消息,节省加载会话的时间,方法为: options.setNumberOfMessagesLoaded(1);  
    3. 获取未读消息数量:

      EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
      
      conversation.getUnreadMsgCount();  
    4. 未读消息数清零:

      EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username); 
      
      //指定会话消息未读数清零  
      conversation.markAllMessagesAsRead();  
      
      //把一条消息置为已读  
      conversation.markMessageAsRead(messageId);  
      
      //所有未读消息数清零  
      EMClient.getInstance().chatManager().markAllConversationsAsRead();  
    5. 获取消息总数:

      EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);  
      
      //获取此会话在本地的所有的消息数量  
      conversation.getAllMsgCount();  
      
      //如果只是获取当前在内存的消息数量,调用  
      conversation.getAllMessages().size();  
    6. 删除会话及聊天记录:

      //删除和某个user会话,如果需要保留聊天记录,传false  
      EMClient.getInstance().chatManager().deleteConversation(username, true);
      
      //删除当前会话的某条聊天记录  
      EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);  
      
      conversation.removeMessage(deleteMsg.msgId);  
    7. 导入消息到数据库:

           EMClient.getInstance().chatManager().importMessages(msgs);   

    十一、好友管理

    1. 获取好友列表

    获取好友的username list,开发者需要根据username去自己服务器获取好友的详情。

    List<String> usernames = EMClient.getInstance().contactManager().getAllContactsFromServer();
    1. 查找好友

    SDK不提供好友查找的服务,如需要查找好友,需要调用开发者自己服务器的用户查询接口。

    为了保证查找到的好友可以添加,需要将开发者自己服务器的用户数据(用户的环信ID),通过SDK的后台接口导入到 环信服务器中。

    1. 添加好友

      //参数为要添加的好友的username和添加理由
      EMClient.getInstance().contactManager().addContact(toAddUsername, reason);
    2. 删除好友

      EMClient.getInstance().contactManager().deleteContact(username);
    3. 同意好友请求

    默认好友请求是自动同意的,如果要手动同意需要在初始化SDK时调用 opptions.setAcceptInvitationAlways(false); 。

    EMClient.getInstance().contactManager().acceptInvitation(username);
    1. 拒绝好友请求

      EMClient.getInstance().contactManager().declineInvitation(username);
    2. 监听好友状态事件

       EMClient.getInstance().contactManager().setContactListener(new EMContactListener() {
      
       @Override
       public void onContactAgreed(String username) {
            //好友请求被同意
       }
      
       @Override
      public void onContactRefused(String username) {
          //好友请求被拒绝
       }
      
       @Override
       public void onContactInvited(String username, String reason) {
           //收到好友邀请
        }
      
        @Override
        public void onContactDeleted(String username) {
            //被删除时回调此方法
      }
      
      
      @Override
       public void onContactAdded(String username) {
            //增加了联系人时回调此方法
       }
      });
    3. 从服务器获取黑名单列表

      EMClient.getInstance().contactManager().getBlackListFromServer();
    4. 从本地数据库获取名单列表

      EMClient.getInstance().contactManager().getBlackListUsernames();
    5. 将用户加入黑名单

      //第二个参数如果为true,则把用户加入到黑名单后双方发消息时对方都收不到;false,则我能给黑名单的中用户发               消息,但是对方发给我时我是收不到的
      EMClient.getInstance().contactManager().addUserToBlackList(username,true);
    6. 把用户从黑名单移除

      EMClient.getInstance().contactManager().removeUserFromBlackList(username);

    十二、群组管理

    1. 新建群组
      /**
      * 创建群组
      * @param groupName 群组名称
      * @param desc 群组简介
      * @param allMembers 群组初始成员,如果只有自己传null即可
      * @param reason 邀请成员加入的reason
      * @param option 群组类型选项,可以设置群组最大用户数(默认200)及群组类型@see {@link EMGroupStyle}
      * @return 创建好的group
      * @throws HyphenateException
      */
      EMGroupOptions option = new EMGroupOptions();
      option.maxUsers = 200;
      option.style = EMGroupStyle.EMGroupStylePrivateMemberCanInvite;
      
      EMClient.getInstance().groupManager().createGroup(groupName, desc, allMembers, reason, option);

    option里的GroupStyle分别为:

    EMGroupStylePrivateOnlyOwnerInvite——私有群,只有群主可以邀请人;
    EMGroupStylePrivateMemberCanInvite——私有群,群成员也能邀请人进群;
    EMGroupStylePublicJoinNeedApproval——公开群,加入此群除了群主邀请,只能通过申请加入此群;
    EMGroupStylePublicOpenJoin ——公开群,任何人都能加入此群。

    1. 群组加人

      //群主加人调用此方法
      EMClient.getInstance().groupManager().addUsersToGroup(groupId, newmembers);//需异步处理
      //私有群里,如果开放了群成员邀请,群成员邀请调用下面方法
      EMClient.getInstance().groupManager().inviteUser(groupId, newmembers, null);//需异步处理
    2. 群组踢人

      //把username从群组里删除
      EMClient.getInstance().groupManager().removeUserFromGroup(groupId, username);//需异步处理
    3. 加入某个群组

      //如果群开群是自由加入的,即group.isMembersOnly()为false,直接join
      EMClient.getInstance().groupManager().joinGroup(groupid);//需异步处理
      //需要申请和验证才能加入的,即group.isMembersOnly()为true,调用下面方法
      EMClient.getInstance().groupManager().applyJoinToGroup(groupid, "求加入");//需异步处理
    4. 退出群组

      EMClient.getInstance().groupManager().leaveGroup(groupId);//需异步处理
    5. 解散群组

      EMClient.getInstance().groupManager().destroyGroup(groupId);//需异步处理
    6. 获取群组列表

      //从服务器获取自己加入的和创建的群组列表,此api获取的群组sdk会自动保存到内存和db。
      List<EMGroup> grouplist = EMClient.getInstance().groupManager().getJoinedGroupsFromServer();//需异步处理
      
      //从本地加载群组列表
      List<EMGroup> grouplist = EMClient.getInstance().groupManager().getAllGroups();
      
      //获取公开群列表
      //pageSize为要取到的群组的数量,cursor用于告诉服务器从哪里开始取
      EMCursorResult<EMGroupInfo> result = EMClient.getInstance().groupManager().getPublicGroupsFromServer(pageSize,      cursor);//需异步处理
      List<EMGroupInfo> groupsList = List<EMGroupInfo> returnGroups = result.getData();
      String cursor = result.getCursor();
    7. 修改群组名称

      //groupId 需要改变名称的群组的id
      //changedGroupName 改变后的群组名称
      EMClient.getInstance().groupManager().changeGroupName(groupId,changedGroupName);//需异步处理
    8. 获取单个群组信息

      //根据群组ID从本地获取群组基本信息
      EMGroup group = EMClient.getInstance().groupManager().getGroup(groupId);
      //根据群组ID从服务器获取群组基本信息
      EMGroup group = EMClient.getInstance().groupManager().getGroupFromServer(groupId);
      
      group.getMembers();//获取群成员
      group.getOwner();//获取群主
      ...
    9. 屏蔽群消息

      /**
      * 屏蔽群消息后,就不能接收到此群的消息(还是群里面的成员,但不再接收消息)
      * @param groupId, 群ID
      * @throws EasemobException
      */
      EMClient.getInstance().groupManager().blockGroupMessage(groupId);//需异步处理
    10. 解除屏蔽群

      /**
      * 取消屏蔽群消息,就可以正常收到群的所有消息
      * @param groupId
      * @throws EaseMobException
      */
      EMClient.getInstance().groupManager().unblockGroupMessage(groupId);//需异步处理
    11. 将群成员拉入群组黑名单

      /**
      * 将用户加到群组的黑名单,被加入黑名单的用户无法加入群,无法收发此群的消息
      * (只有群主才能设置群的黑名单)
      * @param groupId, 群组的ID
      * @param username, 待屏蔽的用户名
      * @exception EaseMobException 出错会抛出
      */
          EMClient.getInstance().groupManager().blockUser(groupId, username);//需异步处理
    12. 将用户移出群黑名单

      /**
      * 将用户从群组的黑名单移除(只有群主才能调用此函数)
      * @param groupId, 群组的ID
      * @param username, 待解除屏蔽的用户名
      */
      EMClient.getInstance().groupManager().unblockUser(groupId, username);//需异步处理
    13. 获取群组黑名单用户列表

      /**
      * 获取群组的黑名单用户列表
      * (只有群主才能调用此函数)
      * @return List<String> 
      * @throws EaseMobException 获取失败
      */
      EMClient.getInstance().groupManager().getBlockedUsers(groupId);//需异步处理
    14. 群组监听事件

          EMClient.getInstance().groupManager().addGroupChangeListener(new EMGroupChangeListener() {
          @Override
          public void onUserRemoved(String groupId, String groupName) {
              //当前用户被管理员移除出群组
          }
          @Override
          public void onInvitationReceived(String groupId, String groupName, String inviter, String reason) {
              //收到加入群组的邀请
          }
          @Override
          public void onInvitationDeclined(String groupId, String invitee, String reason) {
              //群组邀请被拒绝
          }
          @Override
          public void onInvitationAccpted(String groupId, String inviter, String reason) {
              //群组邀请被接受
          }
          @Override
          public void onGroupDestroy(String groupId, String groupName) {
              //群组被创建者解散
          }
          @Override
          public void onApplicationReceived(String groupId, String groupName, String applyer, String reason) {
              //收到加群申请
          }
          @Override
          public void onApplicationAccept(String groupId, String groupName, String accepter) {
              //加群申请被同意
          }
          @Override
          public void onApplicationDeclined(String groupId, String groupName, String decliner, String reason) {
              // 加群申请被拒绝
          }
      });

以上是关于环信Android客户端集成文档的主要内容,如果未能解决你的问题,请参考以下文章

环信im Flutter sdk使用帮助

android-使用环信SDK开发即时通信功能及源代码下载

环信IM集成指南Web端常见问题整理

环信IM集成指南Web端常见问题整理

环信IM集成指南Web端常见问题整理

iOS 环信集成问题(连文档都不说明的坑。。)