1、账号准备工作

首先要有一个讯飞的账号啦,为后面申请APPID、APPKey等东西做准备。顺带一提:讯飞对不同认证类型用户开

放的SDK的使用次数是有不同的,详情如下图。

账号申请完成后,需要去你自己的控制台注册你的应用,同时也可以看到你的应用对应的 APPID 等属性,开通的功能,调用量剩余次数等信息。

本文介绍的是Android SDK的接入,这是Android SDK的下载地址,可以根据项目的具体需求具体分析。

2、SDK集成准备工作

如果参照官方文档中或者官方DEMO的做法,需要把对应架构的文件拷贝到 Android工程的libs目录下 。

而官方提供的DEMO中,它只拷贝了armeabi-v7a架构。如下图所示(我信了它的邪,在我第一次接入时,就因为参考了官方DEMO只导入了armeabi-v7a架构,导致出了一大堆毛病?)

为了避免这个坑,我的建议是:把提供的架构都拷贝到工程里。(有特殊设备需求的除外)

然后在build.gradle文件中,添加SDK的依赖

    implementation files('libs/Msc.jar')

如果将SDK导入到lib文件夹后,可能还会有无法识别的错误。

可以试下在build.gradle(app)中注释掉以下的代码(玄学操作~~),再继续排查。

//        ndk {
// //选择要添加的对应cpu类型的.so库。
// abiFilters 'armeabi-v7a', 'armeabi'
// } // sourceSets {
// main{
// jniLibs.srcDirs = ['libs']
// }
// }

3、在 AndroidManifest.xml 文件 添加所需权限

静态添加权限部分,参考了官方文档的说法。

<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

不过,静态申请了权限,还不够哦。对于现在的手机,很大部分都已经是Android版本678910的了,应用是需要动态申请权限的,得让用户确认同意了,APP才可以使用这些权限。

动态申请权限的方法有很多,也有很多开源的项目,这里就不做介绍了。

4、SDK初始化

SDK初始化建议放在程序入口处(如Application、Activity的onCreate方法),非常简单,就一行语句。

初始化代码如下:

//将“1234567”替换成您申请的APPID
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=1234567");

注意:SpeechConstant.APPID +"=1234567" 采用的是拼接的方式,所以不可以在“=”与appid之间添加任何空字符或者转义符。

5、调用语音听写功能

最重要的来了,前面铺垫这么久,就是为了能调用它的语音听写啊。

离线听写方式,需要购买且下载特定的离线识别SDK,故这里使用的是在线听写。

在线听写的SDK,提供了两种识别方式,分别是带语音对话框识别和无UI识别。

一.无UI识别

//初始化识别无UI识别对象
//使用SpeechRecognizer对象,可根据回调消息自定义界面--自己的语音识别UI
mIat = SpeechRecognizer.createRecognizer(IatDemo.this, mInitListener); //设置语法ID和 SUBJECT 为空,以免因之前有语法调用而设置了此参数;或直接清空所有参数,具体可参考 DEMO 的示例。
mIat.setParameter( SpeechConstant.CLOUD_GRAMMAR, null );
mIat.setParameter( SpeechConstant.SUBJECT, null );
//设置返回结果格式,目前支持json,xml以及plain 三种格式,其中plain为纯听写文本内容
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//此处engineType为“cloud”
mIat.setParameter( SpeechConstant.ENGINE_TYPE, engineType );
//设置语音输入语言,zh_cn为简体中文
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//设置结果返回语言
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
// 设置语音前端点:静音超时时间,单位ms,即用户多长时间不说话则当做超时处理
//取值范围{1000~10000}
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
//设置语音后端点:后端点静音检测时间,单位ms,即用户停止说话多长时间内即认为不再输入,
//自动停止录音,范围{0~10000}
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
//设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT,"1");
//开始识别,并设置监听器
mIat.startListening(mRecogListener);

二.带语音对话框识别(SDK自带)

// 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
// 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
mIatDialog = new RecognizerDialog(IatDemo.this, mInitListener); //以下为dialog设置听写参数
mIatDialog.setParameter(SpeechConstant.RESULT_TYPE, "json");
//设置语音输入语言,zh_cn为简体中文
mIatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//设置结果返回语言
mIatDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
// 设置语音前端点:静音超时时间,单位ms,即用户多长时间不说话则当做超时处理
//取值范围{1000~10000}
mIatDialog.setParameter(SpeechConstant.VAD_BOS, "4500");
//设置语音后端点:后端点静音检测时间,单位ms,即用户停止说话多长时间内即认为不再输入,
//自动停止录音,范围{0~10000}
mIatDialog.setParameter(SpeechConstant.VAD_EOS, "1500");
//开始识别并设置监听器
mIatDialog.setListener(mRecognizerDialogListener); //开始识别并设置语音UI监听器
mIatDialog.setListener(mRecognizerDialogListener);
//显示听写对话框,show方法实际是内部调用无UI识别方式
mIatDialog.show();

