IM SDK for Android 开发指引
概述
游密即时通讯SDK(IM SDK)为玩家提供完整的游戏内互动服务,游戏开发者无需关注IM通讯复杂的内部工作流程,只需调用IM SDK提供的接口,即可快速实现世界聊天、公会聊天、组队聊天、文字、表情、语音等多项功能。
IM SDK接口调用顺序

四步集成IM SDK
第一步 注册账号
在游密官网注册游密账号。
第二步 添加游戏,获取Appkey
在控制台添加游戏,获得接入需要的Appkey、Appsecret。
第三步 下载IM SDK包体
第四步 开发环境配置
快速接入
1. 导入IM SDK
解压SDK
解压SDK并将lib文件夹的所有文件移至Android工程-app-libs文件夹下(开发者也可根据实际路径填写)。
配置依赖项
- 添加 SDK 引用,进入到 “app” 目录,打开 “build.gradle” 文件。在 “defaultConfig” 节点添加 “ndk” 节点,指定支持的平台类型。
defaultConfig{
//添加如下设置支持到so库架构
ndk{
abiFilters 'armeabi','armeabi-v7a','x86' //架构可选对应项目需要的
}
}- 在 “android” 节点添加 “sourceSets” 节点,指定 “libs” 所在目录。
sourceSets{
main{
jniLibs.srcDirs = ['libs']
}
}- 引入依赖的Jar包,按图示2点击后,在弹出的框内选择jar包的地址,即Android工程-app-libs文件夹。
引入后,会自动在 “dependencies” 节点增加以下项,其中红框部分的dir为jar包所在路径。

如果接入的是带google语音识别功能版本的SDK:
- 需要在app的build.gradle中添加如下内容:
allprojects {
repositories {
//添加google语音识别需要的
jcenter()
google()
//添加结束
}
}- 需要在Module的build.gradle的dependencies中配置依赖项:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//添加google语音识别需要的
compile "io.grpc:grpc-okhttp:1.32.2"
compile "io.grpc:grpc-protobuf-lite:1.4.0"
compile "io.grpc:grpc-stub:1.4.0"
compile 'javax.annotation:javax.annotation-api:1.2'
//添加结束
}如果接入的是带云知声语音识别的版本:
- 需要在app的build.gradle中添加如下内容:
allprojects {
repositories {
//添加云知声语音识别需要的
mavenCentral()
//添加结束
}
}- 需要在Module的build.gradle的dependencies中配置一下依赖项。
dependencies {
implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs')
//添加云知声语音识别需要的
implementation 'com.android.support:appcompat-v7:24.1.1'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
//添加结束
}Android权限配置
- 在AndroidManifest.xml中添加如下配置信息:
<!-- 添加到application节点内 -->
<application xxxx>
<receiver android:name="com.youme.im.NetworkStatusReceiver" android:label="NetworkConnection" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
<!-- 添加到跟application平级 -->
<!-- 允许程序访问互联网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序获取 Wi-Fi 状态信息(Wi-Fi 是否启用) -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序获取网络信息状态(是否连接到网络) -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许程序写入外部存储(存储 SDK 日志文件) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许程序通过手机或耳机的麦克录制声音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 获取地理位置的权限,可选 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />混淆配置
- 如果打包或生成APK时需要混淆,则需要在proguard.cfg文件中添加如下代码:
-keep class com.youme.** {*;}
-keep class com.iflytek.**
-keepattributes Signature 2. 初始化
成功导入SDK后,应用启动的第一时间需要调用初始化接口。
import包名
import com.youme.imsdk.YIMClient;
这是一个单例类,可以通过getInstance()获取到它的实例。通过它就可以调用IM SDK的API接口。
初始化IM SDK
-
调用示例:
JAVA YIMClient.getInstance().init(context, "strAppKey", "strSecrect", 0); -
接口与参数:
-
返回值:
YIMConstInfo.ErrorCode:错误码,详细描述见错误码定义。
-
备注:
此接口本是异步操作,未给出异步回调,一般返回的错误码是Success即表示初始化成功。
3. 设置回调监听 (以下流程是参考2.3.0.11036版本及之前的流程新版sdk的接口流程请查询API Guides)
IM引擎底层对于耗时操作都采用异步回调的方式,函数调用会立即返回,操作结果java层会同步回调。因此,用户必须实现相关接口并在初始化完成以后注册到YIMService。常用功能需要注册登录回调,聊天室回调,消息回调,如需其它功能查看API接口。
-
调用示例:
JAVA import com.youme.imsdk.YIMClient; ... public class MainActivity extends Activity { ... private YouMeIMCallback mCallback = new YouMeIMCallback(); protected void onCreate(Bundle savedInstanceState) { // 初始化 YIMClient.getInstance().init(this, "strAppKey", "strSecrect", 0); // 设置监听 YIMClient.getInstance().registerMessageListener(mCallback); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... } ... // 回调接口实现 private class YouMeIMCallback implements MessageEventCallback { /** * 功能:接收到用户发来的消息 * * @param message 消息内容结构体 */ public void onRecvMessage(YIMMessage message) { if (null == message) return; int msgType = message.getMessageType(); if (YIMConstInfo.MessageBodyType.TXT == msgType) { Log.i("YOUMEIM", "接收到一条文本消息: " + ((YIMMessageBodyText)message.getMessageBody()).getMessageContent()+",消息ID:"+message.getMessageID()); } else if (YIMConstInfo.MessageBodyType.Voice == msgType) { YIMMessageBodyAudio audioMessage = (YIMMessageBodyAudio)message.getMessageBody(); int audioDuration = audioMessage.getAudioTime(); String param = audioMessage.getParam();//自定义附加参数 String txt = audioMessage.getText();//语音转文字识别结果 long mRecvAudioMsgId = message.getMessageID(); Log.i("YOUMEIM", "接收到一个录音文件 / AudioTime: " + audioDuration + " 录音文本信息:" + txt + " messID: " + mRecvAudioMsgId); //下载语音文件 .... } } //其余回调接口实现 ... } ... } -
接口:
消息回调注册接口:public void registerMsgEventCallback(YIMEventCallback.MessageEventCallback callback)
4. 登录IM系统
成功初始化IM后,调用IM SDK登录接口登录IM系统。
-
调用示例:
JAVA YIMClient.getInstance().login("1001", "12345","", new YIMEventCallback.ResultCallback<String>() { @Override public void onSuccess(String userID) { Log.i("YOUMEIM","登录成功,"+userID); }); -
接口与参数:
-
登录接口:public void login(String userId, String password, String token, final YIMEventCallback.ResultCallback<String> callback) -
userId:由调⽤者分配,不可为空字符串,只可由字母或数字或下划线组成,用户首次登录会自动注册所用的用户ID和密码。 -
password:⽤户密码,不可为空字符串,由调用者分配,二次登录时需与首次登录一致,否则会报UsernamePasswordError。 -
token:用户验证token,可选,如不使用token验证传入:""。 -
callback:登录回调。
-
5. 进入聊天频道
登录成功后,如果有群组聊天需要,比如游戏里面的世界、工会、区域等,需要进入聊天频道;调用方为聊天频道设置一个唯一的频道ID,可以进入多个频道。
-
调用示例:
JAVA // 可在登录成功的回调里面调用 YIMClient.getInstance().joinChatRoom("1234", new YIMEventCallback.ResultCallback<ChatRoom>() { @Override public void onSuccess(ChatRoom info) { Log.i("YOUMEIM","加入频道成功,"+info.groupId); } ); -
接口与参数
-
进入频道接口:public void joinChatRoom(String roomId, final YIMEventCallback.ResultCallback<ChatRoom> callback) -
roomId:请求加入的频道ID,仅支持数字、字母、下划线组成的字符串,区分大小写,长度限制为255字节。 -
callback:加入频道回调。
-
6. 发送文本消息
在成功登录IM后,即可发送IM消息。
-
调用示例:
JAVA // 发送私聊文本消息 YIMClient.getInstance().sendTextMessage("1001", YIMConstInfo.ChatType.PrivateChat, "mMsgContent", "", new YIMEventCallback.ResultCallback<SendMessage>(){ @Override public void onSuccess(SendMessage info) { Log.i("YOUMEIM","发送文本消息 成功,requestID:"+info.requestId + ",sendTime:"+info.sendTime+", reasonType: "+info.reasonType+", isForbiddenRoom: "+info.isForbidRoom+", endTime: "+info.endTime); } @Override public void onFailed(int errorcode, SendMessage info) { Log.i("YOUMEIM","发送文本消息 失败,requestID:"+info.requestId + ",sendTime:"+info.sendTime+", reasonType: "+info.reasonType+", isForbiddenRoom: "+info.isForbidRoom+", endTime: "+info.endTime); } }); -
接口与参数:
-
发文本消息接口:public void sendTextMessage(String recvId, int chatType, String msgContent, String attachParam, YIMEventCallback.ResultCallback<SendMessage> callback) -
recvId:接收者ID,私聊传入用户ID,频道聊天传入频道ID。 -
chatType:聊天类型,私聊传1,频道聊天传2;需要频道聊天得先成功进入频道后发文本消息,此频道内的成员才能接收到消息。 -
msgContent:聊天内容。 -
attachParam: 发送文本附加信息。 -
callback:发送文本消息回调。
-
-
发送文本消息回调::
YIMEventCallback.ResultCallback<SendMessage>:
public interface ResultCallback<SendMessage> {
/**
* @param msgInfo 发送消息回调信息
*/
public void onSuccess(SendMessage msgInfo);
/**
* @param msgInfo 发送消息回调信息
*/
public void onFailed(int errorcode, SendMessage msgInfo);
}
-
备注:
SendMessage类成员方法如下:
getRequestId(): 消息序列号,用于校验一条消息发送成功与否的标识,long类型。
getSendTime(): 消息发送时间,long类型。
getIsForbidRoom(): 若发送的是频道消息,显示在此频道是否被禁言,true-被禁言,false-未被禁言,boolean类型。
getReasonType(): 若在频道被禁言,禁言原因类型,0-未知,1-发广告,2-侮辱,3-政治敏感,4-恐怖主义,5-反动,6-色情,7-其它,int类型。
getEndTime(): 若在频道被禁言,禁言结束时间,long类型。
getMessageID(): 返回服务器messageID,与接收消息时的getMessageID()是统一的。 -
拓展功能: 发送消息时,可以将玩家头像、昵称、角色等级、vip等级等要素打包成json格式发送。
7. 发送语音消息
在成功登录IM后,可以发送语音消息。
- 按住语音按钮时,调用
startRecordAudioMessage接口,启动录音。- 松开按钮,调用
stopAndSendAudioMessage接口,发送语音消息。- 按住过程若需要取消发送,调用
cancleAudioMessage取消本次语音发送。
-
调用示例:
JAVA // 启动语音 YIMClient.getInstance().startRecordAudioMessage("1001",1,"带文字识别",true,false); // 停止并发送语音消息 YIMClient.getInstance().stopAndSendAudioMessage(new YIMEventCallback.AudioMsgEventCallback(){ @Override public void onStartSendAudioMessage(Long requestID, int errorcode, String strText, String strAudioPath, int audioTime) { Log.i("YOUMEIM","开始发送语音回调,errorcode:" + errorcode + ", requestID: "+requestID+", text:"+strText + ", audioPath: "+strAudioPath+", audioTime: "+audioTime); } @Override public void onSendAudioMessageStatus(int errorcode, SendVoiceMsgInfo voiceMsgInfo) { Log.i("YOUMEIM","发送语音结果回调,errorcode:" + errorcode + ", requestID: "+voiceMsgInfo.getRequestId()+", extraText:"+voiceMsgInfo.getExtraText() + ", localPath: "+voiceMsgInfo.getLocalPath()+", audioTime: "+voiceMsgInfo.getDuration()+", sendTime: "+voiceMsgInfo.getSendTime() +", isForbidRoom: "+voiceMsgInfo.getIsForbidRoom()+", reasonType: "+voiceMsgInfo.getReasonType()+", endTime: "+voiceMsgInfo.getEndTime()); } } ); // 如果不想发送语音,调取消本次语音,调取消后收不到消息的发送回调 YIMClient.getInstance().cancleAudioMessage(); -
接口与参数:
-
发送语音消息接口:public MessageSendStatus startRecordAudioMessage(String recvId, int chatType, String extraText, boolean recognizeText, boolean IsOpenOnlyRecognizeText) -
结束录音接口:public void stopAndSendAudioMessage(YIMEventCallback.AudioMsgEventCallback callback) -
取消录音接口:public int cancleAudioMessage() -
strRecvID:接收者ID(⽤户ID或者频道ID)。 -
chatType:消息类型,表示私聊还是频道消息。 -
extraText:发送语音消息附加信息,主要用于调用方特别需求。 -
recognizeText:是否带文字识别。 -
IsOpenOnlyRecognizeText:是否开启仅识别语音文本,不发送语音消息。
-
-
回调接口与参数:
调用stopAndSendAudioMessage接口后,会收到发送语音的回调,如果录音成功会收到开始发送语音的回调onStartSendAudioMessage,无论录音是否成功都会收到发送语音消息结果的回调onSendAudioMessageStatus,onStartSendAudioMessage在接收时间上比onSendAudioMessageStatus快,常用于上屏显示。
public interface AudioMsgEventCallback {
/**
* 录音结束,开始发送录音的通知,这个时候已经可以拿到语音文件进行播放
*
* @param requestID 请求ID(与startRecordAudioMessage输出参数requestID一致)。
* @param errorcode 错误码。
* @param strText 语音转文字识别的文本内容,如果带语音转文字参数为false,该字段为空字符串。
* @param strAudioPath 录音生成的wav文件的本地完整路径。
* @param audioTime 录音时长(单位秒)。
*/
public void onStartSendAudioMessage(long requestID, int errorcode, String strText, String strAudioPath, int audioTime);
/**
* 自己的语音消息发送成功或者失败的通知
*
* @param errorcode 错误码
* @param voiceMsgInfo :语音信息
*/
public void onSendAudioMessageStatus(int errorcode, SendVoiceMsgInfo voiceMsgInfo);
} - 备注:
语音发送是异步操作。onStartSendAudioMessage表示录音完成并进入开始发送阶段,可用于显示“发送中”;最终发送成功以onSendAudioMessageStatus回调的错误码为 Success 为准。stopAndSendAudioMessage返回 void,调用方通过回调处理结果。接收方通过onRecvMessage获取语音消息并下载语音文件。
8. 接收消息
- 通过
onRecvMessage接口被动接收消息,需要开发者实现
-
调用示例:
JAVA public void onRecvMessage(YIMMessage yimMessage) { Log.i("YOUMEIM", "接收到消息 "); if (null == yimMessage) return; int msgType = yimMessage.getMessageType(); if (YIMConstInfo.MessageBodyType.TXT == msgType) { Log.i("YOUMEIM", "接收到一条文本消息: " + ((YIMMessageBodyText)yimMessage.getMessageBody()).getMessageContent()+",消息ID:"+yimMessage.getMessageID()); } else if (YIMConstInfo.MessageBodyType.Voice == msgType) { YIMMessageBodyAudio audioMessage = (YIMMessageBodyAudio)yimMessage.getMessageBody(); int audioDuration = audioMessage.getAudioTime(); String param = audioMessage.getParam();//自定义附加参数 String txt = audioMessage.getText();//语音转文字识别结果 long mRecvAudioMsgId = yimMessage.getMessageID(); Log.i("YOUMEIM", "接收到一条语音消息,AudioTime: " + audioDuration + " 录音文本信息:" + txt + " messID: " + mRecvAudioMsgId); // 下载语音文件 YIMClient.getInstance().downloadAudioMessage(mRecvAudioMsgId, "save Path", new YIMEventCallback.DownloadFileCallback() { @Override public void onDownload(int errorcode, YIMMessage message, String savePath) { Log.i("YOUMEIM","手动下载语音消息回调,err: "+errorcode+", senderID: "+message.getSenderID()+", savePath: "+savePath); YIMClient.getInstance().startPlayAudio(savePath, new YIMEventCallback.ResultCallback<String>() { @Override public void onSuccess(String info) { Log.i("YOUMEIM","播放语音成功,"+info); } @Override public void onFailed(int errorcode, String info) { Log.i("YOUMEIM","播放语音失败,err: "+ errorcode+", info: "+info); } }); } }); } ... }
9. 接收语音消息并播放
- 通过
getMessageType()分拣出语音消息(MessageBodyType.Voice)。- 用
getMessageID()获得消息ID。- 调用
downloadAudioMessage接口下载语音消息。- 成功下载语音消息后,调用
StartPlayAudio接口播放语音消息。
-
调用示例:
JAVA // 下载语音文件 YIMClient.getInstance().downloadAudioMessage(mRecvAudioMsgId, "save Path", new YIMEventCallback.DownloadFileCallback() { @Override public void onDownload(int errorcode, YIMMessage message, String savePath) { Log.i("YOUMEIM","手动下载语音消息回调,err: "+errorcode+", senderID: "+message.getSenderID()+", savePath: "+savePath); YIMClient.getInstance().startPlayAudio(savePath, new YIMEventCallback.ResultCallback<String>() { @Override public void onSuccess(String info) { Log.i("YOUMEIM","播放语音成功,"+info); } @Override public void onFailed(int errorcode, String info) { Log.i("YOUMEIM","播放语音失败,err: "+ errorcode+", info: "+info); } }); } }); -
接口和参数:
-
下载语音消息接口:public void downloadAudioMessage(long serial, String savePath, YIMEventCallback.DownloadFileCallback callback) -
播放语音消息接口:public void startPlayAudio(String audioPath, YIMEventCallback.ResultCallback<String> callback)serial:消息ID。savePath:语音文件保存路径。audioPath:待播放文件路径。callback:回调。
-
-
回调接口与参数:
下载语音接口是异步操作,下载语音成功的标识是onDownload回调的错误码为Success;downloadAudioMessage返回 void,通过onDownload回调判断下载结果。成功下载语音消息后即可播放语音消息。下载回调接口:
JAVA public interface DownloadFileCallback { /** * 下载回调 * * @param errorcode 错误码 * @param message 消息 * @param savePath 文件存放路径 */ public void onDownload(int errorcode, YIMMessage message, String savePath); }-
errorcode:错误码。 -
message:消息基类。 -
savePath:保存路径。 -
播放完成回调接口:
JAVA public interface ResultCallback<String>{ /** * @param audioPath 播放的音频文件路径 */ public void onSuccess(String audioPath); /** * @param errorcode 错误码 * @param audioPath 播放的音频文件路径 */ public void onFailed(int errorcode, String audioPath); }
10. 登出IM系统
注销账号时,调用登出接口logout登出IM系统。
-
调用示例:
JAVA YIMClient.getInstance().logout(new YIMEventCallback.OperationCallback(){ @Override public void onSuccess() { Log.i("YOUMEIM","登出成功,"); } @Override public void onFailed(int errorcode) { Log.i("YOUMEIM","登出失败,code:"+errorcode); } }); -
接口:
登出接口:public void logout(final YIMEventCallback.OperationCallback callback)
典型场景集成方案
主要分为世界频道聊天,用户私聊,直播聊天室;集成的时都需要先初始化SDK,登录IM系统。
启动应用,初始化SDK
应用启动的第一时间需要调用初始化接口。
-
接口与参数:
-
代码示例与详细说明:
登录应用时,登录IM系统

- 点击
登录按钮时,调用IM SDK登录接口。
-
接口与参数:
login:登录接口。userId:由调⽤者分配,不可为空字符串,只可由字母或数字或下划线组成。password:⽤户密码,不可为空字符串。token:用户验证token,可选,如不使用token验证传入:""。callback:登录回调。
-
代码示例与详细说明:
典型场景
世界频道聊天

- 进入应用后,调用加入频道接口,进入世界、公会、区域等需要进入的聊天频道。
- 应用需要为各个聊天频道设置一个唯一的频道ID。
- 成功进入频道后,发送频道消息,文本、语音消息等。
-
接口与参数
joinChatRoom:加入频道。roomId:请求加入的频道ID。callback:加入频道回调。
-
代码示例与详细说明:
用户私聊
直播聊天室
- 用户集成直播SDK后,导入IM SDK。
- 初始化IM SDK。
- 登录IM 系统。
- 进入指定的聊天频道。
- 发送频道消息(例如:弹幕式),调用流程查看发送文本消息。
发送文本消息

- 点击发送按钮,调用发消息接口,将输入框中的内容发送出去。
- 发送出的消息出现在聊天框右侧。
- 表情消息可以将表情信息打包成Json格式发送。
-
相关接口与参数:
sendTextMessage:发文字消息接口。recvId:接收者ID,私聊传入用户ID,频道聊天传入频道ID。chatType:聊天类型,私聊/频道聊天。msgContent:聊天内容。attachParam: 发送文本附加信息。callback:发送文本消息回调。
-
代码示例与详细说明:
-
拓展功能: 发送消息时,可以将玩家头像、昵称、角色等级、vip等级等要素打包成json格式发送。
发送语音消息

- 按住语音按钮时,调用
startRecordAudioMessage。- 松开按钮,调用
stopAndSendAudioMessage接口,发送语音消息。- 按住过程若需要取消发送,调用
cancleAudioMessage取消发送。
-
相关接口与参数:
startRecordAudioMessage:发送语音消息接口。stopAndSendAudioMessage:结束录音接口。cancleAudioMessage:取消录音接口。strRecvID:接收者ID(⽤户ID或者频道ID)。chatType:消息类型,表示私聊还是频道消息。extraText:语音消息附带信息。recognizeText:是否带文字识别。IsOpenOnlyRecognizeText:是否开启仅识别语音文本,不发送语音消息。
-
代码示例与详细说明:
接收消息

- 通过
onRecvMessage接口被动接收消息,需要开发者实现,接收消息进行相应的展示,如果是语音消息需要下载语音,以及下载完成后的语音播放。
-
相关接口与参数:
onRecvMessage:收消息接口。
-
代码示例与详细说明:
接收语音消息并播放

- 通过
getMessageType()分拣出语音消息(MessageBodyType.Voice)。- ⽤
getMessageID()获得消息ID。- 点击语音气泡,调用
downloadAudioMessage接口下载语音文件。- 调用方播放语音文件。
-
相关接口与参数:
-
downloadAudioMessage:下载语音文件接口。 -
startPlayAudio:播放语音文件接口。serial:消息ID。savePath:保存路径。audioPath:音频文件路径。callback:回调。
-
-
代码示例与详细说明:
登出IM系统

- 如下两种情况需要登出IM系统:
- 注销账号时,调用
logout接口登出IM系统。- 退出应用时,调用
logout接口登出IM系统。
-
相关接口:
logout:登出接口。
-
代码示例与详细说明:
