IM 即时通讯(SDK)
Android
开发指南

实现圈组消息收发

更新时间: 2023/09/13 18:46:07

圈组是网易云信 IM 即时通讯服务的全新能力,可用来帮助您快速构建 “类 Discord 即时通讯社群”。本文介绍如何通过较少的代码集成 NetEase IM SDK (以下简称 NIM SDK)并调用 API,在您的应用中实现圈组消息收发。

前提条件

实现流程

流程概览

实现圈组消息收发的流程,可分为下图所示的 5 大步骤。

圈组快速开始.png

接收方: 投递消息(QChatMessage)

@enduml -->

圈组服务端圈组服务器是两个不同概念,前者指云信服务端提供圈组功能的部分,后者为圈组的特殊概念,对应 Discord 的 Server, 为社群本身,具体参见圈组主要概念

步骤1: 集成 NIM SDK

本节仅介绍更为快速的 Gradle 自动集成方式。如需查看手动集成的具体说明,请参见手动集成

Gradle集成

  1. 若您需要创建新项目,在 Android Studio 里,在顶部菜单依次选择 File > New > New Project 新建工程,再依次选择 Phone and Tablet > Empty Activity,单击 Next
    image

    创建 Android 项目成功后,Android Studio 会自动开始同步 gradle, 您需要等同步成功后再进行下一步操作。

  2. 在项目根目录下的build.gradle文件中,配置repositories(使用 maven)。示例代码如下:

    allprojects {
        repositories {
            mavenCentral()
        }
    }
    
  3. 在主工程的 build.gradle 文件中,设置支持的 SO 库架构。

    android {
    defaultConfig {
        ndk {
            //设置支持的SO库架构
            abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
            }
    }
    }
    
  4. 在主工程的 build.gradle 文件中,添加必需的依赖:

    dependencies {
        implementation fileTree(dir: 'libs', include: '*.jar')
        // 添加依赖。注意,版本号必须一致。
        
        // IM基础功能 (必需)
        implementation "com.netease.nimlib:basesdk:${LATEST_VERSION}"
        // 通过云信来集成小米等厂商推送需要(可选)
        implementation "com.netease.nimlib:push:${LATEST_VERSION}"
    // 圈组功能(集成圈组必需)
    implementation "com.netease.nimlib:qchat:${LATEST_VERSION}"
    }
    

    SDK 的组件版本号必须一致,如圈组组件的版本号必须与其他组件的一致。可在SDK下载页面查看当前最新版本。

添加权限

根据实际应用需求,在 AndroidManifest.xml 中添加以下配置(请将 com.netease.nim.demo 替换为自己的包名),设置所需的权限。更多可添加的权限项,请参见添加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.netease.nim.demo">

    <!-- 权限声明 -->
    <!-- 访问网络状态-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    
    
    <!-- 8.0+系统需要-->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    
</manifest>

防止代码混淆

代码混淆是指使用简短无意义的名称重命名已存在的类、方法、属性等,增加逆向工程的难度,保障 Android 程序源码的安全性。

为了避免因上述的重命名而导致调用 NIM SDK 异常,请在 proguard-rules.pro 文件中加入以下代码,将 NIM SDK 相关类加入不混淆名单。

-dontwarn com.netease.nim.**
-keep class com.netease.nim.** {*;}

-dontwarn com.netease.nimlib.**
-keep class com.netease.nimlib.** {*;}

-dontwarn com.netease.share.**
-keep class com.netease.share.** {*;}

-dontwarn com.netease.mobsec.**
-keep class com.netease.mobsec.** {*;}

#如果你使用全文检索插件,需要加入
-dontwarn org.apache.lucene.**
-keep class org.apache.lucene.** {*;}

#如果你开启数据库功能,需要加入
-keep class net.sqlcipher.** {*;}

步骤2: 初始化 NIM SDK

将 SDK 集成到客户端后,需要先完成 SDK 的初始化才能使用其他功能。


ApplicationonCreate 中,调用 init方法进行初始化。

示例代码如下:

public class NimApplication extends Application {
    public void onCreate() {
        NIMClient.init(this, loginInfo(), options());
    // 如果提供用户信息,将同时进行自动登录。如果当前还没有登录用户,请传入null。
    private LoginInfo loginInfo() {
        return null;
    }
    // 设置初始化配置参数,如果返回值为 null,则全部使用默认参数。
    private SDKOptions options() {
        SDKOptions options = new SDKOptions();
        return options;
      }// 可在 SDKOptions 中配置 App Key
    }
}

以上提供了一个简化的初始化示例,更多初始化信息请参见初始化 SDK

步骤3: 登录云信 IM 服务端

