消息常见问题
1.消息类型有哪些?是否支持自定义消息类型?
IMSDK 包含以下消息类型,支持自定义消息
类型 | Class | 必填参数 | 描述 |
---|---|---|---|
文本消息元素 | TextElem | text:String | 存储字符串类型,并形成文本消息 |
表情消息元素 | FaceElem | index:int data:byte | IMSDK 并不提供表情包,如果开发者有表情包,可使用 index 存储表情在表情包中的索引,由用户自定义。或者直接使用 data 存储表情二进制信息,由用户自定义,IMSDK 内部只做透传 |
位置消息元素 | LocationElem | desc:String longitude:double latitude:double | IMSDK 提供了发送经纬度类型的消息,接收消息后可读取其中的经纬度传给如腾讯地图 SDK,用来在界面展示地图信息 |
图片消息元素 | ImageElem | path:String level:int format:int | level 图片级别(0 = 原图,1 = 高压缩率图,2 = 高清图) format 图片格式(1 = jpg,2 = gif,3 = png,4 = bmp,255 = 未知) |
声音消息元素 | SoundElem | path:String size:long duration:long | size 语音数据文件大小, duration 持续时间,以秒为单位, 一条消息只能添加一个声音元素,添加多个声音元素时,发送消息会失败 |
文件消息元素 | FileElem | path:String size:long | size 数据文件大小, 一条消息只能添加一个文件元素,添加多个文件时,发送消息会失败 |
视频消息元素 | VideoElem | videoPath:String snapshotPath:String | 设置路径后可发送消息,如果使用跨平台 IMSDK,VideoElem 需要更多的必填参数,详情见:点击跳转 一条消息只能添加一个视频元素,添加多个视频时,发送消息会失败 |
自定义消息元素 | CustomElem | desc:String data:byte | desc 描述字段,如果需要将消息进行离线推送,则必须填写这个字段, data 开发者数据格式,内容全部由开发者定义,TIMSDK 只负责透传。 |
2.消息如何构建?
构建消息元素后,实例化一个 TIMMessage 对象,然后调用 addElement() 方法构建到 TIMMessage 消息对象中,不推荐在同一个消息对象中使用多个元素
注意:文件、图片、语音、视频消息元素每个 TIMMessage 对象仅能添加一个,添加多个文件类型元素时,发送消息会失败
3.消息历史记录保存多久?如何获取?
本地消息保存时间无限制
漫游消息默认保存 7天,可通过即时通信IM控制台进行更改保存时长,最长 12个月
漫游消息可以通过 getMessage() 接口拉取至本地,最多可以拉取到如上述配置的时间内的消息
4.消息如何解析?
1) 实例化一个基类保存从 TIMMessage.getElement() 获取的消息元素
2) 判断元素的类型
3) 根据元素类型进行不同的处理,例如文本消息通过 getText() 读取字符串,文件消息通过 getToFile() 下载文件至本地,官网示例代码:点击跳转
5.如何发送消息?
TIMMessage 构建完成后,可通过 TIMManager.getConversation() 获取或创建会话,调用 TIMConversation.sendMessage() 即可完成消息发送
6.普通消息和在线消息的区别是?
在线消息即无痕消息,特点是不被服务端保存,只有在线的一次收发
使用在线消息可以实现如 "阅后即焚"、"正在输入" 等功能
正在输入:监测到键盘输入,可以向对方发送 N条在线消息,对方收到在线消息后再做 UI 展示,因为不会存储的特性,从而无须担心影响本来的消息列表
7.多媒体、文件类型的消息如何处理?
接收到文件消息后,有两种处理方式
通过 getToFile() 下载到指定目录文件夹
通过 getUrl() 获取到 URL 链接,访问链接下载文件
8.消息撤回有哪些限制?
默认可以撤回 2分钟之内的消息,可在 "控制台->功能配置->消息" 处进行更改,消息可撤回时间配置项,最大不能超过消息漫游的时长
音视频聊天室(AVChatRoom) 和 在线成员广播大群(BChatRoom) 不支持消息撤回
9.消息对象有哪些可用字段?
字段 | 数据类型 | 读写权限 |
---|---|---|
elemCount | long | 只读 |
ElemArray | TIMElem | 可读可写 |
convId | String | 可读可写 |
convType | TIMConversationType | 可读可写 |
sender | String | 可读可写 |
senderProfile | TIMUserProfile | 只读 |
clientTimestamp | long | 可读可写 |
isSelf | bool | 只读 |
isRead | bool | 只读 |
peerRead | bool | 只读 |
status | uint64 | 只读 |
uniqueId | uint64 | 只读 |
seq | uint64 | 只读 |
rand | uint64 | 只读 |
CustomInt | int | 可读可写(本地) |
CustomStr | String | 可读可写(本地) |
10.会话列表和漫游消息的拉取机制是怎样的?
IMSDK 登录成功后会同步近期的会话列表,通过漫游 本地的方式返回会话列表。
漫游方式为新产生并且未超过漫游消息时长限制,返回最新的一条消息生成会话。
返回的本地会话会因为以下操作受到影响:
1) 执行过删除会话接口
2) 使用新的手机首次登录
3) Windows 端更换 config 目录
11.文件消息的大小限制是多少?
大小限制为 28M, WEB 端为 20M;
12.可以删除 Service 上的消息吗?
暂不支持删除 Service 消息,可通过这两种方法删除本地消息:
1) 调用 remove() 接口为消息打上删除标记进行消息过滤;
2) delFromStorage() 将本地数据库彻底删除 (仅 iOS 端支持此接口);
13. 3.x 的 TIMUGCElem 与 4.x TIMVideoElem 是否兼容?
不兼容:
TIMUGCElem 是利用 LiteAVSDK 采集并存储视频,并且需要开通短视频服务;
TIMVideoElem 则是 4.x 新消息元素,不再需要集成 TIMUGCElem 的相关库文件,使用方式是提供给 TIMVideoElem 本地视频数据路径即可,并不会限制采集视频数据的方法;
14.我想删除本地会话或消息,看到有三个接口:deleteConversation(),deleteLocalMessage(),deleteConversationAndMessages(),我应该调用哪个接口?
deleteConversation() 的接口特性是保留消息删除会话,接收到新消息后可以通过 getConversationList() 重新获取到,根据之前的消息记录继续聊天;
deleteLocalMessage() 可以在保留会话同时删除本地的会话消息,可以通过 getMessage() 拉取回消息,适用于清除一个星期/月/年前的历史消息的场景;
deleteConversationAndMessages() 删除本地消息同时删除服务器上保存的会话,执行此方法后再次登录将不会出现在最近联系人列表里,适用于断绝好友关系场景下调用;
15.IMSDK 支持 PC 端与移动手机 APP 端的消息同步吗?
支持的,两端通过 getMessage() 拉取历史漫游消息来完成消息同步,也可以在云通信控制台配置多端同时在线一同接收消息;
16.getLastMessage() 接口描述中 “没有网络无法获取” 是什么意思?
IMSDK 成功登录后会同步最近的会话列表,为了便于 UI 的展示会通过网络 getLastMessage() 获取会话中最新的漫游消息,在没有网络的情况下,则会通过本地缓存获取最新消息;
17.我使用表情输入法发送了一条表情消息,为什么另一端收到此表情消息并解析出文本或超出我预期的情况?
1) iOS 的 emoji 表情输入法使用的是 Unicode 编码,如果另一端操作系统不支持 Unicode 编码将无法解析 emoji 表情,比如 Android 8.0 开始支持 Unicode 编码,Android 8.0 以上将会正常的解析使用 Unicode 的表情;
2) 例如码点 "U 1F600" 是 “一张微笑的脸” 表情,它在各个操作系统或 App 下渲染的表情会有细微差异,如果没有则为空或文本,此链接可以查看各版本的 emoji 差别;
18.我发送消息前设置了消息自定义字段 setCustomStr(),为什么收到消息后 getCustomStr() 为空?
消息自定义字段 CustomStr 仅存储于本地,发送消息并不会携带 CustomStr ,更换终端后无效;
CustomStrInt 与上同理;
适用场景:语音消息是否已播放,红包是否已拆开... 等其他场景建议使用消息自定义字段;
19.非好友关系可以收发消息吗?
默认是可以的,在 “云通信控制台 --> 应用配置 --> 功能配置 --> 单聊消息检验关系链” 编辑此属性,开启单聊消息检验关系链,非好友关系就不能收发消息,默认为关闭状态;
20.过期的资源文件还可以使用吗?
只要不删除这条消息可以继续使用,但无法从漫游消息拉取过期的文件消息;
若对过期的文件消息调用 getToFile() 方法,则返回 6009;
若请求过期的文件 URL,则返回 HTTP 4xx 错误;
21.disableAutoReport 开启或关闭的区别在哪里?
disableAutoReport = NO 时为开启自动上报:当成功注册新消息监听回调后执行 onNewMessages() 后 IMSDK 会自动将消息进行上报,清除 Service 的消息下发队列,切换终端或下次打开 App 注册新消息监听回调后将不会再通过 onNewMessages() 抛出消息
disableAutoReport = YES 时为关闭自动上报:与上面介绍的情况相反,每次打开 App 时,Service 会一直通过 onNewMessages() 下发消息,直到显式调用 setReadMessage() 将消息进行已读上报才会停止下发
注意事项:disableAutoReport 需要在登录前设置,登录后设置无效
Service 消息队列介绍:点击跳转
22.是否支持将单条消息置为已读状态?
暂不支持,setReadMessage() 是根据参数传入该条消息的时间戳之前的所有消息置为已读状态,填 NULL 将该会话的所有消息置为已读状态
23.我能获取进群前的历史消息记录吗?
可以的,请使用聊天室(ChatRoom) 群组类型创建群组,最多拉取的消息根据配置的漫游消息时长决定
24.saveMessage() 是否会保存到云端?
不会,仅存储于本地
适用场景:聊天界面下插入单方的提醒消息,或特殊提醒消息气泡
25.处于黑名单状态下能否向对方发送消息?
默认允许向对方发送消息,只不过对方无法收到此消息
如果需要感知对方添加了黑名单,可以在 "控制台->功能配置->消息保留设置" 处配置,届时再向对方发送消息将返回 20007 错误码
群组常见问题
1.有哪些类型的群组?适用哪些场景?
群组类型 | 特性 | 场景 |
---|---|---|
公开群(Public) | 默认无法邀请其他用户加群,如需此功能可提交工单配置 | 适用于公开群组,具有较为严格的管理机制、准入机制,类似于 QQ 群 |
私有群(Private) | 无法直接申请加群,需要邀请其他用户方可加群 | 适用于较为私密的聊天场景,群组资料不公开,只能通过邀请的方式加入,类似于微信群 |
聊天室(ChatRoom) | 可以获取加群前的消息记录 | 成员上限 6000 人,适合较为大型的聊天广场场景下使用 |
音视频聊天室(AVChatRoom) | 无人数上限,不支持漫游消息,支持游客 | 适用于互动直播场景,如礼物、点赞、弹幕都可以使用自定义消息来实现与主播互动 |
在线广播大群(BChatRoom) | 无人数上限,不支持漫游消息 | 适用于发送大喇叭消息的场景 |
2.如何创建群组?
1) 实例化一个群组参数 CreateGroupParam
2) 群组类型、群名称、群成员(至少一人) 为必填项
3) 调用 createGroup() 创建群组
群组ID 支持自定义,需要在创建群组前设置,格式要求:点击跳转
3.如何进行群组禁言?
可通过如下 API 进行禁言:
代码语言:javascript复制//sdk api
//群主可以调用此接口将管理员禁言,但不能禁言群主
TIMGroupManager.modifyMemberInfoParam.setSilence()
代码语言:javascript复制//sdk api
//群主或管理员可以调用此接口将所有普通成员禁言,不包括群主和管理员
TIMGroupManager.modifyMemberInfoParam.setSilenceAll()
代码语言:javascript复制//rest api
//https://cloud.tencent.com/document/product/269/1627
//App 管理员可以调用此接口将指定的 identifier 禁言,无论角色是否为群主或管理员,都会被禁言
v4/group_open_http_svc/forbid_send_msg
代码语言:javascript复制//rest api
//https://cloud.tencent.com/document/product/269/4230
//App 管理员可以调用此接口将指定的 identifier 进行全局禁言,在禁言时间未到期时间内,所有的消息均会发送失败,包括 C2C 单聊消息
v4/openconfigsvr/setnospeaking
4.如何解散群组?
群主调用接口 deleteGroup() 即可进行解散,需要注意的是私有群无法直接解散群组,需要服务端调用 rest api 进行解散
5.群维度资料有哪些可用字段?
字段 | 介绍 | 更改权限 |
---|---|---|
groupType | 群组类型 | 需要在创建群组时设定,后续不可修改 |
groupId | 群组ID | 需要在创建群组时设定,后续不可修改 |
groupName | 群名称 | 创建群组后修改 |
notification | 群公告 | 创建群组时可设定,后续可修改 |
introduction | 群简介 | 创建群组时可设定,后续可修改 |
faceURL | 群头像 | 创建群组时可设定,后续可修改 |
addOption | 加群选项 | 创建群组时可设定,后续可修改 |
maxMemberNum | 最大成员数 | 需要在创建群组时设定,后续不可修改 |
customInfo | 自定义信息 | 创建群组时可设定,后续可修改 |
members | 群成员 | 创建群组时可设定,后续可修改 |
visable | 群组成员是否对外可见 | 创建群组后修改 |
silenceAll | 禁言功能 | 创建群组后可使用此功能 |
控制台群组自定义字段 | 群组自定义字段 | 使用方法可以参考:点击跳转 |
6.群成员资料维度有哪些可用字段?
字段 | 介绍 | 描述 |
---|---|---|
nameCard | 群名片 | 群成员在群内的昵称 |
receiveMessageOpt | 群消息接收选项 | ChatRoom、AVChatRoom、BChatRoom 默认为接收但不离线推送群消息 |
role | 角色 | AVChatRoom、BChatRoom 不支持修改用户群内身份 |
silenceTime | 禁言时间 | 只有群主或者管理员可以进行对群成员进行禁言 详情可查看 "3.如何进行群组禁言?" 篇幅 |
控制台群成员自定义字段 | 群成员自定义字段 | 使用方法可以参考:点击跳转 |
7.如何修改和获取群消息接收选项?
修改:
1) 实例化一个修改参数 ModifyMemberInfoParam
2) 通过 setReceiveMessageOpt() 方法设置消息接收选项
ReceiveAndNotify | 接收群消息,若离线情况下会推送离线消息 |
---|---|
NotReceive | 不接收群消息, 服务器不会进行转发 |
ReceiveNotNotify | 接收群消息,但若离线情况下则不会推送离线消息 |
3) 最后通过 modifyMemberInfo() 方法进行更改
获取:
1) 使用 TIMGroupManager.getSelfInfo() 获取群组的个人信息
2) 再调用 getRecvOpt() 即可获取群消息接收选项
8.退群后我希望把会话列表的记录也删掉,该怎么做?
退群后 IMSDK 不会删除会话,可以在业务层面决定是否保留群消息记录。
1) 退群后删除会话保留消息可以使用 deleteConversation();
2) 退群后删除会话和消息可以使用 deleteConversationAndMessages();
3) 退群后保留会话和消息无需做其他操作;
9.为什么我创建了一个群组, getGroupList() 却得不到?
1) 确认用户是否加入了群组, CreateGroupParam / applyJoinGroup() 的成功回调是否执行; 如果申请加入的群类型为私有群(Private), 则直接返回 10007 错误码;
2) 确认群组类型是否为私有群(Private), 可通过 getGroupType() 获取群类型;
3) 私有群(Private) 需要通过发送一条消息来激活群组;
10.为什么我创建了一个群组, 却无法邀请他人?
1) 确认群组类型是否为私有群(Private), 可通过 getGroupType() 获取群类型;
2) 公开群(Public) 和 聊天室(ChatRoom) 默认只有 APP 管理员能够邀请其他用户加群;
3) 音视频聊天室(AVChatRoom) 和 在线成员广播大群(BChatRoom) 则不允许任何人邀请他人进群;
4) 如需公开群(Public) 和 聊天室(ChatRoom) 邀请他人的功能请提交工单申请;
11.为什么我无法发送群消息?
1) 不是群成员, 使用 getGroupList() 可获取已加入的群组列表;
2) 群组类型为在线成员广播大群(BChatRoom), 可通过 getGroupType() 获取群类型;
3) 被禁言后会返回错误码: 20012
12.登录成功后拉取最近的会话列表,为什么缺少了部分群组?
音视频聊天室(AVChatRoom),广播大群(BChatRoom) 是不会出现在会话列表中的,需要再次加入会话,同时不支持离线消息;
13.为什么有的群组消息收不到离线推送?
1) 确认 TIMGroupReceiveMessageOpt 是否为关闭免打扰的状态:ReceiveAndNotify;
2) 群组类型为聊天室(ChatRoom),音视频聊天室(AVChatRoom),广播大群(BChatRoom) 是不支持离线推送的;
14.为什么我作为群主却无法解散群组?
私有群 (Private) 和在线成员广播大群 (BChatRoom) 是只有 APP 管理员方可解散群组;
通过云通信控制台或使用 APP管理员帐号使用 rest api 可解散群组;
15.TIMGroupMemberInfo.nameCard 和 TIMUserProfile.nickName 是什么关系?
nameCard 是可以在群内显示的名字字段,每个群可以设置并使用不同的群昵称;
nickName 是个人资料的昵称字段,同一时间只能使用一个昵称;
在群组聊天业务场景下,可以先获取 nameCard 字段,如果为空可以选择再去获取 nickName 或 identifier 展示在页面上;
16.TIMGroupMemberInfo 没有头像字段?
一般每个用户的头像只有一个,个人资料的 faceUrl 字段可以用来当作群成员头像;
用户资料常见问题
1.如何获取资料?
通过如下 4个 API 即可返回 TIMUserProfile 解析资料字段
代码语言:javascript复制TIMFriendshipManager.getSelfProfile()
TIMFriendshipManager.getUsersProfile()
TIMFriendshipManager.querySelfProfile()
TIMFriendshipManager.queryUserProfile()
TIMUserProfile 有如下字段
字段 | 数据类型 | 描述 |
---|---|---|
TIM_PROFILE_TYPE_KEY_NICK | String | 昵称 |
TIM_PROFILE_TYPE_KEY_FACEURL | String | 头像 |
TIM_PROFILE_TYPE_KEY_ALLOWTYPE | String | 好友申请接收方式 |
TIM_PROFILE_TYPE_KEY_GENDER | int | 性别 |
TIM_PROFILE_TYPE_KEY_BIRTHDAY | int | 生日 |
TIM_PROFILE_TYPE_KEY_LOCATION | String | 位置 |
TIM_PROFILE_TYPE_KEY_LANGUAGE | int | 语言 |
TIM_PROFILE_TYPE_KEY_LEVEL | int | 等级 |
TIM_PROFILE_TYPE_KEY_ROLE | int | 角色 |
TIM_PROFILE_TYPE_KEY_SELFSIGNATURE | String | 签名 |
控制台自定义字段 | 自定义字段 | 使用方法详情参考:点击跳转 |
2.非好友关系能否获取资料?
可以获取到,调用 TIMFriendshipManager.getUsersProfile() 传入想获取的陌生人的 identifier 即可返回资料,支持批量
3.获取资料时需要开启 forceUpdate 吗?
建议根据不同的 UI 界面来开启或关闭 forceUpdate,参考微信,会话列表界面时,使用本地缓存的头像,进入用户资料页时再强制拉取资料数据进行更新
当 forceUpdate = true 时,会强制从后台拉取数据,并把返回的数据缓存下来。
当 forceUpdate = false 时,则先在本地查找,如果本地没有数据则再向后台请求数据。
4.如何获取本地存储的用户资料?
可以通过 TIMFriendshipManager 类下的 query 方法来获取本地存储资料数据,使用 query 方法前需要事先通过 getSelfProfile() 或 getUsersProfile() 从网络拉取数据到本地,否则返回空
代码语言:javascript复制TIMUserProfile.querySelfProfile()
TIMUserProfile.queryUserProfile(String identifier)
5.用户资料的字段值可以设置多少字节?
用户资料和关系链经过重构后 String 类型的字符串可以存储 500 字节(Byte) 的数据;
6.用户资料限制的字节长度,有中文的情况下如何计算?
首先确认工程使用的编码再做计算,如:
utf-8 编码中,1个英文字母字符占用 1个字节,1个汉字占用 3-4个字节 (少数汉字占用 3字节,多数汉字 4字节)。
utf-16 和 Unicode 编码中,1个英文字母字符或中文都是占用 2个字节 (Unicode 扩展区的部分汉字 4个字节)。
utf-32 编码中,世界上的任何字符都需要占用 4个字节。
gbk 编码中,1个英文字母字符占用 1个字节,1个汉字占用 2个字节。
推荐使用 “utf-8”,较为通用。
关系链常见问题
1.好友维度的字段包含哪些?
字段 | 数据类型 | 描述 |
---|---|---|
identifier | String | 用户唯一ID |
remark | String | 好友备注 |
addWording | String | 申请加好友的理由 |
addSource | String | 申请加好友的来源 |
addTime | long | 申请加好友的时间 |
groupNames | List<String> | 好友分组 |
TIMUserProfile | TIMUserProfile | 好友资料 |
控制台好友自定义字段 | 好友自定义字段 | 使用方法可以参考:点击跳转 |
2.有哪些方法可以管理好友?
添加好友:
通过 TIMFriendshipManager.addFriend() 方法添加好友
代码语言:javascript复制public void addFriend(@NonNull TIMFriendRequest timFriendRequest, @NonNull TIMValueCallBack<TIMFriendResult> cb)
构建 TIMFriendRequest 参数需要填写以下字段:
代码语言:javascript复制TIMFriendRequest.setIdentifier()
TIMFriendRequest.setRemark()
TIMFriendRequest.setAddWording()
TIMFriendRequest.setAddSource()
TIMFriendRequest.setFriendGroup()
参数类型均为字符串 String 类型,其中 identifier 为必填项,其他为选填
删除好友
通过 TIMFriendshipManager.deleteFriends() 方法删除好友,支持批量
代码语言:javascript复制public void deleteFriends(@NonNull List<String> identifiers, @NonNull int delFriendType, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
参数 TIMDelFriendType 有两个枚举值:
代码语言:javascript复制TIM_FRIEND_DEL_SINGLE 为单向删除
TIM_FRIEND_DEL_BOTH 为双向删除
修改好友
通过 TIMFriendshipManager.modifyFriend() 方法修改好友字段信息
代码语言:javascript复制public void modifyFriend(@NonNull String identifier, @NonNull HashMap<String, Object> profileMap, @NonNull TIMCallBack cb)
参数 HashMap<String, Object> 要求填写 Key-Value,Key 默认有一些字段:
代码语言:javascript复制TIM_FRIEND_PROFILE_TYPE_KEY_REMARK 为好友备注字段
TIM_FRIEND_PROFILE_TYPE_KEY_GROUP 为好友分组字段
TIM_FRIEND_PROFILE_TYPE_KEY_CUSTOM_PREFIX "xxx" 为好友自定义字段,详情参考:https://cloud.tencent.com/developer/article/1494042
获取所有好友
通过 TIMFriendshipManager.getFriendList() 方法获取好友列表
代码语言:javascript复制public void getFriendList(@NonNull TIMValueCallBack<List<TIMFriend>> cb)
成功回调将返回所有好友 TIMFriend
处理好友请求
如果在 TIMUserProfile 中设置了好友验证方式为 "AllowType_Type_NeedConfirm",则需要通过 TIMFriendshipManager.doResponse() 方法同意或拒绝好友请求
代码语言:javascript复制public void doResponse(TIMFriendResponse response, @NonNull TIMValueCallBack<TIMFriendResult> cb)
与之前添加好友构建 TIMFriendRequest 相似,其中:
代码语言:javascript复制TIMFriendResponse.TIM_FRIEND_RESPONSE_AGREE 同意加好友
TIMFriendResponse.TIM_FRIEND_RESPONSE_AGREE_AND_ADD 同意并建立双向好友
TIMFriendResponse.TIM_FRIEND_RESPONSE_REJECT 拒绝加好友
校验好友关系
通过 TIMFriendshipManager.checkFriends() 方法可校验好友关系
代码语言:javascript复制public void checkFriends(@NonNull TIMFriendCheckInfo checkInfo, @NonNull TIMValueCallBack<List<TIMCheckFriendResult>> cb)
参数 TIMFriendCheckInfo 设置项:
TIMFriendCheckInfo.setUers() 想要校验的 identifier,支持批量
代码语言:javascript复制TIMFriendCheckInfo.setCheckType()
type = 1:TIM_FRIEND_CHECK_TYPE_UNIDIRECTION 是否为单向好友
type = 2:TIM_FRIEND_CHECK_TYPE_BIDIRECTION 是否为双向好友
回调返回的 TIMFriendCheckInfo 中可以获取检查的好友关系类型
代码语言:javascript复制TIM_FRIEND_RELATION_TYPE_NONE 不是好友
TIM_FRIEND_RELATION_TYPE_MY_UNI 对方在我的好友列表中
TIM_FRIEND_RELATION_TYPE_OTHER_UNI 我在对方的好友列表中
TIM_FRIEND_RELATION_TYPE_BOTH_WAY 互为好友
黑名单操作
可以通过 TIMFriendshipManager 下的三个方法管理黑名单列表
代码语言:javascript复制//可以把任意用户拉黑,如果此前是好友关系,拉黑后自动解除好友,拉黑后对方发消息无法收到。
public void addBlackList(List<String> users, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
public void deleteBlackList(List<String> users, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
public void getBlackList(@NonNull TIMValueCallBack<List<TIMFriend>> cb)
3.如何创建好友分组?
通过 TIMFriendshipManager 类下的如下方法可以管理好友分组,注意好友分组本质是一组字符串标记的字段,一个好友可以有多个分组信息,既此好友存在多个分组中,以多对多的方式进行管理,如果业务有需求,可以把 groupNames 的容器元素个数限制为 1
代码语言:javascript复制/**
* 新建好友分组
*
* @param groupNames 分组名称列表,必须是当前不存在的分组
* @param identifiers 要添加到分组中的好友
* @param cb 回调
*/
public void createFriendGroup(List<String> groupNames, List<String> identifiers, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
/**
* 删除好友分组
*
* @param groupNames 要删除的好友分组名称列表
* @param cb 回调
*/
public void deleteFriendGroup(List<String> groupNames, @NonNull TIMCallBack cb)
/**
* 添加好友到某分组
*
* @param groupName 好友分组名称
* @param identifiers 要添加到分组中的好友列表
* @param cb 回调
*/
public void addFriendsToFriendGroup(String groupName, List<String> identifiers, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
/**
* 从某分组删除好友
*
* @param groupName 好友分组名称
* @param identifiers 要移除分组的好友列表
* @param cb 回调
*/
public void deleteFriendsFromFriendGroup(String groupName, List<String> identifiers, @NonNull TIMValueCallBack<List<TIMFriendResult>> cb)
/**
* 重命名好友分组
*
* @param oldName 原来的分组名称
* @param newName 新的分组名称
* @param cb 回调
*/
public void renameFriendGroup(String oldName, String newName, @NonNull TIMCallBack cb)
/**
* 获取指定的好友分组,传入 null 获得所有分组信息
* @param groupNames 要获取信息的好友分组名称列表
* @param cb 回调
*/
public void getFriendGroups(List<String> groupNames, @NonNull TIMValueCallBack<List<TIMFriendGroup>> cb)
4.为什么我添加好友报错?
1) 确认对方的 identifier 是否合法, 若不合法会返回错误码: 20003,可使用云通信控制台的签名 (UserSig) 校验工具检验对应的 identifier;
2) 可通过 getFutureFriends() 拉取未决请求确认是否曾经向对方发送了加好友请求;
在线状态相关常见问题
1.多端互踢的机制是什么样的?
单端登录:仅允许一个终端登录
双端登录:仅允许一个终端登录,Web 端排除在外,可以 iOS Web,Android Web 或 Windows Web
三端登录:仅允许一个移动端登录,如:iOS Windows Web 或 Android Windows Web
多端同时在线:允许 Windows、Web、Android 或 iOS 多端或全端同时在线登录,最多可以 13个终端同时在线
2.App 退到后台后无法收到消息和通知?
由于 Android 和 iOS 系统的限制,大部分 APP 并不能支持后台运行,所以在 APP 退到后台后几秒到几分 钟后 APP 就被挂起,无法收取任何消息。在这种情况下所有的消息和通知都是通过推送 (厂商推送、APNS) 来通知用户。只有在用户收到推送并打开 APP 后,SDK 才会自动重连上服务器并拉取离线的消息和通知。
集成离线推送文档链接:点击跳转
社区指引及常见问题:点击跳转
3.登录后我会收到哪些状态回调?
通过注册 TIMUserStatusListener 可以监听到两种状态回调
代码语言:javascript复制onForceOffline() 被踢下线的通知回调
onUserSigExpired() 用户登录使用的 userSig 过期,需要重新获取 userSig 后登录
4.报错:errCode: 6026, errDesc: No_Previous_Login 是什么?
设置自动登录时没有登录过该用户导致的;
5.一个 SDKAPPID 可以用于两个 App 吗?
可以用于两个或多个 App,但在同一时间下,只有一个 identifier 可以登录并使用;
6.Android 和 iOS 登录了同一个 identifier 不会互踢,而两台 Android 或两台 iOS 可以互踢?
这是因为在 "控制台 -> 功能配置" 设置了双端登录或多端登录,配置此功能后,将允许不同类型终端同时在线;
如果需要 Android 和 iOS 互踢,请将设置改成 “单端登录” ;
用户帐号常见问题
1.如何创建一个 identifier?
创建一个用户帐号有三种方式:
1) 通过 "控制台->开发者辅助工具" 填写 identifier,密钥来生成一个用户帐号,由于方法不可批量,建议在测试环境下使用此方法,如果需要测试 rest api,也可以用此方法生成 App 管理员的 usersig
2) 在客户端 demo 的 GenerateTestUserSig 模块中设置 sdkappid 和 SECRETKEY 参数,登录时会自动计算 usersig,例如在此 sdkappid 下没有 "test01" 帐号,将会自动创建此用户id
注意:此方法仅适用于 “HMAC-SHA256” 加密方式的密钥,建议在测试环境下使用,正式环境因本地计算的方式会带来安全风险
3) 在服务端配置计算密钥程序,用户提交注册帐号时,请求服务端计算密钥,然后返回 usersig 完成登录流程,详情见文档:点击跳转
2.如何注销一个 identifier?
使用 rest api 可以注销 identifier,单次请求最多支持100个帐号,详情见接口介绍:点击跳转
3.我能否查询所有的 identifier?
暂不支持统计所有 identifier,可以在客户端用户注册帐号成功后将用户信息一并写入 SQL 中进行管理或查询
4.如何进行游客登录?
游客是指在不登录的情况下可以接收音视频聊天室(AVChatRoom)群组类型的消息,目前仅支持 webim,初始化成功后即可加入群组接收消息
初始化:点击跳转
加入群组:点击跳转
SDK 使用相关问题
1.Windows SDK 如何使用自定义的用户数据目录?
SDK 提供了自定义数据目录接口,只需在初始化 SDK 时传入相对路径或绝对路径,SDK 会自动创建对应的文件夹目录作为用户数据目录。
相对路径,会在 .exe 同级目录下创建 "config" 和 "logs" 文件夹。
代码语言:javascript复制Json::Value json_init;
json_init[kTIMSdkConfigConfigFilePath] = ".//config";
json_init[kTIMSdkConfigLogFilePath] = ".//logs";
TIMInit(SDKAPPID, json_init.toStyledString().c_str());
绝对路径,会在 "E://IMApp//config" 下创建 "config" 文件夹。
代码语言:javascript复制Json::Value json_init;
json_init[kTIMSdkConfigConfigFilePath] = "E://IMApp//config";
json_init[kTIMSdkConfigLogFilePath] = "E://IMApp//logs";
TIMInit(SDKAPPID, json_init.toStyledString().c_str());
2.在弱网或无网络情况下,发送消息的超时时间可以控制吗?
超时时间为 15秒,不能设置。在此期间若网络恢复正常或重连成功,IMSDK 会自动继续之前的发送任务,网络超时则返回错误码:9508
3.报错:errCode: 9506, errDesc: out of frequency limit 是什么?
触发了 IMSDK 的接口频率限制,每秒钟最多可以发起 5次请求,第 6次将返回此错误信息
4.disableStorage() 的作用是?
禁用本地存储,在 TIMUserConfig 类下,开启此配置后,会话、消息、资料数据均不会存储于本地
注意:需要在登录前配置
适用场景:无痕登录、直播场景(大量消息并发时,可以开启此配置提升性能)