实现圈组消息收发
更新时间: 2024/07/08 18:24:56
圈组是网易云信 IM 即时通讯服务的全新能力,可用来帮助您快速构建 类 Discord 即时通讯社群。本文介绍如何通过较少的代码集成 NetEase IM SDK (以下简称 NIM SDK)并调用 API,在您的应用中实现圈组消息收发。
前提条件
-
已 注册网易云信 IM 账号,获取 accid 和 token。
-
已 开通和配置圈组功能。
-
开发环境满足如下条件:
- Android 5.0 及以上版本。
- v6.9.0 起,改用 AndroidX 支持库,Target API 改为 28,不再支持 support 库。
流程概览
圈组服务端 与 圈组服务器 是两个不同概念,前者指网易云信服务端提供圈组功能的部分,后者为圈组的特殊概念,对应 Discord 的 Server,为社群本身,具体参考 圈组主要概念。
实现圈组消息收发的流程,可分为下图所示的 5 大步骤。
步骤 1:集成 NIM SDK
本节仅介绍更为快速的 Gradle 自动集成方式。如需查看手动集成的具体说明,请参考 手动集成。
Gradle 集成
-
若您需要创建新项目,在 Android Studio 里,在顶部菜单依次选择 File > New > New Project 新建工程,再依次选择 Phone and Tablet > Empty Activity,单击 Next。
创建 Android 项目 成功后,Android Studio 会自动开始同步 gradle, 您需要等同步成功后再进行下一步操作。
-
在项目根目录下的
build.gradle
文件中,配置repositories
(使用 maven)。示例代码如下:allprojects { repositories { mavenCentral() } }
-
在主工程的 build.gradle 文件中,设置支持的 SO 库架构。
android { defaultConfig { ndk { //设置支持的 SO 库架构 abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64" } } }
-
在主工程的 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<?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 相关类加入不混淆名单。
Groovy-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 的初始化才能使用其他功能。
在 Application
的 onCreate
中,调用 init
方法进行初始化。
示例代码如下:
Javapublic 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 服务端。
-
调用
observeOnlineStatus
方法监听 IM 登录状态。示例代码如下:
Java
NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus( new Observer<StatusCode> () { public void onEvent(StatusCode status) { //获取状态的描述 String desc = status.getDesc(); if (status.wontAutoLogin()) { // 被踢出、账号被禁用、密码错误等情况,自动登录失败,需要返回到登录界面进行重新登录操作 } } }, true);
-
(可选)调用
observeLoginSyncDataStatus
方法监听登录后数据同步过程。如您仅需集成圈组功能,不需要 IM 其他组件的功能,可跳过这一步。
示例代码如下:
Java
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);
-
调用
AuthService#login
方法开始手动登录。示例代码如下:
Java
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); } }
-
登录开始后,
observeOnlineStatus
方法的Observer
接口根据实际登录情况触发回调函数,返回具体的登录状态。如最终返回LOGINED
,则代表登录成功。
步骤 4:登录云信圈组服务端
-
发送方和接收方调用
observeStatusChange
方法监听圈组登录状态。示例代码如下:
Java
NIMClient.getService(QChatServiceObserver.class).observeStatusChange(new Observer<QChatStatusChangeEvent>() { @Override public void onEvent(QChatStatusChangeEvent qChatStatusChangeEvent) { //当前状态 StatusCode status = qChatStatusChangeEvent.getStatus(); } },true);
-
接收方调用
QChatServiceObserver#observeReceiveMessage
方法监听圈组消息接收。示例代码如下:
Java
NIMClient.getService(QChatServiceObserver.class).observeReceiveMessage(new Observer<List<QChatMessage>>() { @Override public void onEvent(List<QChatMessage> qChatMessages) { //收到消息 qChatMessages for (QChatMessage qChatMessage : qChatMessages) { //处理消息 } } }, true);
-
发送方和接收方调用
QChatService#login
方法开始登录圈组服务端。目前移动端仅支持 非独立模式 登录圈组服务端,即必须先登录 IM 服务端。
示例代码如下:
Java
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 } });
-
登录后,
observeStatusChange
方法的Observer
接口触发回调函数,根据实际登录情况返回登录状态。如最终返回LOGINED
,则代表登录成功。圈组登录状态及其变化流程与 IM 的相同,具体请参考本文文末的 登录状态变化流程。
步骤 5:圈组消息收发
本节以发送方与接收方的消息交互为例,介绍在不考虑用户权限管理的情况下,使用 SDK API 快速实现圈组 文本消息 收发的流程。
-
发送方调用
QChatServiceObserver#observeMessageStatusChange
)方法监听圈组消息发送状态。示例代码如下:
Java
NIMClient.getService(QChatServiceObserver.class).observeMessageStatusChange(new Observer<QChatMessage>() { @Override public void onEvent(QChatMessage qChatMessage) { //收到状态变化的消息 qChatMessage } }, true);
-
发送方调用
createServer
方法创建圈组服务器。为更加快速实现消息收发,创建时可将QChatInviteMode
设置为AGREE_NEED_NOT(1)
(发送邀请后,不需要被邀请方同意,被邀请方立即加入服务器)。创建成功后,需记录服务器的 ID(
serverId
),后续步骤将需要传入serverId
。示例代码如下:
Java
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) { // 创建异常 } });
-
发送方调用
createChannel
方法,调用时传入上一步中创建的圈组服务器的serverId
,且将QChatChannelMode
和QChatChannelType
分别设置为PUBLIC
和MessageChannel
,从而在圈组服务器中创建一个消息类型的公开频道。创建成功后,需记录频道的 ID(
channelId
),后续步骤将需要传入channelId
。示例代码如下:
Java
//建立一个消息类型的频道 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 异常 } });
-
发送方调用
inviteServerMembers
方法,邀请接收方 加入圈组服务器。示例代码如下:
Java
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) { //邀请异常 } });
-
发送方调用
QChatMessageService#sendMessage
方法,调用时传入圈组服务器与公开频道的 ID,从而在公开频道中发送一条消息。示例代码如下:
Java
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) { //发送消息异常 } });
-
QChatServiceObserver#observeReceiveMessage
方法的Observer
接口触发回调函数,接收方通过该回调收到消息。
下一步
为保障通信安全,如果您在调试环境中的使用的是网易云信控制台生成的测试用 IM 账号 和 token
,请确保在后续的正式生产环境中,将其替换为通过 IM 服务端 API 生成的正式 IM 账号(accid
)和 token
。
集成开发
请参考以下文档进行圈组功能开发: