互动消息是用于加强直播间消息沟通、提升交互体验的服务。提供了丰富、易集成的SDK,可在用户开发的直播应用中轻松集成评论、弹幕、点赞等能力。本文介绍Android端集成互动消息应用的操作步骤。
前提条件
客户端集成前,请确保已完成服务端集成,并提供客户端访问的获取鉴权Token的接口。详细操作,请参见服务端集成。
集成SDK
添加Maven仓库。
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
}
添加SDK依赖。
// 互动库
implementation "com.aliyun.sdk.android:AliVCInteractionMessage:1.3.2"
配置AndroidManifest.xml
权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
使用SDK
SDK使用需遵循如下操作顺序:
初始化
登录
相关操作
登出
反初始化
其中相关操作包含群组操作和消息操作,详细说明如下:
相关操作
群组操作
消息操作
单发消息
群发消息
查询最近群发消息列表
查询全部群发消息(仅限群主/群管理员操作)
删除/撤回群消息
查询历史消息
注意事项
各ID需遵循以下规则:
appid :最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
userid:最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
groupid:最长64位,仅限于A~Z,a~z, 0~9及“-”, 不能包含其他字符
初始化
在App入口(如Application/Activity的onCreate中)进行初始化配置。
ImSdkConfig config = new ImSdkConfig();
config.deviceId = "deviceId"; //[选填]
config.appId = "appId"; //[必填],传空会返回初始化失败-2
config.appSign = "appSign"; //[必填],传空会返回初始化失败-2
// 初始化返回非0,表示初始化失败,其中1001:重复初始化、1002:创建底层引擎失败、-1:底层重复初始化、-2:初始化配置信息有误
int ret = AliVCIMEngine.instance().init(context, config);
监听长连接状态
AliVCIMEngine.instance().addSdkListener(new ImSdkListener() {
@Override
public void onConnecting() {
}
@Override
public void onConnectSuccess() {
}
@Override
public void onConnectFailed(com.aliyun.im.common.Error error) {
}
@Override
public void onDisconnect(int code) {
}
// 登录token失效(如token过期)会通过该接口获取新的token,务必实现该接口
@Override
public void onTokenExpired(ImTokenCallback callback) {
// 第一步,实现新token的生成,若需要网络请求等耗时操作,请务必抛到异步线程实现;
// 第二步,若token生成失败,则通过 callback.onError() 回调错误信息;
// 若token生成成功,则通过 callback.onSuccess() 回调token信息;
}
@Override
public void onReconnectSuccess(ArrayList<ImGroupInfo> groupStatus) {
}
});
登录
ImLoginReq req = new ImLoginReq();
req.user.userId = userId;
//透传业务额外信息
Map<String, Object> data = new HashMap<>();
data.put("level", "high");
req.user.userExtension = App.getGson().toJson(data).toString();
req.userAuth = new ImAuth(nonce, timestamp, role, app_token);
AliVCIMEngine.instance().login(req, new ImSdkCallback());
其中role参数,有两种角色:
登出
AliVCIMEngine.instance().logout();
反初始化
登出后进行反初始化。
AliVCIMEngine.instance().unInit();
消息服务
//消息服务
AliVCIMMessageInterface messageInterface = AliVCIMEngine.instance().getMessageManager();
非管理员操作
监听消息
//监听消息
messageInterface.addMessageListener(new ImMessageListener() {
@Override
public void onRecvC2cMessage(ImMessage msg) {
}
@Override
public void onRecvGroupMessage(ImMessage msg, String groupId) {
}
@Override
public void onDeleteGroupMessage(String msgId, String groupId) {
}
});
发送C2C消息
ImSendMessageToUserReq req = new ImSendMessageToUserReq();
req.type = 88888;
req.data = "This is a test message";
req.receiverId = userInput.getText().toString();
// 需确保对方在线,否则会返回错误码424,此时建议待对方上线后再重发
messageInterface.sendC2cMessage(req, new ImSdkValueCallback<ImSendMessageToUserRsp>() {
@Override
public void onSuccess(ImSendMessageToUserRsp data) {
Log.v(ImTag.TAG, "发送C2C消息成功:" + data.messageId);
}
@Override
public void onFailure(Error error) {
Log.v(ImTag.TAG, "发送C2C消息失败:error" + error.code);
}
});
在群组内发送全员消息
ImSendMessageToGroupReq req = new ImSendMessageToGroupReq();
req.level = ImMessageLevel.HIGH;
req.type = 88888;
req.data = "a test";
req.groupId = groupId;
// 需确保已经加入群成功(即在AliVCIMGroupInterface.joinGroup回调成功之后),再发送群组消息,否则会返回错误码425
messageInterface.sendGroupMessage(req, new ImSdkValueCallback<ImSendMessageToGroupRsp>() {
@Override
public void onSuccess(ImSendMessageToGroupRsp data) {
Log.v(ImTag.TAG, "发送高优先级群消息成功:" + data.messageId);
}
@Override
public void onFailure(Error error) {
Log.v(ImTag.TAG, "发送高优先级群消息成功" + error.code);
}
});
查询最近消息列表
ImListRecentMessageReq req;
req.groupId = groupId;
messageInterface.listRecentMessage(req, new ImSdkValueCallback<ImListRecentMessageRsp>() {
@Override
public void onSuccess(ImListRecentMessageRsp data) {
}
@Override
public void onFailure(com.aliyun.im.common.Error error) {
}
});
查询历史消息
//该接口主要用户直播结束后的历史消息回放,用户无需进入群组可查询,比较耗时,在直播过程中不建议使用,另外该接口后续会收费。
ImListHistoryMessageReq req = new ImListHistoryMessageReq();
req.groupId = "群ID";
req.nextPageToken = 231231; //不传时表示第一页,遍历时服务端会返回下一页Token,客户端获取下一页时应带上
req.type = 99999; // 自定义消息类型,需大于10000
req.sortType = ImSortType.ASC;
req.pageSize = 20;
req.beginTime = 0; // 按时间范围遍历,开始时间,单秒,为0时表示最早时间
req.endTime = 0; // 按时间范围遍历,结束时间,单秒,为0时表示最晚时间
messageInterface.listHistoryMessage(req, new ImSdkValueCallback<ImListHistoryMessageRsp>() {
@Override
public void onSuccess(ImListHistoryMessageRsp rsp) {
}
@Override
public void onFailure(Error error) {
}
});
删除消息
ImDeleteMessageReq req = new ImDeleteMessageReq();
req.groupId = "群ID";
req.messageId = "消息ID";
messageInterface.deleteMessage(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
管理员操作
查询消息列表
//该接口(仅限群主/群管理员操作)
ImListMessageReq req = new ImListMessageReq();
req.groupId = "群ID";
req.nextPageToken = 231231; //不传时表示第一页,遍历时服务端会返回下一页Token,客户端获取下一页时应带上
req.type = 99999; // 自定义消息类型,需大于10000
req.sortType = ImSortType.ASC;
req.pageSize = 20;
req.beginTime = 0; // 按时间范围遍历,开始时间,单秒,为0时表示最早时间
req.endTime = 0; // 按时间范围遍历,结束时间,单秒,为0时表示最晚时间
messageInterface.listMessage(req, new ImSdkValueCallback<ImListMessageRsp>() {
@Override
public void onSuccess(ImListMessageRsp rsp) {
}
@Override
public void onFailure(Error error) {
}
});
群组服务
//群组服务
AliVCIMGroupInterface groupInterface = AliVCIMEngine.instance().getGroupManager();
非管理员操作
监听群组状态
//监听群组
groupManager.addGroupListener(new ImGroupListener() {
@Override
public void onMemberChange(String groupId, int memberCount, ArrayList<ImUser> joinUsers, ArrayList<ImUser> leaveUsers) {
}
@Override
public void onExit(String groupId, int reason) {
}
@Override
public void onMuteChange(String groupId, ImGroupMuteStatus status) {
}
@Override
public void onInfoChange(String groupId, ImGroupInfoStatus info) {
}
});
加入群组
ImJoinGroupReq req = new ImJoinGroupReq();
req.groupId = groupId;
groupInterface.joinGroup(req, new ImSdkValueCallback<ImJoinGroupRsp>() {
@Override
public void onSuccess(ImJoinGroupRsp data) {
}
@Override
public void onFailure(Error error) {
}
});
离开群组
ImLeaveGroupReq req = new ImLeaveGroupReq();
req.groupId = groupId;
groupInterface.leaveGroup(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
查看最近群组成员
ImListRecentGroupUserReq req = new ImListRecentGroupUserReq();
req.groupId = groupId;
groupManager.listRecentGroupUser(req, new ImSdkValueCallback<ImListRecentGroupUserRsp>() {
@Override
public void onSuccess(ImListRecentGroupUserRsp data) {
}
@Override
public void onFailure(Error error) {
}
});
管理员操作
创建群组
ImCreateGroupReq req = new ImCreateGroupReq();
req.groupName = "羽毛球群";
Map<String, Object> data = new HashMap<>();
data.put("desc", "一三五晚8-10");
req.groupMeta = App.getGson().toJson(data).toString();
groupInterface.createGroup(req, new ImSdkValueCallback<ImCreateGroupRsp>() {
@Override
public void onSuccess(ImCreateGroupRsp data) {
Log.v(ImTag.TAG, "Create Group Success:" + data.groupId);
}
@Override
public void onFailure(com.aliyun.im.common.Error error) {
Log.v(ImTag.TAG, "Create Group Failure:" + error.getCode());
}
});
删除群组
ImCloseGroupReq req = new ImCloseGroupReq();
req.groupId = groupId;
groupInterface.closeGroup(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
修改群组
ImModifyGroupReq req = new ImModifyGroupReq();
req.groupId = groupId;
req.admins.add(adminUserId);//指定群管理员ID列表,最多设置3个管理员;若需要清空列表,则配置空列表或者不设置,同时必须设置req.forceUpdateAdmins=true;
req.groupMeta = "群信息拓展字段";//添加群拓展信息;若需要清空,则配置空字符串或者不设置,同时必须设置req.forceUpdateGroupMeta=true;
groupInterface.modifyGroup(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
查询群组成员
ImListGroupUserReq req = new ImListGroupUserReq();
req.groupId = groupId;
req.sortType = ImSortType.ASC;
req.pageSize = 30;
groupManager.listGroupUser(req, new ImSdkValueCallback<ImListGroupUserRsp>() {
@Override
public void onSuccess(ImListGroupUserRsp data) {
}
@Override
public void onFailure(Error error) {
}
});
全体禁言
ImMuteAllReq req = new ImMuteAllReq();
req.groupId = groupId;
groupInterface.muteAll(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
取消禁言
ImCancelMuteAllReq req = new ImCancelMuteAllReq();
req.groupId = groupId;
groupInterface.cancelMuteAll(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
禁言指定用户
ImMuteUserReq req = new ImMuteUserReq();
req.groupId = groupId;
req.userList.add(muteUserId);
groupInterface.muteUser(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
取消禁言
ImCancelMuteUserReq req = new ImCancelMuteUserReq();
req.groupId = groupId;
req.userList.add(muteUserId);
groupInterface.cancelMuteUser(req, new ImSdkCallback() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(Error error) {
}
});
查询禁言用户
ImListMuteUsersReq req = new ImListMuteUsersReq();
req.groupId = groupId;
groupManager.listMuteUsers(req, new ImSdkValueCallback<ImListMuteUsersRsp>() {
@Override
public void onSuccess(ImListMuteUsersRsp data) {
}
@Override
public void onFailure(Error error) {
}
});