AIMSDK支持端到端的消息发送和接收,同时提供了发送和接收流程上的一定的自定义能力,开发者可以根据自身业务的特点做定制。每个消息都是和会话(单聊和群聊)关联的,发送前消息需要先获得会话标识(cid)。全文的示例代码均以Android代码为例。

消息类型

支持的消息类型:文本消息图片消息语音消息视频消息地理消息结构化消息文件消息回复消息转发消息自定义消息

除自定义消息以外其他消息类型均属于标准消息类型。开发者可以通过自定义消息类型,自定义消息的内容协议(例如二进制数据,内存块等)。每种消息类型都有共有属性(例如已读、未读等)和内容属性。消息共有属性,请参见消息属性

消息类型说明,如下表所示:
消息类型 AIMMsgContentType 说明
文本消息 CONTENT_TYPE_TEXT 不同的文字消息,使用UTF8编码。
图片消息 CONTENT_TYPE_IMAGE 支持JPG、GIF、PNG、BMP等格式,会自动为原始图片生成缩略图。
语音消息 CONTENT_TYPE_AUDIO 支持AMR、OGG、OPUS、MP3、WAV格式。
视频消息 CONTENT_TYPE_VIDEO 支持格式:AVI、RMVB、RM、MPG、WMV、MKV、VOB、MP4。
地理消息 CONTENT_TYPE_GEO 包括位置经纬度和图片。
结构化消息 CONTENT_TYPE_STRUCT 借助结构化消息可以实现系统消息和@人消息。
自定义消息 CONTENT_TYPE_CUSTOM 开发者自定义内容和子类型,采用二进制格式传输。
文件消息 CONTENT_TYPE_FILE 文件类型信息。
回复消息 CONTENT_TYPE_REPLY 消息回复,不可回复合并转发消息。
转发消息 CONTENT_TYPE_COMBINE_FORWARD 分为普通转发和合并转发。
说明 AIMMsgContentType枚举中的CONTENT_TYPE_LINKCONTENT_TYPE_AT 消息类型暂不对外开放。
消息类型结构,如下图所示:发送与接收

消息属性

属性 类型 说明
appCid string 会话唯一标识。
mid string 消息服务端唯一标识,消息发送成功前为空。
注意 mid在所有端唯一,重装后不变,在消息发送中、发送失败、纯本地消息(未完成发送)都是为空。
localid string 消息本地唯一标识,不为空。
注意 localid在本地唯一,不同设备不唯一,且成功安装一次后不变,只有在重装后才改变。
sender AIMUserId 发送者(uid)。
receivers list 接收者数组,空表示发给会话中的所有人。
createdAt long 消息发送时间。
unreadCount int 未读数。
receiverCount int 接收者数量。
is_read bool 是否自己已读。
entension map 业务扩展信息(共有),所有接收人一样。
local_extension map 业务本地扩展信息。
user_extension map 业务扩展信息(个人),接收人可能不一样。
content AIMMsgContent 消息内容。
status AIMMsgSendStatus 消息状态(发送成功、发送中、发送失败)。
is_delete bool 是否删除。
is_recall bool 是否撤回。
is_disable_read bool 是否不能发送已读,已读降级的场景使用。
is_local bool 是否是本地消息,发送中、发送失败、本地系统消息都属于本地消息,纯粹的本地消息没有mid。
biz_info AIMMsgBizInfo 搜索用信息。
display_style AIMMsgDisplayStyle 消息展示类型(用户消息、系统消息)。
recall_feature AIMMsgRecallFeature 消息撤回信息。

消息发送

消息发送主要依靠AIMPubModule中的AIMPubMsgService相关接口实现。

消息发送的标准流程,如下图所示:标准模式
  1. GetMsgService:
    1. 获取当前用户(userid)的AIMPubModule
    2. AIMPubModule中获取消息服务AIMPubMsgService对象。
    3. 构造AIMPubMsgSendMessage消息体。
  2. SendMessage:调用AIMPubMsgServicesendMessage接口。
  3. onAddedMessages(Sending):通知创建了一个新的AIMPubMessage对象,消息状态(status)为发送中(Sending),表示已经向服务端发起请求,还没有收到服务端返回。
    说明 此时的消息ID(mid)为空,本地消息标识(localid)不为空,消息未读数无效。
  4. onConvLastMessageChanged(Sending):通知会话的最后一条消息变更,消息体内容和OnAddedMessages(Sending)保持一致。
  5. onProgress:消息发送的进度,只有发送消息中包含文件上传才会触发,比如图片消息、视频消息等。
  6. onMsgStatusChanged:消息发送成功后,状态(status)、是否已读(isRead)、消息(IDmid)、未读数(unReadCount)等字段都将变更。
  7. onSuccess:通知消息发送成功。
  8. onConvLastMessageChanged:消息发送成功后,会通知会话的最后一条消息发生了变更。
上述IMSDK(即时通讯服务)的回调,来自于不同的监听器(Listener),具体归属如下表所示:
回调函数 归属Listener 归属Service
onAddedMessages AIMPubMsgListener AIMPubMsgService
onMsgStatusChanged AIMPubMsgChangeListener AIMPubMsgService
onConvLastMessageChanged AIMPubConvChangeListener AIMPubConvService
onProgress AIMPubMsgSendMsgListener 临时Listener,不直接属于任何service。
onSuccess AIMPubMsgSendMsgListener 临时Listener,不直接属于任何service。
调用的示例代码,如下所示:
// first.java
// 外部构造完成AIMPubMsgSendMessage消息体传入
private void sendMessage(AIMPubMsgSendMessage message) {
  AIMPubModule module = AIMPubModule.getModuleInstance(getCurrentUserId());
  // 根据用户UserID获取AIMPubModule
  AIMPubMsgService service = module.getMsgService();
  // 获取MsgService
  service.sendMessage(message, new AIMPubMsgSendMsgListener() {
    // 调用sendMessage接口
    // 构造AIMPubMsgSendMsgListener,注册消息发送进度回调
    @Override
    public void onProgress(double v) {
      AIMLog.e("发送消息中..." + v);
      // 更新发送状态,以onAdded回调为准
    }

    @Override
    public void onSuccess(AIMPubMessage AIMPubMessage) {
      AIMLog.e("发送消息成功");
      // 消息发送成功
    }

    @Override
    public void onFailure(DPSError DPSError) {
      AIMLog.e("发送消息失败, code:" + DPSError);
      // 消息发送失败
    }
  }, new HashMap<String, String>());
}
说明

sendMessage接口的userData参数用于埋点测试,App一般不需要配置该参数,传入一个空的HashMap即可。

回复消息和转发消息AIMPubMsgService提供了专门的调用接口,客户端不需要手动构造AIMPubMsgSendMessage调用SendMessage

消息发送示例

  • 文本消息(纯文本)
    示例代码,如下所示:
    // 构造AIMPubMsgTextContent
    AIMPubMsgTextContent textContent = new AIMPubMsgTextContent();
    // 给文本信息赋值
    textContent.text = text;
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = newAIMPubMsgContent();
    // 定义Content类型
    content.contentType = AIMMsgContentType.CONTENT_TYPE_TEXT;
    content.textContent = textContent; // 给textContnet成员属性赋值
    
    // 构造AIMPubMsgSendMessage
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    // 会话ID
    message.appCid = cid;
    // 消息体内容赋值
    message.content = content;
    // 定义接收者列表(ArrayList)
    message.receivers = receivers;
    关键数据结构,请参见AIMPubMsgTextContentAIMPubMsgContentAIMPubMsgSendMessage
  • 图片消息

    图片消息支持发送多种类型的图片,客户端在构造AIMMsgImageContent时需要填写IMSDK的本地上传路径uploadPath或localPath。IMSDK会自动将图片文件上传到文件服务器(如过在配置DPSPubEngine时没有配置文件上传服务器fileUploadServerAddress, 则上传到默认的文件服务器)。AIMPaaS服务端收到图片消息后,会将图片原图下载的URL,以及自动生成的缩略图文件的下载URL更新到AIMPubMessage消息体中并下发。图片消息的接收方可以根据AIMPubMessage中的图片URL,通过IM媒体服务AIMMediaService下载到所需图片。

    说明 IMPaaS下发的图片消息中会带有缩略图数据BlurredData,可以直接获得缩略图数据,不需要使用URL下载。但在弱网的情况下,不一定会有缩略图数据。
    示例代码,如下所示:
    // 构造AIMMsgImageContent
    AIMMsgImageContent imageContent = new AIMMsgImageContent();
    // 设置图片本地地址
    imageContent.localPath = localPath;
    // 设置是否压缩Flag
    imageContent.type = AIMMsgImageCompressType.IMAGE_COMPRESS_TYPE_ORIGINAL;
    // 设置图片类型
    imageContent.fileType = AIMMsgImageFileType.IMAGE_FILE_TYPE_JPG;
    // 设置MIME类型
    imageContent.mimeType = "image/jpeg";
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_IMAGE;
    content.imageContent = imageContent;
    
    // 构造AIMPubMsgSendMessage
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    receivers.add(userId);                      // 对方的UserId
    receivers.add(UserUtil.getCurrentUserId()); // 自己的UserId
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgImageContent
  • 视频消息

    视频消息支持发送各种类型的视频文件,文件的上传下载逻辑与图片信息类似,都是通过将视频文件上传到文件服务器,并通知接收方使用URL进行下载。与图片消息不同的是,视频消息中需要额外提供视频的封面文件以及相关文件信息,帮助视频信息接收者在未下载视频文件时正确显示这条视频消息。

    示例代码,如下所示:
    // 构造AIMMsgVideoContent
    AIMMsgVideoContent videoContent = new AIMMsgVideoContent();
    videoContent.localPath = localPath;
    videoContent.mimeType = "video/mp4";
    videoContent.fileType = ".mp4";
    
    // 视频封面位置
    videoContent.coverLocalPath = coverPath;
    viedoContent.coverFileType = AIMMsgImageFileType.IMAGE_FILE_TYPE_JPG;
    videoContent.coverMimeType = "image/jpeg";
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_VIDEO;
    content.videoContent = videoContent;
    
    // 构造AIMPubMsgSendMessage
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgVideoContent
  • 音频消息

    音频消息支持多种格式(opus、ogg、amr等)音频数据的收发,发送方仍然是发送消息+上传文件的形式。IMPaaS服务端会将模糊语音的二进制数据放进下发消息AIMPubMessagebinaryData字段中,接收方可以直接从中得到音频数据,当然也可以通过音频文件URL借助AIMMediaService下载音频文件。

    注意 音频消息尽量不超过100KB,超过100KB的音频可以使用文件消息发送。

    模糊语音在弱网的状态下,不一定会有数据。

    示例代码,如下所示:
    // 构造AIMMsgAudioContent
    AIMMsgAudioContent audioContent = new AIMMsgVideoContent();
    audioContent.localPath = audioPath;
    audioContent.mimeType = "audio/mp3";
    audioContent.audioType = AUDIO_TYPE_UNKNOWN;
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_AUDIO;
    content.audioContent = audioContent;
    
    // 构造AIMPubMsgSendMessage
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgAudioContent
  • 地理信息

    地理信息中包括了地理位置的名称、经纬度、地理位置图片信息,可以理解为地理信息就是对图片信息的一种扩展,逻辑与图片信息基本一致。

    示例代码,如下所示:
    // 构造AIMMsgGeoContent
    AIMMsgGeoContent geoContent = new AIMMsgGeoContent();
    geoContent.picLocalPath = picLocalPath;
    geoContent.longitude = longitude;
    geoContent.latitude = latitude;
    geoContent.locationName = locationName;
    geoContent.picFileType = AIMMsgImageFileType.IMAGE_FILE_TYPE_JPG;
    geoContent.mimeType = "image/jpg";
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_GEO;
    content.geoContent = geoContent;
    
    // 构造AIMPubMsgSendMessage
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgGeoContent
  • 自定义消息

    自定义消息能够支持客户端实现更多的消息类型,消息AIMMsgCustomContent中为客户端、开发者预留了Type、Title、Summary、Degrade字段以及二进制数组binaryData。IM服务对二进制数据和所有字段只做透传,由客户端开发者自行解析相关数据。

    示例代码,如下所示:
    // 构造AIMMsgCustomContent
    AIMMsgCustomContent customContent = new AIMMsgCustonContent();
    customContent.type = type;
    customContent.title = title;
    customContent.summary = summary;
    customContent.degrade = degrade;
    // 给Byte数组赋值
    byte[] byteArray = new byte[10];
    byteArray[0] = 1;
    byteArray[1] = 2;
    ... customContent.binaryData = byteArray;
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_CUSTOM;
    content.customContent = customContent;
    
    // 构造AIMPubMsgSendMessage
    
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgCustomContent
  • 结构化消息

    结构化消息可以用于实现@消息、系统消息,每个消息包括元素链表,每个元素目前有两中类型,文本context类型和uid类型,uid类型包含了用户ID信息,开发者需要替换用户ID为真实的姓名。

    结构化消息实现系统消息的示例图,如下所示:系统消息
    结构化消息实现系统消息的示例代码,如下所示:
    // 构造AIMPubMsgStructContent
    AIMPubMsgStructContent structContent = new AIMPubMsgStructContent();
    structContent.elements = new ArrayList<AIMPubMsgStructElement>();
    
    AIMPubMsgStructElement structElement1 = new AIMPubMsgStructElement();
    structElement1.elementType = AIMMsgStructElementType.ELEMENT_TYPE_TEXT;
    structElement1.textContent = new AIMPubMsgTextContent("用户");
    structContent.elements.add(structElement1);
    
    AIMPubMsgStructElement structElement2 = new AIMPubMsgStructElement();
    structElement2.elementType = AIMMsgStructElementType.ELEMENT_TYPE_UID;
    structElement2.uidElement =
        new AIMPubMsgStructElementUid("123456", "张三", "prefix");
    structContent.element.add(structElement2);
    
    AIMPubMsgStructElement structElement3 = new AIMPubMsgStructElement();
    structElement3.elementType = AIMMsgStructElementType.ELEMENT_TYPE_TEXT;
    structElement3.textContent = new AIMPubMsgTextContent("邀请用户");
    structContent.elements.add(structElement3);
    
    AIMPubMsgStructElement structElement4 = new AIMPubMsgStructElement();
    structElement4.elementType = AIMMsgStructElementType.ELEMENT_TYPE_UID;
    structElement4.uidElement =
        new AIMPubMsgStructElementUid("234567", "李四", "prefix");
    structContent.element.add(structElement4);
    
    AIMPubMsgStructElement structElement5 = new AIMPubMsgStructElement();
    structElement5.elementType = AIMMsgStructElementType.ELEMENT_TYPE_TEXT;
    structElement5.textContent = new AIMPubMsgTextContent("加入群聊");
    structContent.elements.add(structElement5);
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_STRUCT;
    content.structContent = structContent;
    
    // 构造AIMPubMsgSendMessage
    
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    结构化消息实现@消息的示例图,如下所示:@消息
    结构化消息实现@消息的示例代码,如下所示:
    // 构造AIMPubMsgStructContent
    AIMPubMsgStructContent structContent = new AIMPubMsgStructContent();
    structContent.elements = new ArrayList<AIMPubMsgStructElement>();
    
    AIMPubMsgStructElement structElement1 = new AIMPubMsgStructElement();
    structElement1.elementType = AIMMsgStructElementType.ELEMENT_TYPE_AT;
    structElement1.atElement = new AIMPubMsgTextContent(false, "123456", "张三");
    structContent.elements.add(structElement1);
    
    AIMPubMsgStructElement structElement2 = new AIMPubMsgStructElement();
    structElement2.elementType = AIMMsgStructElementType.ELEMENT_TYPE_AT;
    structElement2.atElement = new AIMPubMsgTextContent(false, "234567", "李四");
    structContent.elements.add(structElement2);
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_STRUCT;
    content.structContent = structContent;
    
    // 构造AIMPubMsgSendMessage
    
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMPubMsgStructContentAIMPubMsgStructElementAIMPubMsgTextContentAIMPubStructElementUidAIMPubMsgStructElementAt
  • 文件消息

    文件消息与前面的图片消息、视频消息、音频消息基本类似,只是少了一些类型相关的描述字段。

    示例代码,如下所示:
    // 造AIMMsgFileContent
    AIMMsgFileContent fileContent = new AIMMsgFileContent();
    fileContent.localPath = localPath;
    fileContnet.fileType = "pdf";
    fileCotnent.mimeType = "normal/pdf";
    
    // 造AIMPubMsgContent
    AIMPubMsgContent content = new AIMPubMsgContent();
    content.contentType = AIMMsgContentType.CONTENT_TYPE_FILE;
    content.structContent = structContent;
    
    // 造AIMPubMsgSendMessage
    
    AIMPubMsgSendMessage message = new AIMPubMsgSendMessage();
    ArrayList<String> receivers = new ArrayList<String>();
    // 对方的UserId
    receivers.add(userId);
    // 自己的UserId
    receivers.add(UserUtil.getCurrentUserId());
    message.appCid = cid;
    message.content = content;
    message.receivers = receivers;
    关键数据结构,请参见AIMMsgFileContent
  • 回复消息

    回复消息是指引用一条已有消息,在其基础上再添一条新的消息,并将两条消息合并发送给消息接受者。

    构造回复消息时,发送者需要构造AIMPubMsgSendReplyMessage。在AIMPubMsgReplyContent字段中包含了回复的已有消息AIMPubMsgReference和新消息AIMPubMsgInnerReplyContent

    AIMPubMsgSendReplyMessageAIMPubMsgSendMessage不同之处在于,AIMPubMsgSendReplyMessage需要填写引用的已有消息的Mid,同时也说明了只能回复拥有Mid的消息;而接受者仍然会接收到一条AIMPubMessage消息,消息类型为CONTENT_TYPE_REPLY

    说明 目前回复消息中的新消息仅支持文本消息和结构化消息。

    对回复类型消息进行回复,只保留原回复类型消息中的新消息,原回复类型消息中的已有消息会被抛弃。

    示例代码,如下所示:
    // 构造AIMPubMsgTextContent(以回复文本消息为例,注意:回复消息只能是文本消息或者结构化消息)
    AIMPubMsgTextContent textContent = new AIMPubMsgTextContent();
    textContent.text = text; // 给文本信息赋值
    
    // 构造AIMPubMsgContent
    AIMPubMsgContent replyContent = newAIMPubMsgContent();
    replyContent.contentType =
        AIMMsgContentType.CONTENT_TYPE_TEXT; // 定义Content类型
    replyContent.textContent = textContent;  // 给textContnet成员属性赋值
    
    // 构造AIMPubMsgSendReplyMessage
    AIMPubMsgSendReplyMessage replyMessage = new 构造AIMPubMsgSendReplyMessage();
    // 设置会话ID
    replyMessage.appCid = cid;
    // 设置引用消息Mid
    replyMessage.referenceMid = referenceMid;
    // 设置回复消息Content
    replyMessage.replyContent = replyContent;
    // 设置消息接收者
    replyMessage.receivers = receiver;
    
    private void replyMessage(AIMPubMsgSendReplyMessage message) {
      AIMPubModule module = AIMPubModule.getModuleInstance(getCurrentUserId());
      // 根据用户UserID获取AIMPubModule
      AIMPubMsgService service = module.getMsgService();
      // 获取MsgService
      service.replyMessage(message, new AIMPubMsgReSendMsgListener() {
        // 注意不是ReplySendMsgListener
        // 调用replyMessage接口
        // 构造AIMPubMsgReSendMsgListener,注册消息发送进度回调
        @Override
        public void onProgress(double v) {
          AIMLog.e("发送消息中..." + v);
          //更新发送状态,以onAdded回调为准
        }
    
        @Override
        public void onSuccess(AIMPubMessage AIMPubMessage) {
          AIMLog.e("发送消息成功");
          // 消息发送成功
        }
    
        @Override
        public void onFailure(DPSError DPSError) {
          AIMLog.e("发送消息失败, code:" + DPSError);
          // 消息发送失败
        }
      }, new HashMap<String, String>());
    }
    关键数据结构,请参见AIMPubMsgSendReplyMessage
  • 转发消息
    转发消息分为两种,普通转发和合并转发:
    • 普通转发

      普通转发中,转发者通过指定Mid列表选择需要转发的消息列表,选择好接收者receivers后,调用AIMPubMsgServieforwardMessage接口转发消息;所有指定的接收者都会逐条接收到转发的消息AIMPubMessage,消息类型也为被转发消息本身的类型。

      示例代码,如下所示:
      // 构造AIMPubMsgForwardMessage
      AIMPubMsgForwardMessage forwardMessage = new AIMPubMsgForwardMessage();
      // 需要转发的消息的源会话Id
      forwardMessage.appCid = appCid;
      // 需要转发的消息mid列表
      forwardMessage.mids = mids;
      // 需要转发到的目标会话Id
      forwardMessage.toAppCid = toAppCid;
      // 需要转发到的目标UserId
      forwardMessage.receivers = receivers;
      
      private void forwardMessage(AIMPubMsgForwardMessage message) {
        AIMPubModule module = AIMPubModule.getModuleInstance(getCurrentUserId());
        // 根据用户UserID获取AIMPubModule
        AIMPubMsgService service = module.getMsgService();
        // 获取MsgService
        service.forwardMessage(message, new AIMPubMsgForwardMsgListener() {
          // forwardMessage
          @Override
          public void onSuccess(AIMPubMessage AIMPubMessage) {
            AIMLog.e("发送消息成功");
            // 消息发送成功
          }
      
          @Override
          public void onFailure(DPSError DPSError) {
            AIMLog.e("发送消息失败, code:" + DPSError);
            // 消息发送失败
          }
        }, new HashMap<String, String>());
      }

      关键数据结构,请参见AIMPubMsgForwardMessage

    • 合并转发

      合并转发中,转发者通过指定Mid列表选择需要转发的消息列表,选择好接收者receivers后,调用AIMPubMsgServiecombineForwardMessage接口转发消息,与普通转发消息不同的是,接收者只会收到一条消息AIMPubMessage,消息类型为CONTENT_TYPE_COMBINE_FORWARD

      合并消息解析说明,请参见转发接收示例

      说明 注意合并转发的消息中,可以包含回复类型CONTENT_TYPE_REPLY消息,但不允许包含类型为CONTENT_TYPE_COMBINE_FORWARD的消息。
      示例代码,如下所示:
      // 构造AIMPubMsgForwardMessage
      AIMPubMsgForwardMessage forwardMessage = new AIMPubMsgForwardMessage();
      
      // 构造AIMPubMsgForwardMessage
      AIMPubMsgForwardMessage forwardMessage = new AIMPubMsgForwardMessage();
      // 需要转发的消息的源会话Id
      forwardMessage.appCid = appCid;
      // 需要转发的消息mid列表
      forwardMessage.mids = mids;
      // 需要转发到的目标会话Id
      forwardMessage.toAppCid = toAppCid;
      // 需要转发到的目标UserId
      forwardMessage.receivers = receivers;
      
      private void combineForwardMessage(AIMPubMsgForwardMessage message) {
        AIMPubModule module = AIMPubModule.getModuleInstance(getCurrentUserId());
        // 根据用户UserID获取AIMPubModule
        AIMPubMsgService service = module.getMsgService();
        // 获取MsgService
        service.combineForwardMessage(
            message, new AIMPubMsgCombineForwardMsgListener() {
              // combineForwardMessage
              @Override
              public void onSuccess(AIMPubMessage AIMPubMessage) {
                AIMLog.e("发送消息成功");
                // 消息发送成功
              }
      
              @Override
              public void onFailure(DPSError DPSError) {
                AIMLog.e("发送消息失败, code:" + DPSError);
                // 消息发送失败
              }
            }, new HashMap<String, String>());
      }

      关键数据结构,请参见AIMPubMsgForwardMessage

消息接收

消息接收即消息的同步,AIMSDK使用推拉结合的方式。7000条及以内或最近一周的消息采用推送的方式,7000条以外的消息采用主动拉取的方式。

  • 消息推送

    AIMSDK会将IMPaaS服务端主动推送的消息通过AIMPubMsgListeneronAddedMessges接口回调给客户端。

    AIMPubMsgListener由客户端自己构造并向AIMPubMsgService注册,可以向AIMPubMsgService注册多个AIMPubMsgListenr,当有新消息推送时,AIMSDK会依次调用每个AIMPubMsgListeneronAddedMessges接口。

    示例代码,如下所示:
    // 注册AIMPubMsgListener
    AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
    AIMPubMsgService service = module.getMsgService();
    service.addMsgListener(new AIMPubMsgListener() {
      @Override
      public void onAddedMessages(final ArrayList<AIMPubNewMessage> arrayList) {
        // 消息推送回调接口
        AIMLog.toastWrapper("onAdded");
      }
    
      @Override
      public void onRemovedMessages(ArrayList<AIMPubMessage> arrayList) {
        AIMLog.e("删除消息:size:" + arrayList.size());
        // 见删除消息部分
        AIMLog.toastWrapper("onRemoved");
      }
    
      @Override
      public void onStoredMessages(ArrayList<AIMPubMessage> arrayList) {
        AIMLog.e("onStored:size:" + arrayList.size());
        // 当消息数据库内有消息添加时,触发该回调 包括发送,推送及拉取历史消息
        AIMLog.toastWrapper("onStored");
      }
    });
    关键数据结构,请参见AIMPubNewMessage
  • 消息拉取
    消息拉取的使用有两种情况,如下所示:
    • 例如客户端启动时,需要拉取一定量的历史消息显示在首屏,或者是用户向上滑动聊天框希望看到历史聊天记录。
    • 例如客户端离线期间,IMPaaS服务端堆积了大量等待推送的消息,当离线的数据有积压(超过一定的条数或时间)服务端就不会在客户端重新上线时推送这些历史离线消息,需要在客户端上重新进行拉取。

    消息的拉取由AIMPubMsgService的四个接口实现,listNextLocalMsgslistNextMsgslistPreviousLocalMsgslistPreviousMsgs

    四个接口都有共同的入参,如下所示:
    • appCid表示需要拉取的会话ID。
    • cursor标识需要拉取的消息的时间游标起点。
    • listener用于监听拉取消息回调结果。
    • count标识客户端希望拉取的消息数目(同时也作为AIMSDK返回消息的条数出参)。

    接口中带有Local修饰的表示该接口只拉取本地数据库中的连续历史消息,没有Local修饰标识该接口会向IMPaaS服务端请求本地数据库中缺失的历史消息记录,并返回连续的历史消息记录。

    拉取消息获得的消息通过AIMPubMsgListeneronAddedMessges接口回调给客户端。

    说明 只拉取本地数据库连续消息记录时,AIMSDK一旦遇到本地数据库消息不连续的地方(gap),本地数据库的消息查询会马上终止,并返回之前查到的连续消息记录,因此返回的消息条数不一定等于希望拉取的消息数目。

    使用没有Local修饰的拉取消息接口拉取消息时,一旦遇到本地数据库消息不连续处,AIMSDK会向IMPaaS服务端请求缺失的消息,并最终组成连续的历史消息记录返回。

    使用没有Local修饰的拉取消息接口拉取消息时,一旦遇到本地数据库消息不连续处,AIMSDK会向IMPaaS服务端请求缺失的消息,并最终组成连续的历史消息记录返回。

    时间戳
    拉取流程参考图,如下所示:拉取流程
    拉取一次消息流程分为以下两步:
    1. 拉取本地消息,返回本地连续数据,如果返回结果少于请求数,则发起第二步。
    2. 拉取远端消息,补全第一步不足的消息。
    使用AIM_MAX_MSG_CURSOR字段拉取最新事件,说明如下:
    • 最新时间使用AIM_MAX_MSG_CURSOR。
    • 通常取上一次拉取结果的最后一条消息的创建时间(createdAt)作为下一次API调用的cursor。
    • count为拉取的数量,最多支持每次100个
    • 业务方根据has_more标记来判断是否要发起下一次拉取。当取值为false时,表示会话没有更多的消息。
    • 消息列表会包含请求的createdAt等于cursor的消息,业务方需要去重。当createAt字段填MAX_CURSOR时,从最新点开始拉取。

