# CCIMClientSDK for android 使用指南

## 导入CCIMClientSDK

* 将sdk复制到工程的lib目录下

```
    implementation(name: 'ccim-release', ext: 'aar')
    implementation 'com.google.protobuf:protobuf-java:3.13.0'
    implementation 'com.google.protobuf:protobuf-java-util:3.12.0'
    implementation 'com.karumi:dexter:6.2.3'
    implementation 'com.google.code.gson:gson:2.8.7'
    implementation 'io.netty:netty-all:4.1.4.Final'
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
    def room_version = "2.3.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    implementation 'com.karumi:dexter:6.2.3'

```

* 在AndroidManifest.xml加入以下权限

```
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
```

---

## 错误码定义:[错误码](./ErrorCode.html)

## 设置监听以及回调

### 接收到服务器推送的私聊消息或者频道消息

* 备注: 收到私聊消息,game端需要维护pushPrivateMsgRes中的msgId (如果是语音消息,需要拿msgid播放),这个方法调用一次就行了,重连之后也是不需要重新注册的,重复注册也是最后一个有效
* 接口

CCIMClient.getInstance().registerMessageListener(new OnPushMsgListener() {

```
        @Override
        public void pushPrivateMsg(MessageContent msg) {
            //收到私聊消息
        }

        @Override
        public void pushChannelMsg(MessageContent msg) {
            //收到频道消息
        }

        @Override
        public void pushNewContact(Contact contact) {
            //收到新联系人
        }

        @Override
        public void pushDeleteContact(Long contactId) {
            //收到删除联系人
        }

        @Override
        public void pushContactNetStatus(Long contactId, NetStatus status) {
            //收到联系人网络状态更新
        }

        @Override
        public void pushContactNewReq(User user) {
            //收到联系人申请
        }

         @Override
        public void pushUserMutedRes(Long mutedExpiredAt) {  //禁言的时间戳 -1 表示永久禁言
            ToastUtil.show(getApplicationContext(), "被禁言到" + mutedExpiredAt);
        }
```

## 初始化

* 参数说明:userId :需要登录的用户id,appKey:游戏产品标识,用于区分不同游戏.username:需要登录的用户名.extData:额外参数,提供游戏自用.ts 时间戳(毫秒).sign:登录签名,由游戏服务器提供.ResultEventCallback `<Void>`回调参数.server游戏服
* 备注:

    1. socket断开状态SDK会自动重连次 不会提示服务器断开
    2. 如果提示断开,需要游戏重新调用初始化 登录接口
* 接口

```
CCIMClient.getInstance().initSDK(context, appKey, username, extData, id, ts, sign,server, new OnConnectListener() {
            @Override
            public void onSocketConnection() {
                //连接成功
            }

            @Override
            public void onSocketDisconnection(int code) {
                //重连
            }
        });
```

## 搜索好友接口

* 参数说明 :`userName`:要搜索的好友的名称,`userId`:要搜索的好友的id,`size`:相同昵称一页最多拉取的数量,`page`:当前页码
* 备注:可以通过昵称和userid其一搜索,如果都填,以userid为主. page 页码从 `1`开始
* 接口

```
CCIMClient.getInstance().searchUser(userName, userId, page, size, new ResultEventCallback<SearchRes>() {
                            @Override
                            public void onSuccess(SearchRes searchRes) {
   
                            }

                            @Override
                            public void onFailed(int errorCode) {

                            }
                        });

```

## 添加好友接口

* 参数说明:`userId`:要添加的好友的id
* 备注:两个人互相添加好友,默认同意
* 接口

```
CCIMClient.getInstance().addContact(userId, new ResultEventCallback<Void>() {
                            @Override
                            public void onSuccess(Void unuse) {
  
                            }

                            @Override
                            public void onFailed(int errorCode) {
   
                            }
                        });

```

## 查看好友列表

* 参数说明 `isClearCache` true表示清除缓存,从服务器拿数据,false表示如果本地有数据会先拿本地的
* 备注:SDK会维护好友的在线,离线,拉黑状态,群组,最近联系人.
* 回调说明 contacts 联系人 contactGroups联系人群组 dialogs最近联系的人(包含陌生人) blocklist 黑名单
* 接口

```
CCIMClient.getInstance().getContactList(false, new ResultEventCallback<PullContactsRes>() {
            @Override
            public void onSuccess(PullContactsRes pullContactsRes) {
                contactList.postValue(pullContactsRes.getContacts());
                contactGroupList.postValue(pullContactsRes.getContactGroups());
                dialogList.postValue(pullContactsRes.getDialogs());
                blocklist.postValue(pullContactsRes.getBlockList());
            }

            @Override
            public void onFailed(int errorCode) {

            }
        });
```

## 查看申请人列表

* 备注:没有处理的好友申请,都会在申请人列表里
* 接口

```
CCIMClient.getInstance().getContactReqList(new ResultEventCallback<List<User>>() {
                    @Override
                    public void onSuccess(List<User> contactRequestsResponse) {
   
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 验证好友

* 参数说明:`userId`:通过或者拒绝人的userid `accept`:同意或者拒绝
* 备注:陌生人申请,通过验证就是好友关系
* 接口

```
CCIMClient.getInstance().checkContactReq(userId, accept, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 创建联系人群组

* 参数说明:`groupName`:创建群组的名称
* 备注:群组就是qq中的好友分组功能
* 接口

```
CCIMClient.getInstance().createContactGroup(groupName, new ResultEventCallback<Long>() {
                    @Override
                    public void onSuccess(Long aLong) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 删除联系人群组

* 参数说明:`groupId`:要删除群组的ID
* 接口

```
CCIMClient.getInstance().deleteContactGroup(groupId, new ResultEventCallback<Void>() {
                                    @Override
                                    public void onSuccess(Void unuse) {
                                        loginViewModel.getContactList();
                                    }

                                    @Override
                                    public void onFailed(int errorCode) {

                                    }
                                });
```

## 移动联系人所在组

* 参数说明:`groupId`:群组的ID,`userId`用户Id
* 接口

```
CCIMClient.getInstance().moveContactGroup(groupId, userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
                        refreshLogView("moveContactGroupRequest success ");
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 删除联系人

* 参数说明:`userId`:删除好友Id
* 备注:好友若一方删除,双方就不是好友关系
* 接口

```
CCIMClient.getInstance().deleteContact(userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 联系人加入黑名单

* 参数说明:`userId`:要操作的联系人的id
* 备注:`A` 把 `B` 加入黑名单,`A`可以给 `B`发送消息,`B`不能给 `A`发
* 接口

```
CCIMClient.getInstance().blockContact(userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
   
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });

```

## 联系人移出黑名单

* 参数说明:`userId`:要操作的联系人的id
* 备注:`A` 把 `B` 加入黑名单,`A`可以给 `B`发送消息,`B`不能给 `A`发
* 接口

```
CCIMClient.getInstance().unblockContact(userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
   
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });

```

## 屏蔽频道联系人

* 参数说明:`userId`:要操作的联系人的id `channelId`:频道id
* 备注:频道禁言功能
* 接口

```
CCIMClient.getInstance().blockChannelUser(channelId,userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
   
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });

```

## 举报违规用户

* 参数说明:`illegalUserId`:举报用户id `title`:举报标题 `content`:举报用户内容
* 接口

```
CCIMClient.getInstance().reportIllegalUser(title, content, illegalUserId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 发送消息

* 参数说明:`receiveUserId`:接受消息的人的userid `username`:接受消息的人的username `content`:发送消息的内容
* 备注:用于文本消息,私聊
* 接口

```
CCIMClient.getInstance().sendTextMessage(content, receiveUserId,username ,
                        new ResultEventCallback<MessageContent>() {
                            @Override
                            public void onSuccess(MessageContent messageContent) {

                            }

                            @Override
                            public void onFailed(int errorCode) {

                            }
                        });
```

## 发送频道消息

* 参数说明:`channelId`:频道id `content`:发送消息的内容
* 备注:加入或者创建频道,才可以发送频道消息
* 接口

```
 CCIMClient.getInstance().sendChannelMessage(content, channelId, new ResultEventCallback<MessageContent>() {
                    @Override
                    public void onSuccess(MessageContent messageContent) {
  
                    }
                    @Override
                    public void onFailed(int errorCode) {
  
                    }
                });
```

## 创建频道

* 参数说明:`name`:创建的频道名称 `open`:是否开放加入权限
  `tag`:标签 `userIdsArray`:不开放的时候,允许加入的用户
* 接口

```
CCIMClient.getInstance().createChannel(name, tag, open, userIdsArray, new ResultEventCallback<Long>() {
                    @Override
                    public void onSuccess(Long aLong) {

                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 加入频道

* 参数说明:`channelId`:要加入的频道id
* 接口

```
CCIMClient.getInstance().joinChannel(channelId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });
```

## 移除频道成员

* 参数说明:`channelId`:频道id `userId`:要移除频道的用户id
* 接口

```
 CCIMClient.getInstance().removeChannelMember(channelId, userId, new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {
  
                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                });

```

## 用户主动退出频道

* 参数说明:`channelId`:要退出的频道id
* 接口

```
CCIMClient.getInstance().exitChannel(channelId, new ResultEventCallback<Void>() {
                                    @Override
                                    public void onSuccess(Void unuse) {
       
                                    }

                                    @Override
                                    public void onFailed(int errorCode) {
        
                                    }
                                });
```

## 登出

* 备注:登出以后,只有重新初始化,可以继续操作别的接口
* 接口

```
CCIMClient.getInstance().logout();

```

## 私聊开始录音

* 参数说明:`context`:上下文,`receiverUserId`:接受消息的用户id `username`:接受消息的用户名称
* 接口

```
CCIMClient.getInstance().startRecordAudioMessage(context, receiveUserId, receiveUserName,new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {

                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                },new RecordAutoSendCallback() {
                                @Override
                                public void onSuccess(MessageContent t) {
                                
                                }

                                @Override
                                public void onFailed(int errorCode) {

                                }
                            });
```

## 取消录音

* 备注:取消当前录音
* 接口

```
CCIMClient.getInstance().cancleAudioMessage();
```

## 结束录音 并发送给私聊

* 参数说明:`receiverUserId`:接受消息的用户id `username`:接受消息的用户名称
* 备注:结束录音,并发送消息给用户
* 接口

```
CCIMClient.getInstance().stopAndSendAudioMessage(receiverUserId,username , new ResultEventCallback<MessageContent>(){
                        @Override
                        public void onSuccess(MessageContent message) {
  
                        }
                        @Override
                        public void onFailed(int errorCode) {
  
                        }
                    });
```

## 频道开始录音

* 参数说明:`context`:上下文,`channelId`:发送语音到某频道
* 接口

```
CCIMClient.getInstance().startRecordChannelAudioMessage(context, channelID,new ResultEventCallback<Void>() {
                    @Override
                    public void onSuccess(Void unuse) {

                    }

                    @Override
                    public void onFailed(int errorCode) {

                    }
                }, new RecordAutoSendCallback() {
                                @Override
                                public void onSuccess(MessageContent t) {
                                
                                }

                                @Override
                                public void onFailed(int errorCode) {

                                }
                            });
```

## 结束录音 并发送给频道

* 参数说明:`channelId`:发送语音到某频道
* 接口

```
CCIMClient.getInstance().stopAndSendChannelAudioMessage(channelId, new ResultEventCallback<MessageContent>(){
                        @Override
                        public void onSuccess(MessageContent message) {
  
                        }

                        @Override
                        public void onFailed(int errorCode) {
  
                        }
                    });
```

## 播放声音

* 参数说明:`msg_id`:消息id
* 备注: onsuccess播放成功代表播放完成
* 接口

```
CCIMClient.getInstance().startPlayAudio(msg_id, new ResultEventCallback<Void>() {
                        @Override
                        public void onSuccess(Void unuse) {
  
                        }

                        @Override
                        public void onFailed(int errorCode) {

                        }
                    });
```

## 停止播放声音

* 参数说明:
* 接口

```
CCIMClient.getInstance().stopPlayAudio();
```

## 获取时长

* 参数说明:`msgId` 消息id
* 接口

```
CCIMClient.getInstance().getAudioDuration(msgId, ResultEventCallback<Long> resultCallback);
```

## 获取私聊消息记录

* 参数说明:`userId`:用户id
* 接口

```
CCIMClient.getInstance().getPrivateMessage(userId, new ResultEventCallback<List<MessageContent>>() {
            @Override
            public void onSuccess(List<MessageContent> messageContents) {
  
            }

            @Override
            public void onFailed(int errorCode) {

            }
        });
```

## 获取频道消息记录

* 参数说明:`channelId`:频道id
* 接口

```
CCIMClient.getInstance().getChannelMessage(channelId, new ResultEventCallback<List<MessageContent>>() {
            @Override
            public void onSuccess(List<MessageContent> messageContents) {
  
            }

            @Override
            public void onFailed(int errorCode) {

            }
        });
```

## 加入房间
* 参数说明:context 上下文，roomId 房间号 ，teamId 小队id
* 接口

```
CCIMClient.getInstance().joinAudioRoom(context, roomId, teamId,new AudioRoomListener() {
                            @Override
                            public void onJoinSuccess() {
                                ToastUtil.show(getContext(), "onJoinSuccess");
                            }

                            @Override
                            public void onJoinFailed(int code) {
                                ToastUtil.show(getContext(), "onJoinFailed" + code);
                            }

                            @Override
                            public void onExit() {
                                ToastUtil.show(getContext(), "onExit");
                            }

                            @Override
                            public void onError(int code) {
                                ToastUtil.show(getContext(), "onError");
                            }
                        });
```

## 退出房间

```
CCIMClient.getInstance().exitAudioRoom();
```

## 切换语音目标(小队和频道的切换)
* true 频道语音
```
CCIMClient.getInstance().audioTargetWorld(enable)
```

## 是否开启本地音频
* boolean
```
 CCIMClient.getInstance().setLocalAudio(boolean);
```

## 更新已读偏移量

* userId 用户id
* msgid 消息id

```
public void updateReadOffset(Long userId, Long msgid, ResultEventCallback<Void> callback) 
```

## 是否禁言自己

* boolean

```
public void setLocalAudio(boolean enable)
```

## 消息内容

```
Long msgId;// 消息id
Long senderUserId; //发送消息userid
String content; // 消息内容 发送文本消息会去掉敏感词 语音消息是文件名
Long createdDate;
Long modifiedDate;
Long reciveUserId; //接收方的userId
Long channelId; // 频道消息会带有频道号
MessageType msgType //MessageType.MESSAGE_TYPE_TEXT //文本消息;MessageType.MESSAGE_TYPE_VOICE //语音消息
MessageSourceType msgSrcType // MessageSourceType.MESSAGE_SOURCE_TYPE_PRIVATE //私聊消息 MESSAGE_SOURCE_TYPE_CHANNEL //频道消息
User senderUser; //发送消息人的信息 包含id , name
voiceContent; //语音转文本内容

```
