Talk SDK for Android 使用指南
适用范围
本文档适用于游密实时语音引擎(Talk SDK)Android Studio开发环境下接入。
开发环境
在开始集成游密 Talk SDK 前,请确保开发环境满足以下要求:
- Android Studio 2.1 或以上版本。
- Android SDK 25、Android SDK Build-Tools 25.0.2、Android SDK Platform-Tools 25.x.x 或以上版本。
- Android 4.0 或以上版本,且支持音频的 Android 设备或模拟器(推荐使用真机) Android 设备已经连接到 Internet。
SDK包
项目依赖的实时语音 SDK 为youme_voice_engine.aar本地归档包。该 AAR 内部包含 Java 对外 API 包装类以及对应多 ABI 架构的 JNI 原生 so 库;Java 层 API 作为上层封装,会转发调用 AAR 内部 so 库中注册的 JNI 本地函数完成实际业务逻辑。
集成SDK
- 将AAR文件移至Android工程libs文件夹下(示例代码中 “libs” 目录仅为举例,开发者可根据实际路径填写)
- 添加 SDK 引用,进入到 “app” 目录,打开 “build.gradle” 文件。在 “defaultConfig” 节点添加 “ndk” 节点,指定支持的平台类型:
- Groovy (.gradle)
defaultConfig{
//添加如下设置支持到so库架构
ndk{
abiFilters 'armeabi','armeabi-v7a','x86' //架构可选对应项目需要的
}
}- Kotlin DSL (.gradle.kts)
defaultConfig {
ndk {
abiFilters.clear()
abiFilters += listOf("arm64-v8a")
}
}- 在 “dependencies” 节点引入 “libs” 下所有的 aar文件:
- Groovy (.gradle)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar'], exclude: [])
}- Kotlin DSL (.gradle.kts)
dependencies {
implementation(fileTree("libs") {
include("*.aar")
})
}- Android平台的AAR包已默认包含以下配置,解压AAR包可看到AndroidManifest.xml文件,主工程勿重复添加:
<!-- 允许程序访问互联网 -->
<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" />
<!-- 允许程序修改Wi-Fi状态(如开启/关闭Wi-Fi) -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 允许程序修改网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_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.MODIFY_AUDIO_SETTINGS" />
<!-- 允许程序连接到蓝牙设备配对,Android 11 (API 30) 及以下 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 允许程序连接到蓝牙设备配对,Android 12 (API 31) 及以上 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />- 防止混淆代码:YOUMESDK不需要混淆,如果你的工程有混淆,请在proguard-rules.pro文件中添加如下代码:
-keep class com.youme.**{*;}
-keepattributes Signature- 设置加载库以及启动相关服务 在入口Activity类先导入package:
import android.content.Intent;
import android.os.Bundle;
import com.youme.voiceengine.mgr.YouMeManager; 然后在onCreate方法里添加“YouMeManager.Init”,且需要在“super.onCreate”之前调用,以解决某些设备兼容性问题: YouMeManager.Init(this);
super.onCreate(savedInstanceState);语音通话流程图

语音通话时序图