消息接收示例

AIMSDK支持包括文本消息、图片消息、视频消息等数十种消息的接收和发送,其中一些消息的接收流程与一般的文本消息略有不同,此处以部分示例为例补充说明。

  • 图片消息

    接收图片消息时,消息中并不包含图片的原始数据(可能包含缩略图数据,具体信息,请参见图片消息),而是包含了图片的下载URL,需要消息接收者利用AIMMediaServicedownloadFile接口下载实际的图片数据。

    说明 其他视频、音频、地理等需要下载文件的消息处理过程都与图片消息类似。
    示例代码,如下所示:
    // 从ImageContent中获得图片下载url,并配置图片保存地址
    AIMDownloadFileParam downloadParam = new AIMDownloadFileParam(
        imageContnet.getUrl(), cameraVideoSavePath.toString());
    // 构造下载进度监听器AIMDownloadFileListener
    AIMDownloadFileListener downloadFileListener = new AIMDownloadFileListener() {
      @Override
      public void onCreate(String s) {}
    
      @Override
      public void onStart() {}
    
      @Override
      public void onProgress(long l, long l1) {
        AIMLog.toastWrapper("下载中");
      }
    
      @Override
      public void onSuccess(String path) {
        AIMLog.toastWrapper("下载成功,请再次点击打开");
        // 对下载图片进行操作,比如显示
        intent.setDataAndType(Uri.fromFile(cameraVideoSavePath), "image/*");
        startActivity(intent);
      }
    
      @Override
      public void onFailure(DPSError dpsError) {}
    };
    
    AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
    AIMMediaService service = module.getMediaService();
    service.downloadFile(downloadParam, downloadFileListener);
  • 回复消息

    回复消息中,AIMPubMsgReplyContent字段被赋值,其中包含了被回复的消息AIMPubMSgReference以及回复的消息AIMPubMsgInnerReplyContent

  • 转发消息(合并转发)

    合并转发消息中,AIMPubMSgCombineForwardContent字段被赋值,里面保存有一个转发消息列表ArrayList<AIMPubMsgCombineForward>,其中每一个元素代表一条转发消息,各自保存了转发消息的发送者senderId,会话IdappCid,消息IdMid以及消息体AIMPubMsgInnerComnineContent

    AIMPubMsgInnerComnineContent消息体中的contentType字段表明该消息的类型,非转发消息的消息内容放置在AIMPubMsgSimpleContent字段中,转发消息CONTENT_TYPE_REPLY的消息内容放置在AIMPubMsgReplyCongtent字段中。

