文档导航 Android
本页目录

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

  1. 将AAR文件移至Android工程libs文件夹下(示例代码中 “libs” 目录仅为举例,开发者可根据实际路径填写)
  2. 添加 SDK 引用,进入到 “app” 目录,打开 “build.gradle” 文件。在 “defaultConfig” 节点添加 “ndk” 节点,指定支持的平台类型:
  • Groovy (.gradle)
TEXT
defaultConfig{
        //添加如下设置支持到so库架构
        ndk{
            abiFilters 'armeabi','armeabi-v7a','x86'      //架构可选对应项目需要的
        }
 }
  • Kotlin DSL (.gradle.kts)
TEXT
defaultConfig {
    ndk {
        abiFilters.clear()
        abiFilters += listOf("arm64-v8a")
    }
}
  1. 在 “dependencies” 节点引入 “libs” 下所有的 aar文件:
  • Groovy (.gradle)
TEXT
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'], exclude: [])
}
  • Kotlin DSL (.gradle.kts)
TEXT
dependencies {
    implementation(fileTree("libs") {
        include("*.aar")
    })
}
  1. Android平台的AAR包已默认包含以下配置,解压AAR包可看到AndroidManifest.xml文件,主工程勿重复添加:
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" />
  1. 防止混淆代码:YOUMESDK不需要混淆,如果你的工程有混淆,请在proguard-rules.pro文件中添加如下代码:
JAVA
    -keep class com.youme.**{*;}
    -keepattributes Signature
  1. 设置加载库以及启动相关服务 在入口Activity类先导入package:
JAVA
  	import android.content.Intent;
  	import android.os.Bundle;
  	import com.youme.voiceengine.mgr.YouMeManager;
JAVA
  然后在onCreate方法里添加“YouMeManager.Init”,且需要在“super.onCreate”之前调用,以解决某些设备兼容性问题:
JAVA
  	YouMeManager.Init(this);

  	super.onCreate(savedInstanceState);

语音通话流程图

流程图

语音通话时序图

时序图

语音通话相关代码

初始化

设置回调监听。

JAVA
api.SetCallback(this);

然后implements YouMeCallBackInterface。

JAVA
public class MainActivity extends AppCompatActivity implements YouMeCallBackInterface

重写里面的方法,其中里面的onEvent会得到关于所有Talk相关的回调。

JAVA
// 消息回调接口实现
    @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,其余设置值可查看官网文档-服务器部署地区定义。

JAVA
// 初始化
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定义。

JAVA
api.joinChannel(userID, channelID, userRole, true, bCheckRoomExist);

开关音频设备

onEvent收到加入频道成功消息YouMeEvent.YOUME_EVENT_JOIN_OK后: 打开/关闭麦克风:其中mute为true表示关闭麦克风,false表示开启麦克风。

JAVA
api.setMicrophoneMute(mute);

打开/关闭扬声器:mute 为 true 表示关闭扬声器,false 表示开启扬声器。

JAVA
api.setSpeakerMute(mute);

设置音量(音量范围0-100,建议设置70比较适中)。

JAVA
api.setVolume(70); 

离开频道,反初始化

离开频道。

JAVA
api.leaveChannelAll();

反初始化。

JAVA
api.unInit();

附:部分事件状态码

JAVA
 	@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类。

  1. 打开创建的新New project,在MainActivity.java文件里的示例代码如下:
TEXT
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) {}
}

场景调用流程

调用流程时序图

TEXT
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发版地区对应的区域参数,若需要全球互通,可联系游密相关人员配置开通
  • 调用示例:
JAVA
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等耗时操作。

  • 首先要导入相关的包:
JAVA
  import com.youme.voiceengine.MemberChange;
  import com.youme.voiceengine.YouMeCallBackInterface;
  • 然后implements接口YouMeCallBackInterface,具体实现回调方法:
JAVA
  @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 手册。