重点来了,也是很多人很困扰的一步,官方文档的说法是使用这个SDK自带的语音识别对话框,需要把对应的布局文件和图片资源放入工程中。然而,很多人这样做了之后, mIatDialog.show(); 调用了还是会出现空指针的异常。。例如:?

java.lang.NullPointerException
at com.iflytek.cloud.ui.a.a(Unknown Source)
at com.iflytek.cloud.ui.RecognizerDialog.setParameter(Unknown Source)
atcom.example.mediaplayer.activity.SearchActivity.setParam(SearchActivity.java:111)
at com.example.mediaplayer.activity.SearchActivity.onClick(SearchActivity.java:86)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)

解决方法,如下:

首先,在asset文件内,放入所需的资源。注意:asset文件夹的位置,是要在src/main/ 的下一级,然后在与

asset文件夹同级的地方创建 jniLibs 文件夹,把 libs/文件夹的对应SDK文件拷贝到 jniLibs 中,如图:

同时检查下,SDK初始化的 APPId 有无出错的可能。

获取数据

解决了空指针的问题后,接下来调用 show 方法,就可以在自定义的监听器里愉快地获取到返回的听写数据了

 //创建语音识别UI对话框
mIatDialog = new RecognizerDialog(getActivity(), searchViewModel.mInitListener); /**
* 初始化听写事件监听器。
*/
public InitListener mInitListener = new InitListener() { @Override
public void onInit(int code) {
if (code != ErrorCode.SUCCESS) {
//Todo
}
}
};
/**
* 听写UI监听器 讯飞
*/
public RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() { /**
* 接收语音听写回调信息
* @param recognizerResult 回调结果
* @param b 是否翻译
*/
@Override
public void onResult(com.iflytek.cloud.RecognizerResult recognizerResult, boolean b) {
//返回的数据
String data = recognizerResult.getResultString();
}
/**
* 识别回调错误.
*/
public void onError(SpeechError error) {
if(error.getErrorCode() == 14002) {
//Todo
} else {
//Todo
}
} };

修改默认对话框的文字

//动态更换了讯飞自带对话框的底部文字,必须在dialog的show执行后更换,否则空指针报错
TextView recorderDialogTextView = (TextView) mIatDialog.getWindow().getDecorView().findViewWithTag("textlink"); recorderDialogTextView.setText(R.string.recorder_dialog_textview_text);

返回的听写数据实例,用于创建实体类:

{
"sn": 1,
"ls": true,
"bg": 0,
"ed": 0,
"ws": [
{
"bg": 0,
"cw": [
{
"w": "今天",
"sc": 0
}
]
},
{
"bg": 0,
"cw": [
{
"w": "的",
"sc": 0
}
]
},
{
"bg": 0,
"cw": [
{
"w": "天气",
"sc": 0
}
]
},
{
"bg": 0,
"cw": [
{
"w": "怎么样",
"sc": 0
}
]
},
{
"bg": 0,
"cw": [
{
"w": "。",
"sc": 0
}
]
}
]
}

注意:若在SDK中开通了 动态修正的功能,返回的数据会出现格式不一致的情况。官方的说法如下:

动态修正:
  • 未开启动态修正:实时返回识别结果,每次返回的结果都是对之前结果的追加;
  • 开启动态修正:实时返回识别结果,每次返回的结果有可能是对之前结果的的追加,也有可能是要替换之前某次返回的结果(即修正);
  • 开启动态修正,相较于未开启,返回结果的颗粒度更小,视觉冲击效果更佳;
  • 使用动态修正功能需到控制台-流式听写-高级功能处点击开通,并设置相应参数方可使用,参数设置方法:mIat.setParameter(“dwa”, “wpgs”); ;
  • 动态修正功能仅 中文 支持;
  • 未开启与开启返回的结果格式不同,详见下方;

若开通了动态修正功能并设置了dwa=wpgs(仅中文支持),会有如下字段返回:

参数 类型 描述
pgs string 开启wpgs会有此字段 取值为 “apd"时表示该片结果是追加到前面的最终结果;取值为"rpl” 时表示替换前面的部分结果,替换范围为rg字段
rg array 替换范围,开启wpgs会有此字段 假设值为[2,5],则代表要替换的是第2次到第5次返回的结果

PS:一般项目中的语音听写需求,完全可以不使用动态修正功能,但若要使用同步显示语音识别结果或者比较需要比较精准的结果,可以考虑使用此功能。

总结

讯飞语音听写SDK,坑点不少,但是都不是很难,还是适项目快速接入语音听写需求的。。?

如果要更多操作和功能,请参考讯飞语音听写SDK官方文档