消息撤回

AIMSDK允许消息发送者撤回一定时间内发送过的消息,借助AIMPubMsgServicerecallMessage接口实现。

  • 发送方撤回一条消息

    发送方调用AIMPubMsgServicerecallMessage接口,消息撤回成功后,发送方会收到AIMPubMsgChangeListeneronMsgRecalled回调,此时发送方可以执行撤回成功后的相关操作,比如隐藏掉已经撤回的消息。

    示例代码,如下所示:
    private void recallMessage(final AIMPubMessage messageInfo) {
      AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
      AIMPubMsgService service = module.getMsgService();
      // 设置撤回消息的会话Id,消息Id
      service.recallMessage(messageInfo.getAppCid(), messageInfo.getMid(),
                            new AIMMsgRecallMsgListener() {
                              @Override
                              public void onSuccess() {
                                AIMLog.e("撤回消息成功");
                                //以onMessageRecalled为准
                              }
    
                              @Override
                              public void onFailure(DPSError DPSError) {}
                            });
    }
    
    // 注意,上下代码没有执行上的顺序关系,位于不同的文件中
    // 注册的AIMPubMsgChangeListener
    AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
    AIMPubMsgService service = module.getMsgService();
    service.addMsgChangeListener(new AIMPubMsgChangeListener() {
      @Override
      public void onMsgRecalled(final ArrayList<AIMPubMessage> arrayList) {
        AIMLog.e("消息被撤回:size:" + arrayList.size());
        // 消息撤回成功
      }
    
      ... 未列出所有回调函数
    });
    }
  • 接收方感知消息撤回

    当一条消息被撤回后,接收方会收到AIMPubMsgChangeListeneronMsgRecalled回调,此时接收方可以执行撤回成功后的相关操作,比如隐藏掉已经撤回的消息。

    说明 理论上只要知道会话Id与消息Id,无论是消息发送方还是接收方甚至第三者都可以撤回某条消息。

    消息撤回时限可以在阿里云-直播控制台-直播互动-功能配置中配置,最长为1440分钟。

    被撤回的消息仍然保存在本地数据库和IMPaaS服务端数据库中,拉取消息是仍然能够拉取到这条消息,只是其isRecall字段被设置为true,客户端需要根据该字段来判断这条消息是否是撤回消息。

    关键数据结构,请参见AIMPubMsgRecallFeature

