实现圈组消息收发
更新时间: 2024/08/22 17:21:31
圈组是网易云信 IM 即时通讯服务的全新能力,可用来帮助您快速构建 “类 Discord 即时通讯社群”。本文介绍如何通过较少的代码集成 NetEase IM SDK (以下简称 NIM SDK)并调用 API,在您的应用中实现圈组消息收发。
使用前准备
-
已在云信控制台创建应用,获取 App Key。
-
已注册云信 IM 账号,获取 IM 账号和 token。
-
已在云信控制台开通和配置圈组功能。
-
开发环境需满足 Android 5.0 及以上版本。
实现流程
流程概览
实现单聊消息收发的流程,可分为下图所示的 4 大步骤。
圈组服务端与圈组服务器是两个不同概念,前者指云信服务端提供圈组功能的部分,后者为圈组的特殊概念,对应 Discord 的 Server, 为社群本身,具体参见圈组主要概念。
步骤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
中,调用 NIMClient#initV2
方法进行初始化。
示例代码如下:
javapublic class NimApplication extends Application {
public void onCreate() {
// 激活V10 API后,可以根据该字段选项选择是否禁用V10 API登录,默认false,即使用V10 API登录
// sdkOptions.disableV2Login = true;
...
// 按需设置其它 SDKOptions 设置项
NIMClient.initV2(context, sdkOptions);
}
}
以上提供了一个简化的初始化示例,更多初始化信息请参见初始化 Android SDK。
步骤 3:登录 IM
V10 已采用融合登录方案,用户只需要调用 V2NIMLoginService#login
方法登录一次,则可以同时使用 IM 与圈组,无需再单独登录圈组服务器。
调用 V2NIMLoginService#login
后调用 QChatService#login
方法将会报错。
以静态 Token 登录为例,示例代码如下:
javaNIMClient.getService(V2NIMLoginService.class).login("account", "token", null, new V2NIMSuccessCallback<Void>() {
@Override
public void onSuccess(Void unused) {
// TODO
}
},
new V2NIMFailureCallback() {
@Override
public void onFailure(V2NIMError error) {
int code = error.getCode();
String desc = error.getDesc();
// TODO
}
});
其他登录方式请参见登录及登出 IM。
步骤 4:圈组消息收发
本节以发送方与接收方的消息交互为例,介绍在不考虑用户权限管理的情况下,使用 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 账号和 token
。