收发消息
本文介绍了如何从客户端发送超级群消息。超级群收发消息需要使用 RongCoreClient 下的方法。
前置条件
建议先阅读超级群概述和超级群私有频道概述,了解在 App 业务中如何使用频道和超级群频道功能特性。
- 通过服务端 API 创建超级群
- 通过服务端 API 创建频道,或使用默认频道 ID
RCDefault
- 通过服务端 API 将发件人加入超级群
- 如不确定发件人是否在超级群中,请通过服务端 API 查询用户是否为群成员
- 如向超级群私有频道中发送消息,请确认已通过服务端 API 添加私有频道成员
当前频道聊天页面发送与接收消息,需要同时检查超级群 ID 和频道 ID。如果超级群 ID 和频道 ID 和当前频道聊天页面对应,才能在当前频道页面进行展示处理,否则就不处理。如果消息出现在其他聊天页面,一般是因为超级群 ID 或者频道 ID 发生错误。
构造消息对象
在发送消息前,需要构造 Message 对象,消息的 conversationType
字段必须填写超级群业务的会话类型 ConversationType.ULTRA_GROUP
。消息的 targetId
字段表示超级群 ID,channelId
表示超级群频道 ID。
Message
对象中可包含普通消息内容或媒体消息内容。普通消息内容指 MessageContent
的子类,例如文本消息(TextMessage)。
String targetId = "超级群 ID";
ConversationType conversationType = Conversation.ConversationType.ULTRA_GROUP;
String channelId = "超级群频道 ID";
TextMessage messageContent = TextMessage.obtain("测试超级群");
Message message = Message.obtain(targetId, conversationType, channelId, messageContent);
媒体消息内容指 MediaMessageContent
的子类,例如图片消息(ImageMessage)、GIF 消息(GIFMessage)等。
String targetId = "超级群 ID";
ConversationType conversationType = Conversation.ConversationType.ULTRA_GROUP;
String channelId = "超级群频道 ID";
Uri localUri = Uri.parse("file://图片的路径");//图片本地路径,接收方可以通过 getThumUri 获取自动生成的缩略图 Uri
boolean mIsFull = true; //是否发送原图
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, channelId, mediaMessageContent);
- 如果您的应用/环境在 2022.10.13 日及以后开通超级群服务,超级群业务中会包含一个 ID 为
RCDefault
的默认频道。如果发消息时不指定频道 ID,则该消息会发送到RCDefault
频道中。 - 如果您的应用/环境在 2022.10.13 日前已开通超级群服务,在发送消息时如果不指定频道 ID,则该消息不属于任何频道。融云支持客户调整服务至最新行为。该行为调整将影响客户端、服务端收发消息、获取会话、清除历史消息、禁言等多个功能。如有需要,请提交工单咨询详细方案。
发送普通消息
发送超级群普通消息需要使用 RongCoreClient 中的提供的 sendMessage
方法。
RongCoreClient.getInstance().sendMessage(message, null, null, new IRongCoreCallback.ISendMessageCallback() {
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode errorCode) {
}
});
sendMessage
中直接提供了用于控制推送通知内容(pushContent
)和推送附加信息(pushData
)的参数。不过,如果您需要更精细地控制离线推送通知,例如标题、内容、图标、或其他第三方厂商个性化配置,请使用消息推送属性进行配置,详见自定义消息推送通知。
- 如果发送的消息属于 SDK 内置的普通消息类型,例如 TextMessage,这两个参数可设置为
null
。一旦消息触发离线推送通知时,融云服务端会使用各个内置消息类型默认的pushContent
值。关于各类型消息的默认推送通知内容,详见用户内容类消息格式。 - 如果消息类型为自定义消息类型,且需要支持离线推送通知,则必须向融云提供
pushContent
字段,否则用户无法收到离线推送通知。 - 如果消息类型为自定义消息类型,但不需要支持远程推送通知(例如通过自定义消息类型实现的 App 业务层操作指令),可将
pushContent
字段留空。 Message
的推送属性配置MessagePushConfig
的pushContent
和pushData
会覆盖此处配置,并提供更多配置能力,例如自定义推送通知的标题。详见自定义消息推送通知。
参数 | 类型 | 说明 |
---|---|---|
message | Message | 要发送的消息实体,在消息实体中必须指定会话类型(conversationType ),目标 ID(targetId ),消息内容(messageContent )。详见消息介绍。 |
pushContent | String | 修改或指定远程消息推送通知栏显示的内容。您也可以在 Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见自定义消息推送通知。
|
pushData | String | 远程推送附加信息。对端收到远程推送消息时,可通过以下方法获取该字段内容:
Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见自定义消息推送通知。 |
callback | ISendMessageCallback | 发送消息的回调 |
发送媒体消息
媒体消息 Message
对象的 content
字段必须传入 MediaMessageContent 的子类对象,表示媒体消息内容。例如图片消息内容(ImageMessage)、GIF 消息内容(GIFMessage),或继承自 MediaMessageContent 的自定义媒体消息内容。
图片消息(ImageMessage)支持设置为发送原图。
String targetId = "目标 ID";
ConversationType conversationType = ConversationType.ULTRA_GROUP;
String channelId = "目标频道 ID";
Uri localUri = Uri.parse("file://图片的路径");//图片本地路径,接收方可以通过 getThumUri 获取自动生成的缩略图 Uri
boolean mIsFull = true; //是否发送原图
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, channelId, mediaMessageContent);
向超级群中发送媒体消息需要使用 RongCoreClient 中的 sendMediaMessage
方法。SDK 会为图片、小视频等生成缩略图,根据默认压缩配置进行压缩,再将图片、小视频等媒体文件上传到融云默认的文件服务器(文件存储时长),上传成功之后再发送消息。图片消息如已设置为发送原图,则不会进行压缩。
RongCoreClient.getInstance().sendMediaMessage(message, null, null, new IRongCoreCallback.ISendMediaMessageCallback() {
@Override
public void onProgress(Message message, int i) {
}
@Override
public void onCanceled(Message message) {
}
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(final Message message, final IRongCoreEnum.CoreErrorCode errorCode) {
}
});
sendMediaMessage
中直接提供了用于控制推送通知内容(pushContent
)和推送附加信息(pushData
)的参数。不过,如果您需要更精细地控制离线推送通知,例如标题、内容、图标、或其他第三方厂商个性化配置,请使用消息推送属性进行配置,详见自定义消息推送通知。
- 如果发送的消息属于 SDK 内置的媒体消息类型,例如 ImageMessage,这两个参数可设置为
null
。一旦消息触发离线推送通知时,融云服务端会使用各个内置消息类型默认的pushContent
值。关于各类型消息的默认推送通知内容,详见用户内容类消息格式。 - 如果消息类型为自定义消息类型,且需要支持离线推送通知,则必须向融云提供
pushContent
字段,否则用户无法收到离线推送通知。 - 如果消息类型为自定义消息类型,但不需要支持远程推送通知(例如通过自定义消息类型实现的 App 业务层操作指令),可将
pushContent
字段留空。 Message
的推送属性配置MessagePushConfig
的pushContent
和pushData
会覆盖此处配置,并提供更多配置能力,例如自定义推送通知的标题。详见自定义消息推送通知。
参数 | 类型 | 说明 |
---|---|---|
message | Message | 要发送的消息实体,在消息实体中必须指定会话类型(conversationType ),目标 ID(targetId ) ,消息内容(messageContent )。详见消息介绍。 |
pushContent | String | 修改或指定远程消息推送通知栏显示的内容。您也可以在 Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见自定义消息推送通知。
|
pushData | String | 远程推送附加信息。对端收到远程推送消息时,可通过以下方法获取该字段内容:
Message 的推送属性(MessagePushConfig )中配置,会覆盖此处配置,详见自定义消息推送通知。 |
callback | ISendMediaMessageCallback | 发送媒体消息的回调 |
接收消息
消息接收监听的设置在 RongCoreClient 中。
设置监听
public static boolean addOnReceiveMessageListener(OnReceiveMessageWrapperListener listener)
实现监听代理方法
public boolean onReceived(Message message, int left)
如何发送 @ 消息
@消息在融云即时通讯服务中不属于一种预定义的消息类型(详见服务端文档 消息类型概述)。融云通过在消息中携带 mentionedInfo
数据,帮助 App 实现提及他人(@)功能。
消息的 MessageContent
中的 MentionedInfo 字段存储了携带所 @ 人员的信息。无论是 SDK 内置消息类型,或者您自定义的消息类型,都直接或间接继承了 MessageContent 类。
融云支持在向群组和超级群中发消息时,在消息内容中添加 mentionedInfo
。消息发送前,您可以构造 MentionedInfo
,并设置到消息的 MessageContent
中。
List<String> userIdList = new ArrayList<>();
userIdList.add("userId1");
userIdList.add("userId2");
MentionedInfo mentionedInfo = new MentionedInfo(MentionedInfo.MentionedType.PART, userIdList, null);
TextMessage messageContent = TextMessage.obtain("文本消息");
messageContent.setMentionedInfo(mentionedInfo);
MentionedInfo
参数:
参数 | 类型 | 说明 |
---|---|---|
type | MentionedType | (必填)指定 MentionedInfo 的类型。MentionedType.ALL 表示需要提及(@)所有人。MentionedType.PART 表示需要 @ 部分人,被提及的人员需要在 userIdList 中指定。 |
userIdList | List<String> | 被提及(@)用户的 ID 集合。当 type 为 MentionedType.PART 时必填。 |
mentionedContent | String | 触发离线消息推送时,通知栏显示的内容。如果是 NULL ,则显示默认提示内容(“有人 @ 你”)。@消息携带的 mentionedContent 优先级最高,会覆盖所有默认或自定义的 pushContent 数据。 |
IMLib SDK 接收消息后,您需要处理 @ 消息中的数据。您可以在获取 Message
(消息对象)后,通过以下方法获取到消息对象携带的 MentionedInfo
对象。
MentionedInfo mentionedInfo = message.getContent().getMentionedInfo();
自定义消息推送通知
您可以在发送消息时提供 MessagePushConfig
配置,对单条消息的推送行为进行个性化配置。例如:
- 自定义推送标题、推送通知内容
- 自定义通知栏图标
- 添加远程推送附加信息
- 越过接收客户端的配置,强制在推送通知内显示通知内容
- 其他 APNs 或 Android 推送通道支持的个性化配置
关于 MessagePushConfig
的配置方式详见自定义消息推送通知。
为消息禁用推送通知
在接收者未上线时,融云服务端默认触发推送服务,将消息通过推送通道下发(服务端是否触发推送也会收到应用级别、用户级别免打扰设置的影响)。
您的 App 用户可能希望在发送消息时就指定该条消息不需要触发推送,该需求可通过 Message
对象的 MessageConfig
配置实现。
以下示例中,我们将 messageConfig
的 disableNotification
设置为 true
禁用该条消息的推送通知。接收方再次上线时需要主动拉取。
String targetId = "目标 ID";
String channelId = "目标频道 ID";
ConversationType conversationType = ConversationType.ULTRA_GROUP;
TextMessage messageContent = TextMessage.obtain("消息内容");
Message message = Message.obtain(targetId, conversationType, channelId, messageContent);
message.setMessageConfig(new MessageConfig.Builder().setDisableNotification(true).build());
如何处理消息发送失败
对于客户端本地会存储的消息类型(参见消息类型概述),如果触发(onAttached
)回调,表示此时该消息已存入本地数据库,并已进入本地消息列表。
- 如果入库失败,您可以检查参数是否合法,设备存储是否可正常写入。
- 如果入库成功,但消息发送失败(
onError
),App 可以在 UI 临时展示这条发送失败的消息,并缓存onError
抛出的Message
实例,在合适的时机重新调用sendMessage
/sendMediaMessage
发送。请注意,如果不复用该消息实例,而是重发相同内容的新消息,本地消息列表中会存储内容重复的两条消息。
对于客户端本地不存储的消息,如果发送失败(onError
),App 可缓存消息实例再重试发送,或直接新建消息实例进行发送。