消息删除

消息的发送方或接收方都可以调用AIMPubMsgServicedeleteMessage接口删除一条消息,删除消息是将该消息从本地数据库删除,并且将删除事件同步到云端,IMPaaS服务端会记录这条消息被哪些用户删除,并且在未来这些用户拉取消息时过滤掉这条消息。

消息删除仅针对删除者而言,其他接收到消息或者发送消息者的拉取消息不受影响,也不会收到AIMPubMsgListeneronRemovedMessages回调。

示例代码,如下所示:
// 删除消息
private void deleteMessage(final AIMPubMessage messageInfo) {
  ArrayList<String> mids = new ArrayList<>();
  // 设置需要删除的消息Id
  mids.add(messageInfo.getMid());
  AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
  AIMPubMsgService service = module.getMsgService();
  service.deleteMessage(messageInfo.getAppCid(), mids,
                        new AIMMsgDeleteMsgListener() {
                          @Override
                          public void onSuccess() {
                            AIMLog.e("删除消息成功");
                            // 以onRemovedMessages回调为准
                          }

                          @Override
                          public void onFailure(DPSError DPSError) {}
                        });
}

// 注意,上下代码没有执行上的顺序关系,位于不同的文件中
// 注册监听器AIMPubMsgListener
AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
AIMPubMsgService service = module.getMsgService();
service.addMsgListener(new AIMPubMsgListener() {
  @Override
  public void onRemovedMessages(ArrayList<AIMPubMessage> arrayList) {
    AIMLog.e("删除消息:size:" + arrayList.size());
    AIMLog.toastWrapper("onRemoved");
  }
});

发送消息到本地

可以将消息通过AIMPubMsgServicesendMessageTolocal接口将消息发送到本地,这条消息只会保存在本地数据库中,拉取消息时可以拉取到,但是不会发送给任何人,在其他设备上登录该用户也无法拉取到该消息。

说明 AIMSDK仍然会通过onAddedMessagesonConvLastMessageChanged回调通知这条消息。
示例代码,如下所示:
AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
AIMPubMsgService service = module.getMsgService();
service.sendMessageTolocal(message, new AIMPubMsgSendMsgToLocalListener() {
  @Override
  public void onSuccess(AIMPubMessage aimPubMessage) {
    // 发送消息到本地成功回调
  }

  @Override
  public void onFailure(DPSError dpsError) {}
});

已读未读

消息已读分为两种类型,包括发送者已读和接受者已读。
  • 发送者已读:作为消息的发送者发送的消息有多少接收者已读,是一个0至会话成员数的数字。
  • 接收者已读:消息接收者多端时,同步消息的已读状态。是一个布尔值,会影响自己的在某个会话的消息未读数,也就是会话的未读红点,同时影响消息发送方的消息未读的数字。
  • 发送者已读发送者已读
    1. 发送者发送消息后,接收者通过OnAddedMessages回调收到新消息通知,同时会话未读数字+1。
    2. 当用户查看过消息后,开发者需要调用UpdateMessageToRead接口确认本条消息已读。
    3. 消息的发送方会接收到onUnreadCountChanged回调事件,告知之前的发送的消息,未读用户的数字发生变更。
    4. 持续收到未读数变更事件,直到未读数变为0,代表所有人已读消息。

    消息未读数字是多端同步的,不同的端(iOS、Android)得到的未读数字相同,同样会收到变更事件。除了被动等待onConvUnreadCountChanged回调事件,群聊中发送者还可以主动查询哪些用户已读了自己发送的消息,通过调用AIMPubMsgServiceListMessagesReadStatus接口实现。

    说明 在调用接口ListMessagesReadStatus时,同样会收到OnMsgUnreadCountChanged事件。

    发送者只有消息发送成功了,消息的未读数字属性AIMPubMessage.unreadCount才是生效的。

  • 接受者已读已读
    接收者的消息已读主要体现在会话未读消息数字上,即会话红点,属于同一个帐号不同设备的同步,通过两种途径修改。
    • 设备A调用UpdateMessageToRead,设备B收到会话的事件onUreadCountChanged修改红点数。
    • 调用会话服务AIMPubConvServiceclearRedPoint接口,清理所有的会话红点数字。
说明 以下四种情况特定消息或者会话的未读数量不会增加:
  • 系统消息未读数不增加:display_style = SYSTEM。
  • 当前会话未读数不增加:通过AIMPubConvService.SetActive设置当前会话。
  • 消息未读策略使用了不增加未读数,未读数不增加:服务端接口设置。
  • 消息已经在其他设备上已读未读数不增加。

重发消息

重发消息的功能是选择一条本地数据库存在的消息,将该消息重新发送给之前设置的接受者,使用AIMPubMsgServiceresendMessage接口实现。

重发消息发出的消息将在服务端获得一个新的消息ID,也就是说重发消息resendMessage会产生一条新的消息,同样会触发onAddedMessagesonConvLastMessageChanged等回调函数。

示例代码,如下所示:
AIMPubMsgReSendMessage resendMessage = new AIMPubReSendMessage();
// 消息所属会话id
resendMessage.appCid = cid;      
// 消息本地localid
resendMessage.localid = localid; 

