添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Android SDK

Android SDK

本文介绍了如何使用阿里云智能语音服务提供的 Android NUI SDK,包括 SDK 下载安装、关键接口及代码示例。

前提条件

下载安装

  1. 下载 SDK。

    重要

    请下载后在样例初始化代码中替换您的阿里云账号信息、Appkey Token 才可运行。

    对象

    说明

    SDK 名称

    智能语音交互移动端 SDK

    开发者

    阿里云计算有限公司

    SDK 版本

    2.6.3-01B

    SDK 包名

    com.alibaba.idst.nui

    SDK 更新时间

    2024-12-19

    SDK 大小

    MinSizeRel/nuisdk-release.aar

    7.2MB

    RelWithDebugInfo/nuisdk-release.aar

    9.7MB

    SDK MD5

    MinSizeRel/nuisdk-release.aar

    c8e84d882a776797179b07cb55325a17

    RelWithDebugInfo/nuisdk-release.aar

    3bd1e2c2423c23e6522b7bc3ac072ec9

    隐私政策

    智能语音交互产品隐私政策

    合规配置说明

    智能语音交互 SDK 合规配置指引(安卓)

    SDK 整合包下载

    下载 Android SDK

    类别

    兼容范围

    系统

    支持 Android 4.0 以上版本,API LEVEL 14

    架构

    armeabi-v7a,arm64-v8a ,x86,x86_64

    SDK 还包含如下功能,若未支持您想要的功能,请前往对应文档获取 SDK。

    功能

    是否支持

    一句话识别

    实时语音识别

    语音合成

    实时长文本语音合成

    流式文本语音合成

    离线语音合成

    录音文件识别极速版

    唤醒及命令词

    听悟实时推流

  2. 解压 ZIP 包,在 app/libs 目录下获取 AAR 格式的 SDK 包,将 AAR 包集成到您的工程项目中进行依赖。如果需要 Android CPP 接入方式,可在 ZIP 包的 android_libs android_include 中获得动态库和头文件。

  3. 使用 Android Studio 打开此工程查看参考代码实现,其中实时语音识别示例代码为 SpeechTranscriberActivity.java 文件,替换 Appkey Token 后可直接运行。