Android 讯飞语音听写SDK快速接入(附空指针解决和修改对话框文字方法)的更多相关文章

  1. Android讯飞语音云语音听写学习

    讯飞语音云语音听写学习         这几天两个舍友都买了iPhone 6S,玩起了"Hey, Siri",我依旧对我的Nexus 5喊着"OK,Google" ...

  2. android讯飞语音开发常遇到的问题

    场景:android项目中共使用了3个语音组件:在线语音听写.离线语音合成.离线语音识别 11208:遇到这个错误,授权应用失败,先检查装机量(3台测试权限),以及appid的申请时间(35天期限), ...

  3. 讯飞语音唤醒SDK集成流程

    唤醒功能,顾名思义,通过语音,唤醒服务,做我们想做的事情. 效果图(开启应用后说讯飞语音或者讯飞语点唤醒) 源码下载 地址:http://download.csdn.net/detail/q48788 ...

  4. Android 讯飞语音之语音合成(在线有声朗读)

    原文:http://www.cnblogs.com/scetopcsa/p/3845427.html 在线语音合成的使用方法: 首先下载相关的sdk,这个网址里有多种版本,我选择的Android. h ...

  5. Android自带语音播报+讯飞语音播报封装(直接用)

    一.Android自带的语音播报 1.查看是否支持中文,在测试的设备中打开‘设置’ -->找到 '语言和输入法'-->查看语音选项,是否支持中文,默认仅支持英文. 使用如下: public ...

  6. cocos2dx实现android的对讯飞语音的合成(语言朗读的实现)

    事实上非常easy,只是有些细节须要注意. 关于讯飞语音在android上的应用,大家须要自己去下载SDK,然后依照讯飞语音提供的api在自己的android的Demo上执行成功,那东西也相当的简单. ...

  7. 关于讯飞语音SDK开发学习

    前奏,浑浑噩噩已经工作一年多,这一年多收获还是挺多的.逛园子应该有两年多了,工作后基本上是天天都会来园子逛逛,园子 里还是有很多牛人写了一些不错的博客,帮我解决很多问题.但是一直没写过博客,归根到底一 ...

  8. 继《关于讯飞语音SDK开发学习》之打包过程中遇到小问题

    关于讯飞语音SDK开发学习 使用vs自带打包,具体怎么操作就不说了,网上关于这方面的资料挺多的.例如:winform 打包部署,VS2010程序打包操作(超详细的),关键是桌面上创建快捷方式中的&qu ...

  9. UNITY 接讯飞语音过程总结

    11:13 2017/3/141,安装问题:JDK与ECLIPSE位数一定要对应,32位对64位会出现 java was returned ....code 13的弹框错误.版本号可以不一致.2,EC ...

随机推荐

  1. 28.1 api-- Object(toString equals)

    /* * String toString() : 返回该对象的字符串表示 * return getClass().getName() + "@" + Integer.toHexSt ...

  2. Spring Data REST不完全指南(一)

    简介 Spring Data REST是Spring Data项目的一部分,可轻松在Spring Data存储库上构建超媒体驱动的REST Web服务. Spring Data REST 构建在 Sp ...

  3. 实验一 熟悉IDLE和在线编程平台

    实验目的 1.掌握python IDLE集成开发环境的安装与使用 2.熟悉在线编程平台 3.掌握基本的python程序编写.编译与运行程序的方法 实验内容 1.按照实验指导安装IDLE,尝试交互式运行 ...

  4. linux CVE-2019-13272 本地特权漏洞

    漏洞描述 在5.1.17之前的Linux内核中,kernel / ptrace.c中的ptrace_link错误地处理了想要创建ptrace关系的进程的凭据记录,这允许本地用户通过利用父子的某些方案来 ...

  5. [php] phpStudy+XDebug配置

    一.配置前说明: 1.phpStudy集成了XDebug扩展,所以不用单独下载XDebug. 2.打开XDebug扩展:其它选项菜单 > PHP扩展 > Xdebug 二.配置步骤: ph ...

  6. Springboot:员工管理之首页(十(2))

    访问首页可以通过两种方式: 1:编写controller 2:自定义扩展视图解析器(推荐使用) 1:编写Controller com\springboot\controller\IndexContro ...

  7. Linux-Discuz安装LAMP

    1.下载,解压Discuz cd /data/discuz wget http://download.comsenz.com/DiscuzX/3.2/Discuz_X3.2_SC_GBK.zip un ...

  8. mybatis源码学习:基于动态代理实现查询全过程

    前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...

  9. share sdk

    新浪微博                 http://open.weibo.com 腾讯微博                 http://dev.t.qq.com QQ空间             ...

  10. c++动态数组的使用

    在c++中,有的时候会遇到变长的数组(不管是一维的还是二维的),这个时候就需要用到动态数组了,并且要用new和delete两个操作符,这俩操作符一般成对使用. 先说一维的动态数组吧,直接上代码 #in ...