AIMPubModule module = AIMPubModule.getModuleInstance(currentUserId);
AIMPubMsgService service = module.getMsgService();
        service.resendMessage(resendMsg, new AIMPubMsgReSendMsgListener(
            @Override
            public void onProgress(double v) {
              AIMLog.e("发送消息中..." + v);
              //更新发送状态,以onAdded回调为准
            }

            @Override
            public void onSuccess(AIMPubMessage AIMPubMessage) {
              AIMLog.e("发送消息成功");
              // 消息发送成功
            }

            @Override
            public void onFailure(DPSError DPSError) {
              AIMLog.e("发送消息失败, code:" + DPSError);
              // 消息发送失败
            }
        }, new HashMap<String, String>());

数据结构

以下数据结构,均为消息收发时的关键数据结构。
  • AIMPubMsgTextContent
    字段名 类型 含义(发送者) 含义(接受者)
    text String 需要发送的文本。 接收到的文本。
    说明 文本消息最大长度为9000字节。

    相关示例代码。请参见文本消息结构化消息

  • AIMPubMsgContent
    字段名 类型 含义
    contentType AIMMsgContentType 表明了该MsgContent所承载数据的类型。
    textContent AIMPubMsgTextContent 文本消息Content。
    imageContent AIMMsgImageContent 图像消息Content。
    audioContent AIMMsgAudioContent 音频消息Content。
    videoContent AIMMsgVideoContent 视频消息Content。
    geoContent AIMMsgGeoContent 位置消息Content。
    customContent AIMMsgCustomContent 自定义消息Content。
    structContent AIMPubMsgStructContent 结构化消息Content。
    fileContent AIMMsgFileContent 文件消息Content。
    replyContent AIMPubMsgReplyContent 回复消息Content。
    combineForwardContent AIMPubMsgCombineForwardContent 合并转发消息Content。
    说明 AIMPubMsgContent中组合了所有消息类型的Content对象,但是一个AIMPubMsgContent只能承载一种消息(由contentType字段决定),使用时填写的contentType要与所赋值的Content成员匹配。

    相关示例代码。请参见文本消息

  • AIMPubMsgSendMessage
    字段名 类型 含义
    appCid String 会话ID(converisation)。
    content AIMPubMsgContent 发送消息体。
    receivers ArrayList<String> 接受者数组,空则表示发送给会话中的所有人。
    extension HashMap<String, String> 消息扩展字段,客户端自行赋值与使用,IM服务只单纯传输该字段。
    说明 请区分该字段与AIMPubMsgContent中的扩展字段。
    localExtension HashMap<String, String> 消息本地扩展字段,与消息一起保存在本地数据库中,不进行网络传输。
    callbackCtx HashMap<String, String> AIMPaaS回调App服务端的时候会使用,和更多内容,请参见回调概览
    说明 Reveivers字段举例说明,例如有3个人分别为甲乙丙,甲给乙发送了消息,Reveivers字段中填写了丙的UserId,丙会收到消息,且有新增会话事件。但是该会话与丙无关,会话的所有属性字段也不会提及丙。

    相关示例代码。请参见文本消息

  • AIMMsgImageContent
    字段名 类型 含义(发送者) 含义(接受者)
    localPath String 需要填写,表示本地图片位置。 该字段为空。
    uploadPath String 需要填写,表示真正上传的图片本地路径(如果不填写则上传localPath图片)。 该字段为空。
    mimeType String 需要填写,图片MIME类型。 图片MIME类型。
    originalUrl String 不需要填写。 原始图片的下载URL。
    thumbnailUrl String 不需要填写。 缩略图的下载URL。
    blurredData Byte[] 不需要填写。 缩略图的二进制数据,弱网情况下不保证一定有数据。
    mediaId String 不需要填写。 服务端产生的该图片资源的全局唯一ID(多媒体资源标识符)。
    fileName String 可以填写,图片名称(与实际文件名字无关)。 图片文件的名字。
    height int 可以填写,图片的高度(不填写IM会解析出图片高度)。 图片的高度。
    width int 可以填写,图片的宽度(不填写IM会解析出图片宽度)。 图片的宽度。
    size int 可以填写,图片的大小(不填写则默认为0)。 图片的大小。
    type AIMMsgImageCompressType 需要填写,图片是否压缩。 图片是否压缩。
    fileType AIMMsgImageCompressType 需要填写,图片文件类型(webp、png、jpg、gif)。 图片文件类型(webp、png、jpg、gif)。
    orientation AIMMsgOrientation 可以填写,图片旋转参数,可以帮助接收方正确显示图片(默认为未知)。 图片旋转参数。
    extension HashMap<String, String> 可以填写,扩展字段,IM服务会对该字段进行透传。 Content扩展字段。
    说明 MediaId在文件上传成功后得到,如果构造Content时填写MediaId,则本地文件不再重新上传。

    相关示例代码。请参见图片消息

  • AIMMsgVideoContent
    字段名 类型 含义(发送者) 含义(接受者)
    localPath String 需要填写,表示视频文件的本地路径。 该字段为空。
    uploadPath String 需要填写,表示真正上传的视频本地路径(如果不填写则上传localPath视频)。 该字段为空。
    mimeType String 需要填写,视频MIME类型。 视频MIME类型。
    url String 不需要填写。 视频下载的URL。
    mediaId String 不需要填写。 IM服务为该视频生成的全局唯一的ID(多媒体资源标识符)。
    coverLocalPath String 需要填写,视频封面本地路径。 该字段为空。
    coverUploadPath String 需要填写,表示真正上传的视频封面的本地路径(如果不填写,上传coverLocalPath封面)。 该字段为空。
    coverUrl String 不需要填写。 视频封面下载的URL。
    coverMediaId String 不需要填写。 IM服务为该视频生成的全局唯一的MediaId。
    coverFileType AIMMsgImageFileType 需要填写,封面的文件格式。 封面的文件格式。
    coverMIMEType String 需要填写,封面的MIME类型。 封面的MIME类型。
    fileName String 可以填写,视频名称(与实际文件名字无关)。 视频名称。
    fileType String 可以填写,视频类型。 视频类型。
    fileSize long 可以填写(不填写则默认为-1),视频文件大小,单位:B。 视频文件大小,单位:B。
    duration long 可以填写(不填写则默认为-1),视频时长,单位:ms。 视频时长,单位:ms。
    height int 可以填写(不填写默认为-1),视频分辨率高。 视频分辨率高。
    width int 可以填写(不填写默认为-1),视频分辨率宽。 视频分辨率宽。
    coverWidth int 可以填写(不填写IM会解析出封面宽度),封面宽度。 封面宽度。
    coverHeight int 可以填写(不填写IM会解析出封面高度),封面高度。 封面高度。

    相关示例代码。请参见视频消息

  • AIMMsgAudioContent
    字段名 类型 含义(发送者) 含义(接受者)
    localPath String 需要填写,表示音频文件本地路径。 该字段为空。
    uploadPath String 需要填写,表示真正需要上传的音频文件本地路径。 该字段为空。
    mimeType String 需要填写,音频文件MIME类型。 音频文件MIME类型。
    url String 不需要填写。 音频文件下载的URL。
    mediaId String 不需要填写。 IM服务为该视频生成的全局唯一的ID(多媒体资源标识符)。
    binaryData String 不需要填写。 模糊语音二进制数据,弱网状态下不保证一定有数据。
    audioType AIMMsgAudioType 需要填写,音频文件类型(opus、ogg、amr) 音频文件类型。
    duration long 可以填写(不填写默认为0),音频文件时长,单位:ms。 音频文件时长,单位:ms。

    相关示例代码。请参见音频消息

  • AIMMsgGeoContent
    字段名 类型 含义(发送者) 含义(接受者)
    picLocalPath String 需要填写,表示地理图片的本地路径。 该字段为空。
    picUploadPath String 需要填写,表示实际上传的地理图片的本地路径(如果不填写则上传picLocalPath地理图片)。 该字段为空。
    mimeType String 需要填写,地理图片的MIME类型。 地理图片的MIME类型。
    picUrl String 不需要填写。 地理图片的下载URL。
    pciMediaId String 不需要填写。 IM服务为地理图片生成的全局唯一ID(多媒体资源标识符)。
    picFileType AIMMsgImageFileType 需要填写,地理图片的文件类型。 地理图片的文件类型。
    picWidth int 可以填写(如果不填写,IM会解析地理图片的宽),地理图片的宽。 地理图片的宽。
    picHeight int 可以填写(如果不填写,IM会解析地理图片的高),地理图片的高。 地理图片的高。
    latitude double 需要填写,纬度。 纬度。
    longitude double 需要填写,经度。 经度。
    locationName String 可以填写(不填写默认为空),地理位置名称。 地理位置名称。

    相关示例代码。请参见地理信息

  • AIMMsgCustomContent
    字段名 类型 含义(发送者) 含义(接受者)
    type int 可以填写,开发者自定义消息类型。 开发者自定义消息类型。
    title string 可以填写,开发者自定义title。 开发者自定义title。
    summary string 可以填写,开发者自定义summary。 开发者自定义summary。
    degrade string 可以填写,开发者自定义degrade。 开发者自定义degrade。
    binaryData byte[] 可以填写,开发者填入的二进制数据。 开发者填入的二进制数据。

    相关示例代码。请参见自定义消息

  • AIMPubMsgStructContent
    字段名 类型 含义(发送者) 含义(接受者)
    elements ArrayList<> 需要填写,结构化元素序列。 结构化元素。

    相关示例代码。请参见结构化消息

  • AIMPubMsgStructElement
    字段名 类型 含义(发送者) 含义(接受者)
    elementType AIMMsgStructElementType 需要填写,元素类型。 元素类型。
    textContent AIMPubMsgTextContent 根据elementType决定是否填写文本型元素Content。 文本型元素Content。
    uidElement AIMPubMsgStructElementUid 根据elementType决定是否填写用户信息型元素Content。 用户信息型元素Content。
    atElement AIMPubMsgStructElementAt 根据elementType决定是否填写@型元素Content。 @型元素Content。

    相关示例代码。请参见结构化消息

  • AIMPubStructElementUid
    字段名 类型 含义(发送者) 含义(接受者)
    uid String 需要填写,相关用户的UserId。 相关用户的UserId。
    defaultNick String 需要填写,相关用户的默认昵称。 相关用户的默认昵称。
    prefix String 可以填写,prefix信息。 prefix信息。

    相关示例代码。请参见结构化消息

  • AIMPubMsgStructElementAt
    字段名 类型 含义(发送者) 含义(接受者)
    isAtAll boolean 需要填写(默认false),是否@所有人。 是否@所有人标志位。
    uid String 需要填写,被@用户的UserId。 被@用户的UserId。
    defaultNick String 需要填写,被@用户的默认昵称。 被@用户的默认昵称。

    相关示例代码。请参见结构化消息

  • AIMMsgFileContent
    字段名 类型 含义(发送者) 含义(接受者)
    localPath String 需要填写,表示上传文件的本地路径。 该字段为空。
    fileName String 可以填写。 文件名。
    mediaId String 不需要填写。 IM服务为该文件生成的全局唯一的ID。
    mimeType String 需要填写,文件的MIME类型。 文件MIME类型。
    url String 不需要填写。 文件的下载URL。
    fileSize long 可以填写(默认为0),文件的大小。 文件的大小。

    相关示例代码。请参见文件消息

  • AIMPubMsgSendReplyMessage
    字段名 类型 含义(发送者) 含义(接受者)
    appCid String 需要填写,会话ID。 接收者不会接收到该结构体。
    referenceMid String 需要填写,引用消息的Mid。
    replyContent AIMPubMsgContent 需要填写,回复消息内容,注意类型限制。
    receivers ArrayList<String> 需要填写,接收者userId,不填写则发送给会话所有人。

    相关示例代码。请参见回复消息

  • AIMPubMsgForwardMessage
    字段名 类型 含义(发送者) 含义(接受者)
    appCid String 需要填写,转发消息的来源。 接受者不会接收到该结构体。
    referenceMid String 需要填写,引用消息的Mid。
    replyContent AIMPubMsgContent 需要填写,回复消息内容,注意类型限制。
    receivers ArrayList<String> 需要填写,接收者userId,不填写则发送给会话所有人。
    extension HashMap< String, String > 可以填写,消息扩展字段。
    说明 在普通转发中,如果填写了extension字段,那么所有转发消息里面extension都会被替换,否则保持不变。

    相关示例代码。请参见转发消息

  • AIMPubNewMessage
    字段名 类型 含义
    msg AIMPubMessage 新增消息体。
    type AIMMsgSourceType 新增消息来源(发送、在线接收、离线接收、拉取消息)。
    说明 主动发送消息时,AIMSDK也会回调onAddedMessages事件,消息来源为SOURCE_TYPE_SEND。

    相关示例代码。请参见消息推送

  • AIMPubMsgRecallFeature
    字段名 类型 含义
    operatorType AIMMsgRecallType 撤回类型(发送者撤回、群聊管理员撤回、系统撤回等)。
    code String 描述字段。
    operatorUid String 撤回者UserId。
    extension HashMap<String, String> 扩展字段。

    相关示例代码。请参见消息撤回