SDK 关键接口

  • initialize: 初始化 SDK。

    /**
     * 初始化SDK,SDK为单例,请先释放后再次进行初始化。请勿在UI线程调用,可能会引起阻塞。
     * @param callback:事件监听回调,参见下文具体回调。
     * @param parameters:json string形式的初始化参数,参见下方说明或接口说明:https://help.aliyun.com/document_detail/173528.html。
     * @param level:log打印级别,值越小打印越多。
     * @param save_log:是否保存log为文件,存储目录为ticket中的debug_path字段值。注意,log文件无上限,请注意持续存储导致磁盘存满。
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int initialize(final INativeNuiCallback callback,
                                       String parameters,
                                       final Constants.LogLevel level,
                                       final boolean save_log)

    其中,INativeNuiCallback 类型包含如下回调。

    • onNuiAudioStateChanged :根据音频状态进行录音功能的开关。

      /**
       * 当start/stop/cancel等接口调用时,SDK通过此回调通知App进行录音的开关操作。
       * @param state:录音需要的状态(打开/关闭)
      void onNuiAudioStateChanged(AudioState state);
    • onNuiNeedAudioData :在回调中提供音频数据。

      /**
       * 开始识别时,此回调被连续调用,App需要在回调中进行语音数据填充。
       * @param buffer:填充语音的存储区。
       * @param len:需要填充语音的字节数。
       * @return:实际填充的字节数。
      int onNuiNeedAudioData(byte[] buffer, int len);
    • onNuiEventCallback :SDK 事件回调。

      /**
       * SDK主要事件回调
       * @param event:回调事件,参见如下事件列表。
       * @param resultCode:参见错误码,在出现EVENT_ASR_ERROR事件时有效。
       * @param arg2:保留参数。
       * @param kwsResult:语音唤醒功能(暂不支持)。
       * @param asrResult:语音识别结果。
      void onNuiEventCallback(NuiEvent event, final int resultCode, final int arg2, KwsResult kwsResult, AsrResult asrResult);
    • onNuiAudioRMSChanged:音频能量值回调。

      /**
       * 音频能量值回调
       * @param val: 音频数据能量值回调,范围-1600,一般用于UI展示语音动效
      public void onNuiAudioRMSChanged(float val);

      事件列表:

      名称

      说明

      EVENT_VAD_START

      检测到人声起点。

      EVENT_VAD_END

      检测到人声尾点。

      EVENT_ASR_PARTIAL_RESULT

      语音识别中间结果。

      EVENT_ASR_ERROR

      根据错误码信息判断出错原因。

      EVENT_MIC_ERROR

      录音错误 ,表示 SDK 连续 2 秒未收到任何音频,可检查录音系统是否正常。

      EVENT_SENTENCE_START

      实时语音识别事件,表示检测到一句话开始。

      EVENT_SENTENCE_END

      实时语音识别事件,表示检测到一句话结束,返回一句完整的结果。

      EVENT_SENTENCE_SEMANTICS

      暂不使用。

      EVENT_TRANSCRIBER_COMPLETE

      停止语音识别后最终事件。

  • setParams :以 JSON 格式设置 SDK 参数。

    /**
     * 以JSON格式设置参数
     * @param params:参见接口说明:https://help.aliyun.com/document_detail/173528.html。
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int setParams(String params);
  • startDialog :开始识别。

    /**
     * 开始识别
     * @param vad_mode:多种模式,对于识别场景,请使用P2T。
     * @param dialog_params:json string形式的对话参数,参见接口说明:https://help.aliyun.com/document_detail/173528.html。
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int startDialog(VadMode vad_mode, String dialog_params);
  • stopDialog :结束识别。

    /**
     * 结束识别,调用该接口后,服务端将返回最终识别结果并结束任务。
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int stopDialog();
  • cancelDialog :立即结束识别。

    /**
     * 立即结束识别,调用该接口后,不等待服务端返回最终识别结果就立即结束任务。
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int cancelDialog();
  • release :释放 SDK。

    /**
     * 释放SDK资源
     * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。
    public synchronized int release();
  • GetVersion :获得当前 SDK 版本信息。

    /**
     * 获得当前SDK版本信息
     * @return: 字符串形式的SDK版本信息
    public synchronized String GetVersion();

调用步骤

  1. 初始化 SDK、录音实例。

  2. 根据业务需求设置参数。

  3. 调用 startDialog 开始识别。

  4. 根据音频状态回调 onNuiAudioStateChanged,打开录音机。

  5. onNuiNeedAudioData 回调中提供录音数据。

  6. EVENT_SENTENCE_START 事件回调中表示当前开始识别一个句子,在 EVENT_ASR_PARTIAL_RESULT 事件回调中获取识别中间结果,在 EVENT_SENTENCE_END 事件回调中获得这句话完整的识别结果和各相关信息。

  7. 调用 stopDialog 结束识别。 并从 EVENT_TRANSCRIBER_COMPLETE 事件回调确认已停止识别。

  8. 结束调用,使用 release 接口释放 SDK 资源。

Proguard 配置

如果代码使用了混淆,请在 proguard-rules.pro 中配置:

-keep class com.alibaba.idst.nui.*{*;}

代码示例

说明

您如果有多例需求,也可以直接 new 对象进行使用。也可采用 GetInstance 获得单例。

NUI SDK 初始化

//这里获得资源路径, 即工作路径
//  内部通过context.getApplicationContext().getFilesDir().toString() + "/asr_my" 创建工作路径,
//  例如 /data/user/0/mit.alibaba.nuidemo/files/asr_my
String workspace = CommonUtils.getModelPath(this);
//创建debug路径
String debug_path = getExternalCacheDir().getAbsolutePath() + "/debug_" + System.currentTimeMillis();
Utils.createDir(debug_path);
//从nuisdk.aar中assets资源拷贝到workspace中
CommonUtils.copyAssetsData(this);
//初始化SDK,注意用户需要在genInitParams中填入相关ID信息才可以使用。
NativeNui nui_instance = new NativeNui();
int ret = nui_instance.initialize(this, genInitParams(asset_path,debug_path), Constants.LogLevel.LOG_LEVEL_VERBOSE, true);

其中,genInitParams 生成为 String JSON 字符串,包含资源目录和用户信息。其中用户信息包含如下字段。

private String genInitParams(String workpath, String debugpath) {
    String str = "";
        //获取账号访问凭证:
        //  getTicket为示例工程中提供了多种可能的方式,请选择适合自身业务的安全方式
        //注意:
        //  语音交互服务需要先准备好账号,并开通相关服务。具体步骤请查看:
        //    https://help.aliyun.com/zh/isi/getting-started/start-here
        //原始账号:
        //  账号(子账号)信息主要包括AccessKey ID(后续简称为ak_id)和AccessKey Secret(后续简称为ak_secret)。
        //  此账号信息一定不可存储在app代码中或移动端侧,以防账号信息泄露造成资费损失。
        //STS临时凭证:
        //  由于账号信息下发给客户端存在泄露的可能,阿里云提供的一种临时访问权限管理服务STS(Security Token Service)。
        //  STS是由账号信息ak_id和ak_secret,通过请求生成临时的sts_ak_id/sts_ak_secret/sts_token
        //  (为了区别原始账号信息和STS临时凭证, 命名前缀sts_表示STS生成的临时凭证信息)
        //什么是STS:https://help.aliyun.com/zh/ram/product-overview/what-is-sts
        //STS SDK概览:https://help.aliyun.com/zh/ram/developer-reference/sts-sdk-overview
        //STS Python SDK调用示例:https://help.aliyun.com/zh/ram/developer-reference/use-the-sts-openapi-example
        //账号需求说明:
        //  若使用离线功能(离线语音合成、唤醒), 则必须app_key、ak_id和ak_secret,或app_key、sts_ak_id、sts_ak_secret和sts_token
        //  若使用在线功能(语音合成、实时转写、一句话识别、录音文件转写等), 则只需app_key和token
        JSONObject object = Auth.getTicket(Auth.GetTicketMethod.GET_TOKEN_FROM_SERVER_FOR_ONLINE_FEATURES);
        if (!object.containsKey("token")) {
            Log.e(TAG, "Cannot get token!!!");
        object.put("device_id", Utils.getDeviceId()); // 必填, 推荐填入具有唯一性的id, 方便定位问题
        object.put("url", "wss://nls-gateway.cn-shanghai.aliyuncs.com:443/ws/v1"); // 默认
        object.put("workspace", workpath); // 必填, 且需要有读写权限
        //当初始化SDK时的save_log参数取值为true时,该参数生效。表示是否保存音频debug,该数据保存在debug目录中,需要确保debug_path有效可写。
        //object.put("save_wav", "true");
        //debug目录,当初始化SDK时的save_log参数取值为true时,该目录用于保存中间音频文件。
        object.put("debug_path", debugpath);
        object.put("service_mode", Constants.ModeFullCloud); // 必填
        str = object.toString();
    } catch (JSONException e) {
        e.printStackTrace();
    Log.i(TAG, "InsideUserContext:" + str);
    return str;
}

参数设置

JSON 字符串形式进行设置。

//设置相关识别参数,具体参考API文档
//  initialize()之后startDialog之前调用
nui_instance.setParams(genParams());
private String genParams() {
    String params = "";
    try {
        JSONObject nls_config = new JSONObject();
        nls_config.put("enable_intermediate_result", true);
        // 参数可根据实际业务进行配置
        // 接口说明可见https://help.aliyun.com/document_detail/173528.html
        // 查看 2.开始识别
        // nls_config.put("enable_punctuation_prediction", true);
        // nls_config.put("enable_inverse_text_normalization", true);
        // nls_config.put("max_sentence_silence", 800);
        // nls_config.put("enable_words", false);
        // nls_config.put("sample_rate", 16000);
        // nls_config.put("sr_format", "opus");
        /*若文档中不包含某些参数,但是此功能支持这个参数,可以用如下万能接口设置参数*/
        // JSONObject extend_config = new JSONObject();
        // extend_config.put("custom_test", true);
        // nls_config.put("extend_config", extend_config);
        JSONObject parameters = new JSONObject();
        parameters.put("nls_config", nls_config);
        parameters.put("service_type", Constants.kServiceTypeSpeechTranscriber); // 必填
        //如果有HttpDns则可进行设置
        //parameters.put("direct_ip", Utils.getDirectIp());
        params = parameters.toString();
    } catch (JSONException e) {
        e.printStackTrace();
    return params;
}