登录圈组服务端前,必须先登录 IM 服务端。

  1. 调用observeOnlineStatus方法监听 IM 登录状态。

    示例代码如下:

    NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(
        new Observer<StatusCode> () {
            public void onEvent(StatusCode status) {
        //获取状态的描述
        String desc = status.getDesc();
                if (status.wontAutoLogin()) {
                    // 被踢出、账号被禁用、密码错误等情况,自动登录失败,需要返回到登录界面进行重新登录操作
                }
            }
    }, true);
    
    
  2. (可选)调用observeLoginSyncDataStatus方法监听登录后数据同步过程。

    如您仅需集成圈组功能,不需要 IM 其他组件的功能,可跳过这一步。

    示例代码如下:

    NIMClient.getService(AuthServiceObserver.class).observeLoginSyncDataStatus(new Observer<LoginSyncStatus>() {
        @Override
        public void onEvent(LoginSyncStatus status) {
            if (status == LoginSyncStatus.BEGIN_SYNC) {
                LogUtil.i(TAG, "login sync data begin");
            } else if (status == LoginSyncStatus.SYNC_COMPLETED) {
                LogUtil.i(TAG, "login sync data completed");
            }
        }
    }, true);
    
  3. 调用AuthService#login方法开始手动登录。

    示例代码如下:

    public class LoginActivity extends Activity {
        public void doLogin() {
            LoginInfo info = new LoginInfo(); //传入accid和token
            RequestCallback<LoginInfo> callback =
                new RequestCallback<LoginInfo>() {
                        @Override
                        public void onSuccess(LoginInfo param) {
                            LogUtil.i(TAG, "login success");
                            // your code
                        }
    
                        @Override
                        public void onFailed(int code) {
                            if (code == 302) {
                                LogUtil.i(TAG, "账号密码错误");
                                // your code
                            } else {
                                // your code
                            }
                        }
    
                        @Override
                        public void onException(Throwable exception) {
                            // your code
                        }
            };
    
            //执行手动登录
            NIMClient.getService(AuthService.class).login(info).setCallback(callback);
        }
    }
    
  4. 登录开始后,observeOnlineStatus方法的Observer接口根据实际登录情况触发回调函数,返回具体的登录状态。如最终返回LOGINED,则代表登录成功。

步骤4: 登录云信圈组服务端

  1. 发送方和接收方调用observeStatusChange方法监听圈组登录状态。

    示例代码如下:

    NIMClient.getService(QChatServiceObserver.class).observeStatusChange(new Observer<QChatStatusChangeEvent>() {
    @Override
    public void onEvent(QChatStatusChangeEvent qChatStatusChangeEvent) {
        //当前状态
        StatusCode status = qChatStatusChangeEvent.getStatus();
    }
    },true);
    
  2. 接收方调用QChatServiceObserver#observeReceiveMessage方法监听圈组消息接收。

    示例代码如下:

    NIMClient.getService(QChatServiceObserver.class).observeReceiveMessage(new Observer<List<QChatMessage>>() {
        @Override
        public void onEvent(List<QChatMessage> qChatMessages) {
            //收到消息qChatMessages
            for (QChatMessage qChatMessage : qChatMessages) {
                //处理消息
            }
        }
    }, true);
    
  3. 发送方和接收方调用QChatService#login方法开始登录圈组服务端。

    目前移动端仅支持非独立模式登录圈组服务端,即必须先登录 IM 服务端。

    示例代码如下:

    QChatLoginParam loginParam = new QChatLoginParam();
    NIMClient.getService(QChatService.class).login(loginParam).setCallback(new RequestCallback<QChatLoginResult>() {
    @Override
    public void onSuccess(QChatLoginResult result) {
        LogUtil.i(TAG, "login success");
        // your code
    }
    
    @Override
    public void onFailed(int code) {
        LogUtil.i(TAG, "login failed");
        // your code
    }
    
    @Override
    public void onException(Throwable exception) {
        // your code
    }
    });
    
  4. 登录后,observeStatusChange方法的Observer接口触发回调函数,根据实际登录情况返回登录状态。如最终返回LOGINED,则代表登录成功。

    圈组登录状态及其变化流程与 IM 的相同,具体请参见本文文末的登录状态变化流程

步骤5: 圈组消息收发