语音通话相关代码
初始化
设置回调监听。
api.SetCallback(this);然后implements YouMeCallBackInterface。
public class MainActivity extends AppCompatActivity implements YouMeCallBackInterface重写里面的方法,其中里面的onEvent会得到关于所有Talk相关的回调。
// 消息回调接口实现
@Override
public void onEvent(int eventType, int errorCode, String channelID, Object param) {}
@Override
public void onRequestRestAPI(int i, int i1, String s, String s1) {}
@Override
public void onMemberChange(String s, MemberChange[] memberChanges, boolean b) {}
@Override
public void onBroadcast(int i, String s, String s1, String s2, String s3) {}
@Override
public void onDetectNetWorkComplete(boolean networkOK, String result) {}
@Override
public void onAVStatisticNew(int type, String userID, int value, String param) {}初始化Talk SDK:其中appKey和appSecret为在游密后台申请的App Key和App Secret。serverZone:Talk 服务器区域,建议使用 YouMeConst.YOUME_RTC_SERVER_REGION.RTC_DEFAULT_SERVER,其余设置值可查看官网文档-服务器部署地区定义。
// 初始化
api.init(appKey, appSecret, serverZone, "");加入频道
onEvent收到初始化成功消息YouMeEvent.YOUME_EVENT_INIT_OK后: 加入频道: 其中userID:用户标识,channelID:频道标识,userRole:用户在语音频道里面的角色,主要分为YOUME_USER_HOST(可以随时讲话和播放战歌等)、YOUME_USER_LISTENER(只听不讲)、YOUME_USER_TALKER_FREE(自由讲话者)等,详情见YouMeUserRole定义。
api.joinChannel(userID, channelID, userRole, true, bCheckRoomExist);开关音频设备
onEvent收到加入频道成功消息YouMeEvent.YOUME_EVENT_JOIN_OK后: 打开/关闭麦克风:其中mute为true表示关闭麦克风,false表示开启麦克风。
api.setMicrophoneMute(mute);打开/关闭扬声器:mute 为 true 表示关闭扬声器,false 表示开启扬声器。
api.setSpeakerMute(mute);设置音量(音量范围0-100,建议设置70比较适中)。
api.setVolume(70); 离开频道,反初始化
离开频道。
api.leaveChannelAll();反初始化。
api.unInit();附:部分事件状态码
@Override
public void onEvent(int eventType, int errorCode, String channelID, Object param) {
log("OnEvent:event "+eventType + ",error " + errorCode + ",channel " + channelID + ",param_" + param.toString());
Message msg = new Message();
switch( eventType ){
case YouMeEvent.YOUME_EVENT_INIT_OK: //YOUME_EVENT_INIT_OK:
log("Talk 初始化成功");
break;
case YouMeEvent.YOUME_EVENT_INIT_FAILED://YOUME_EVENT_INIT_FAILED:
log("Talk 初始化失败");
break;
case YouMeEvent.YOUME_EVENT_JOIN_OK://YOUME_EVENT_JOIN_OK:
log("Talk 进入频道成功,频道:"+channelID+" 用户id:"+param);
break;
case YouMeEvent.YOUME_EVENT_JOIN_FAILED://YOUME_EVENT_JOIN_FAILED:
log("Talk 进入频道:"+channelID+"失败,code:"+errorCode);
break;
case YouMeEvent.YOUME_EVENT_LEAVED_ONE://YOUME_EVENT_LEAVED_ONE:
log("Talk 离开单个频道:"+channelID);
break;
case YouMeEvent.YOUME_EVENT_LEAVED_ALL://YOUME_EVENT_LEAVED_ALL:
log("Talk 离开所有频道,这个回调channel参数为空字符串");
break;
case YouMeEvent.YOUME_EVENT_PAUSED://YOUME_EVENT_PAUSED:
log("Talk 暂停");
break;
case YouMeEvent.YOUME_EVENT_RESUMED://YOUME_EVENT_RESUMED:
log("Talk 恢复");
break;
case YouMeEvent.YOUME_EVENT_SPEAK_SUCCESS://YOUME_EVENT_SPEAK_SUCCESS:///< 切换对指定频道讲话成功(适用于多频道模式)
break;
case YouMeEvent.YOUME_EVENT_SPEAK_FAILED://YOUME_EVENT_SPEAK_FAILED:///< 切换对指定频道讲话失败(适用于多频道模式)
break;
case YouMeEvent.YOUME_EVENT_RECONNECTIN://YOUME_EVENT_RECONNECTING:///< 断网了,正在重连
log("Talk 正在重连");
break;
case YouMeEvent.YOUME_EVENT_RECONNECTED://YOUME_EVENT_RECONNECTED:///< 断网重连成功
log("Talk 重连成功");
break;
case YouMeEvent.YOUME_EVENT_REC_PERMISSION_STATUS://YOUME_EVENT_REC_FAILED:///< 通知录音启动失败(此时不管麦克风mute状态如何,都没有声音输出)
log("录音启动失败,code:"+errorCode);
break;
case YouMeEvent.YOUME_EVENT_BGM_STOPPED://YOUME_EVENT_BGM_STOPPED:///< 通知战歌播放结束
log("战歌播放结束,path:"+param);
break;
case YouMeEvent.YOUME_EVENT_BGM_FAILED://YOUME_EVENT_BGM_FAILED:///< 通知战歌播放失败
log("战歌播放失败,code:"+errorCode);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_MIC_ON://YOUME_EVENT_OTHERS_MIC_ON:///< 其他用户麦克风打开
log("其他用户麦克风打开,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_MIC_OFF://YOUME_EVENT_OTHERS_MIC_OFF:///< 其他用户麦克风关闭
log("其他用户麦克风关闭,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_SPEAKER_ON://YOUME_EVENT_OTHERS_SPEAKER_ON:///< 其他用户扬声器打开
log("其他用户扬声器打开,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_SPEAKER_OFF://YOUME_EVENT_OTHERS_SPEAKER_OFF: ///< 其他用户扬声器关闭
log("其他用户扬声器关闭,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_VOICE_ON://YOUME_EVENT_OTHERS_VOICE_ON: ///< 其他用户进入讲话状态
log("开始讲话,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_OTHERS_VOICE_OFF://YOUME_EVENT_OTHERS_SPEAKER_OFF: ///< 其他用户停止讲话
log("停止讲话userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_MY_MIC_LEVEL://YOUME_EVENT_MY_MIC_LEVEL: ///< 自己的麦克风的语音音量级别
log("我当前讲话的音量级别是,数值:"+errorCode);
break;
case YouMeEvent.YOUME_EVENT_MIC_CTR_ON://YOUME_EVENT_MIC_CTR_ON: ///< 自己的麦克风被其他用户打开
log("自己的麦克风被其他用户打开,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_MIC_CTR_OFF://YOUME_EVENT_MIC_CTR_OFF: ///< 自己的麦克风被其他用户关闭
log("自己的麦克风被其他用户关闭,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_SPEAKER_CTR_ON://YOUME_EVENT_SPEAKER_CTR_ON: ///< 自己的扬声器被其他用户打开
log("自己的扬声器被其他用户打开,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_SPEAKER_CTR_OFF://YOUME_EVENT_SPEAKER_CTR_OFF: ///< 自己的扬声器被其他用户关闭
log("自己的扬声器被其他用户关闭,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_LISTEN_OTHER_ON://YOUME_EVENT_LISTEN_OTHER_ON: ///< 取消屏蔽某人语音
log("取消屏蔽某人语音,userid:"+param);
break;
case YouMeEvent.YOUME_EVENT_LISTEN_OTHER_OFF://YOUME_EVENT_LISTEN_OTHER_OFF: ///< 屏蔽某人语音
log("屏蔽某人语音,userid:"+param);
break;
default:
break;
}
@Override
public void onRequestRestAPI(int a,int b,String c,String d){
}
@Override
public void onMemberChange(String a, MemberChange[] b,boolean d){
}
@Override
public void onBroadcast(int a,String b,String c,String d,String e){
}
@Override
public void onDetectNetWorkComplete(boolean networkOK, String result) {}
@Override
public void onAVStatisticNew(int type, String userID, int value, String param) {}更多的事件状态码可以参考官网的状态码定义-YouMeEvent类。
- 打开创建的新New project,在MainActivity.java文件里的示例代码如下:
package com.example.stepbytalkdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.youme.voiceengine.mgr.YouMeManager;
import com.youme.voiceengine.*;
public class MainActivity extends AppCompatActivity implements YouMeCallBackInterface {
public static final String appKey = "YOUME";
public static final String appSecret = "123456789";
@Override
protected void onCreate(Bundle savedInstanceState) {
YouMeManager.Init(this);
api.SetCallback(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
api.init(appKey,appSecret,0,"");
}
@Override
public void onEvent(int eventType,int errorCode,String channelID,Object param){
if(eventType== YouMeConst.YouMeEvent.YOUME_EVENT_INIT_OK){
api.joinChannel("12345", "12345", 1, true, false);
}if(eventType== YouMeConst.YouMeEvent.YOUME_EVENT_INIT_FAILED){
Log.i("初始化失败:",""+errorCode);
}else{
switch (eventType){
case YouMeConst.YouMeEvent.YOUME_EVENT_JOIN_OK:
api.setMicrophoneMute(false);
api.setSpeakerMute(false);
break;
}
}
}
@Override
public void onRequestRestAPI(int a,int b,String c,String d){
}
@Override
public void onMemberChange(String a, MemberChange[] b,boolean d){
}
@Override
public void onBroadcast(int a,String b,String c,String d,String e){
@Override
public void onDetectNetWorkComplete(boolean networkOK, String result) {}
@Override
public void onAVStatisticNew(int type, String userID, int value, String param) {}
}场景调用流程
调用流程时序图
title:Talk SDK 接口调用流程,具体接口说明参见API接口手册
participant Game Client as A
participant YM Talk SDK as B
A->B:设置回调(SetCallback)
A->B:初始化(init)
B-->A:返回初始化回调结果(在OnEvent里返回)
Note right of A:用户可以用自由说话身份加入频道
A->B:加入频道(joinchannelSingleMode)
A->B:根据业务端逻辑打开麦克风扬声器 \n(SetMicrophoneMute、setSpeakerMute)
Note right of A:上述的回调若都是返回success,则在同一频道内\n的用户就都可以相互通话或收听了
A->B:离开频道(LeaveChannelAll)
核心调用API
初始化流程
| 接口 | 含义 |
|---|---|
api.SetCallback(YouMeCallBackInterface callBack) | 注册回调(event、memberchange等) |
api.init | 引擎初始化,区域参数使用app发版地区对应的区域参数,若需要全球互通,可联系游密相关人员配置开通 |
- 调用示例:
api.SetCallback(this); //设置回调监听对象,需要implement YouMeCallBackInterface
api.init("Appkey", "strAPPSecret", YOUME_RTC_SERVER_REGION.RTC_CN_SERVER, ""); //只有appkey,appsecret,serverRegionId 都一样时,才可以进行语音互通,改任意一个视为另外一个区服;加入/退出房间流程
| 接口 | 含义 |
|---|---|
api.joinChannel | 加入房间,建议 role建议设置为1,bCheckRoomExist 设为 false,单频道模式参数设为 true |
api.leaveChannelAll | 退出所有房间 |
本地设备控制接口
收到加入房间成功JOIN_OK事件后可设置:
| 接口 | 含义 |
|---|---|
api.setMicrophoneMute | 设置麦克风状态 |
api.setSpeakerMute | 设置扬声器状态 |
api.setAutoSendStatus | 设置是否通知别人麦克风和扬声器的开关,设置后用户开关麦克风或者扬声器都会通知到同频道到其他用户 |
api.setUseMobileNetworkEnabled | 设置是否允许使用移动网络 |
api.setReleaseMicWhenMute | 设置当麦克风静音时,是否释放麦克风设备,(需要在初始化成功后,加入房间之前调用) |
通话管理
- 在用户切到后台或者要收听电话时,可调用暂停通话;以便释放麦克风等设备资源的占用,当切换会前台时,可以调用恢复通话接口用于继续通话。
| 接口 | 含义 |
|---|---|
api.pauseChannel | 暂停通话 |
api.resumeChannel | 恢复通话 |
设置回调监听
引擎底层对于耗时操作都采用异步回调的方式,函数调用会立即返回,操作结果java层会同步回调。因此,用户必须实现相关接口并在初始化前通过 api.SetCallback(this) 注册接收回调通知的对象。
使用类需要implements接口YouMeCallBackInterface,并实现该接口下的所有回调函数。回调都在子线程中执行,不能用于更新UI等耗时操作。
- 首先要导入相关的包:
import com.youme.voiceengine.MemberChange;
import com.youme.voiceengine.YouMeCallBackInterface;- 然后implements接口YouMeCallBackInterface,具体实现回调方法:
@Override
public void onEvent(int eventType, int iErrorCode, String roomid, Object param){}
@Override
public void onMemberChange(String channelID, MemberChange[] arrChanges, boolean isUpdate){}
@Override
public void onDetectNetWorkComplete(boolean networkOK, String result) {}
@Override
public void onAVStatisticNew(int type, String userID, int value, String param) {}网络质量检测
实现接口YouMeCallBackInterface里的public void onDetectNetWorkComplete(boolean b, String s);回调函数。回调都在子线程中执行,不能用于更新UI等耗时操作。
- 在需要检测网络质量时,可调用开始检测网络质量接口;当需要终止检测网络质量时,可调用终止检测网络质量接口。
| 接口 | 含义 |
|---|---|
api.detectNetworkQuality(nDetectTime, nOverTime, nInterval, nPackSize); | 开始检测网络质量 |
api.stopDetectNetworkQuality(); | 终止检测网络质量 |
最终的网络质量检测结果会通过public void onDetectNetWorkComplete(boolean b, String s);回调函数返回。如果调用了终止检测网络质量接口将不会通过回调函数返回结果。
建议:客户端最好在开始检测网络质量之前,对网络的连通性进行检查,如果不连通的话就不用进行网络质量检测了。
回调与通话流程
使用实现 YouMeCallBackInterface 的对象,在 init 前通过 api.SetCallback 注册。初始化及进退频道结果由 onEvent 接收;回调中更新 Android UI 时切回主线程。
接入顺序:注册/提供回调对象 → 初始化 → 等待初始化成功 → 加入频道 → 等待进房成功 → 设置麦克风和扬声器 → 请求离房并等待完成 → 反初始化。异步接口返回成功表示请求已受理,最终结果按回调处理;同步查询按实际返回类型读取。
各接口的语法、功能、参数、返回值和异步回调见 API 手册。