开始识别

通过 startDialog 接口开启监听。

nui_instance.startDialog(Constants.VadMode.TYPE_P2T, genDialogParams());
private String genDialogParams() {
    String params = "";
    try {
        JSONObject dialog_param = new JSONObject();
        //运行过程中可以在startDialog时更新参数,尤其是更新过期token
        //dialog_param.put("token", "");
        params = dialog_param.toString();
    } catch (JSONException e) {
        e.printStackTrace();
    return params;
}

回调处理

  • onNuiAudioStateChanged :录音状态回调,SDK 内部维护录音状态,根据该状态的回调进行录音机的开关操作。

    public void onNuiAudioStateChanged(Constants.AudioState state) {
        Log.i(TAG, "onNuiAudioStateChanged");
        if (state == Constants.AudioState.STATE_OPEN) {
            Log.i(TAG, "audio recorder start");
            mAudioRecorder.startRecording();
        } else if (state == Constants.AudioState.STATE_CLOSE) {
            Log.i(TAG, "audio recorder close");
            mAudioRecorder.release();
        } else if (state == Constants.AudioState.STATE_PAUSE) {
            Log.i(TAG, "audio recorder pause");
            mAudioRecorder.stop();
    }
  • onNuiNeedAudioData :录音数据回调,在该回调中填充录音数据。

    public int onNuiNeedAudioData(byte[] buffer, int len) {
        int ret = 0;
        if (mAudioRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
            Log.e(TAG, "audio recorder not init");
            return -1;
        ret = mAudioRecorder.read(buffer, 0, len);
        //返回值告知SDK读到了多少数据。
        //如果返回<0,则表示出错。
        //返回0,则表示无录音数据,连续2s返回0,会触发事件EVENT_MIC_ERROR。
        return ret;
    }
  • onNuiEventCallback :NUI SDK 事件回调,请勿在事件回调中调用 SDK 的接口,可能引起死锁。

    public void onNuiEventCallback(Constants.NuiEvent event, final int resultCode, final int arg2, KwsResult kwsResult, AsrResult asrResult) {
        Log.i(TAG, "event=" + event + " resultCode=" + resultCode);
        // asrResult包含task_id,task_id有助于排查问题,请用户进行记录保存。
        // 新版本新增asrResult.allResponse,若为非nullptr和非空,则给出json格式字符串的完整信息。
        if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
          // 实时识别结束
        } else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
          // 例如展示当前句子的识别中间结果
          showText(asrView, asrResult.asrResult);
        } else if (event == Constants.NuiEvent.EVENT_SENTENCE_END) {
          // 例如展示当前句子的完整识别结果
          showText(asrView, asrResult.asrResult);
        } else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) {
          // asrResultEVENT_ASR_ERROR中为错误信息,搭配错误码resultCode和其中的task_id更易排查问题,请用户进行记录保存。
        } else if (event == Constants.NuiEvent.EVENT_MIC_ERROR) {
          // EVENT_MIC_ERROR表示2s未传入音频数据,请检查录音相关代码、权限或录音模块是否被其他应用占用。
        } else if (event == Constants.NuiEvent.EVENT_DIALOG_EX) { /* unused */
          // 此事件可不用关注
    }

结束识别

nui_instance.stopDialog();

释放 SDK

nui_instance.release();

常见问题

新版 Android SDK 实时语音识别,管控台模型选择 8K,但是 Demo 中为什么将采样率设置成 16K 才能识别正确?

建议您将该参数值 nls_config.put("sr_format", "pcm") 配置成小写,在代码中确认 public final static int SAMPLE_RATE = 8000 ,模型选择是 8K。

使用 onNuiNeedAudioData 录音数据回调,在该回调中填充录音数据“ret = audioRecord.read(buffer, 0, len);” 实时录音转写过程中突然断网再联网,录音 SDK 会自动连接然后继续转写吗?

断网后需要重新连接录音 SDK,不会自动连接,需要您增加一些重试机制。

实时音频识别对安卓版本有要求吗?

没有具体要求,最新的 SDK 兼容最新版本。

Android SDK 是否可以上传 OPUS 音频数据,实现实时语音转文字?

ASR 中一句话识别和录音文件极速版支持 OPUS 数据,实时语音转文字仅支持 PCM 编码、16 bit 采样位数、单声道(mono)。具体详情请参见 接口说明

调用 Android SDK 时,手机报错提示“audio recoder not init”如何解决?

您可以通过以下方式排查:

  • 检查 AudioRecord 是否初始化正常。

  • 检查语音播放器是否有问题。

  • 系统的录音模块代码如下,也可单独编写 AudioRecord 录音代码,测试是否正常。 编写AudioRecord录音代码

int ret = nui_instance.initialize(this, genInitParams(assets_path,debug_path), Constants.LogLevel.LOG_LEVEL_VERBOSE, true)。录音权限已打开,但代码仍然报错 240021 是什么原因?

240021 表示 FILE_ACCESS_FAIL 文件访问错误。请完成以下操作:

  • 检查是否有文件读写权限。

  • 检查是否完成 SDK 调用、是否完成 SDK 配置文件的拷贝。

if (CommonUtils.copyAssetsData(this)) {
Log.i(TAG, "copy assets data done");
} else {
Log.i(TAG, "copy assets failed");
return;