本节以发送方与接收方的消息交互为例,介绍在不考虑用户权限管理的情况下,使用 SDK API 快速实现圈组文本消息收发的流程。


  1. 发送方调用QChatServiceObserver#observeMessageStatusChange)方法监听圈组消息发送状态。

    示例代码如下:

    NIMClient.getService(QChatServiceObserver.class).observeMessageStatusChange(new Observer<QChatMessage>() {
        @Override
        public void onEvent(QChatMessage qChatMessage) {
            //收到状态变化的消息qChatMessage
            
        }
    }, true);
    
  2. 发送方调用createServer方法创建圈组服务器。为更加快速实现消息收发,创建时可将QChatInviteMode设置为AGREE_NEED_NOT(1)(发送邀请后,不需要被邀请方同意,被邀请方立即加入服务器)。

    创建成功后,需记录服务器的 ID(serverId),后续步骤将需要传入serverId


    示例代码如下:

    QChatCreateServerParam param = new QChatCreateServerParam("测试");
    param.setInviteMode(QChatInviteMode.AGREE_NEED_NOT);
    QChatAntiSpamConfig antiSpamConfig = new QChatAntiSpamConfig("用户配置的对某些资料内容另外的反垃圾的业务ID");//非必须,请按需配置
    param.setAntiSpamBusinessId(antiSpamConfig);//非必须,请按需配置
    NIMClient.getService(QChatServerService.class).createServer(param).setCallback(
            new RequestCallback<QChatCreateServerResult>() {
                @Override
                public void onSuccess(QChatCreateServerResult result) {
                    // 创建成功
                    QChatServer server = result.getServer();
                }
    
                @Override
                public void onFailed(int code) {
                    // 创建失败,返回错误code
                }
    
                @Override
                public void onException(Throwable exception) {
                    // 创建异常
                        }
            });
    
  3. 发送方调用createChannel方法,调用时传入上一步中创建的圈组服务器的serverId,且将QChatChannelModeQChatChannelType分别设置为PUBLICMessageChannel,从而在圈组服务器中创建一个消息类型的公开频道。

    创建成功后,需记录频道的 ID(channelId),后续步骤将需要传入channelId


    示例代码如下:

    //建立一个消息类型的频道
    QChatCreateChannelParam param = new QChatCreateChannelParam(943445L, "测试频道", QChatChannelType.MessageChannel);
    param.setCustom("自定义扩展");
    param.setTopic("主题");
    //设置频道为公开频道
    param.setViewMode(QChatChannelMode.PUBLIC);
    QChatAntiSpamConfig antiSpamConfig = new QChatAntiSpamConfig("用户配置的对某些资料内容另外的反垃圾的业务ID");
    param.setAntiSpamBusinessId(antiSpamConfig);
    NIMClient.getService(QChatChannelService.class).createChannel(param).setCallback(
            new RequestCallback<QChatCreateChannelResult>() {
                @Override
                public void onSuccess(QChatCreateChannelResult result) {
                    //创建Channel成功,返回创建成功的Channel信息
                    QChatChannel channel = result.getChannel();
                }
    
                @Override
                public void onFailed(int code) {
                    //创建Channel失败,返回错误code
                }
    
                @Override
                public void onException(Throwable exception) {
                    //创建Channel异常
                }
            });
    
  4. 发送方调用inviteServerMembers方法,邀请接收方 加入圈组服务器。

    示例代码如下:

    List<String> accids = new ArrayList<>();
    accids.add("test");
    QChatInviteServerMembersParam param = new QChatInviteServerMembersParam(943445L,accids);
    param.setPostscript("邀请你加入测试服务器");
    NIMClient.getService(QChatServerService.class).inviteServerMembers(param).setCallback(
            new RequestCallback<QChatInviteServerMembersResult>() {
                @Override
                public void onSuccess(QChatInviteServerMembersResult result) {
                    //邀请成功,会返回因为用户服务器数量超限导致失败的accid列表
                    List<String> failedAccids = result.getFailedAccids();
                }
    
                @Override
                public void onFailed(int code) {
                    //邀请失败,返回错误code
                }
    
                @Override
                public void onException(Throwable exception) {
                    //邀请异常
                }
            });
    
  5. 发送方调用QChatMessageService#sendMessage方法,调用时传入圈组服务器与公开频道的ID,从而在公开频道中发送一条消息。

    示例代码如下:

    QChatSendMessageParam param = new QChatSendMessageParam(943445L,885305L, MsgTypeEnum.text);
    param.setBody("测试消息");
    //通过QChatSendMessageParam构造一个QChatMessage
    QChatMessage currentMessage = param.toQChatMessage();
    
    NIMClient.getService(QChatMessageService.class).sendMessage(param).setCallback(new RequestCallback<QChatSendMessageResult>() {
        @Override
        public void onSuccess(QChatSendMessageResult result) {
            //发送消息成功,返回发送成功的消息具体信息
            QChatMessage message = result.getSentMessage();
        }
    
        @Override
        public void onFailed(int code) {
            //发送消息失败,返回错误code
        }
    
        @Override
        public void onException(Throwable exception) {
            //发送消息异常
        }
    });
    
  6. QChatServiceObserver#observeReceiveMessage方法的Observer接口触发回调函数,接收方通过该回调收到消息。

后续步骤

为保障通信安全,如果您在调试环境中的使用的是云信控制台生成的测试用 IM 账号 和 token,请确保在后续的正式生产环境中,将其替换为通过 IM 服务端 API 生成的正式 IM 账号(accid)和 token

圈组相关集成文档

此文档是否对你有帮助?
有帮助
我要吐槽
  • 前提条件
  • 实现流程
  • 流程概览
  • 步骤1: 集成 NIM SDK
  • Gradle集成
  • 添加权限
  • 防止代码混淆
  • 步骤2: 初始化 NIM SDK
  • 步骤3: 登录云信 IM 服务端
  • 步骤4: 登录云信圈组服务端
  • 步骤5: 圈组消息收发
  • 后续步骤
  • 圈组相关集成文档