前言

最近需要对接语音识别业务,毕竟现在是AI时代,一个产品如果能通过AI能力给用户带来全新的体验,也是很值得尝试的。技术对接上选择的是科大讯飞开放平台,也算是国内最早一批做语音识别的企业了,文档方面都比较全面,对接起来也很方便。

技术基础

开发技术栈为Cordova+Angular+Ionic,这篇分享会介绍如何从头开始创建Cordova插件,并实现科大讯飞Android sdk与App端的数据交互。

Apache Cordova是一个开源的移动开发框架。允许你用标准的web技术——HTML5,CSS3和JavaScript做跨平台开发。 应用在每个平台的具体执行被封装了起来,并依靠符合标准的API绑定去访问每个设备的功能,比如说:传感器、数据、网络状态等。

在继续阅读之前,应该确保你有通过Cordova创建并打包一个简单Hybrid App的经验,感兴趣的童鞋可以到Ionic官网和Cordova官网学习下。

创建Cordova插件

全局安装plugman

plugman用于创建Cordova插件,在项目目录下执行cnpm i -g plugman

创建插件

创建一个插件并添加android平台,并生成package.json,插件名xFeiVoice,插件idcom.qinsilk.xFeiVoice,版本号为0.01

plugman create --name xFeiVoice --plugin_id com.qinsilk.xFeiVoice --plugin_version 0.0.1
cd xFeiVoice
plugman createpackagejson ./
plugman platform add --platform_name android
复制代码

创建成功可以看到对应目录如下

  • src目录存放原生代码,此处为java文件
  • www目录存放js暴露给设备的接口,如下
var exec = require('cordova/exec');exports.coolMethod = function (arg0, success, error) {exec(success, error, 'xFeiVoice', 'coolMethod', [arg0]);
};
复制代码

此时我们做下修改,让参数名跟业务命名更加相关。

var exec = require('cordova/exec');exports.record = function (arg0, success, error) {exec(success, error, 'xFeiVoice', 'record', [arg0]);
};
复制代码

安装插件

执行cordova plugin add xFeiVoice,再执行cordova plugin ls可以查看当前App安装的插件。

此时用Android Studio打开项目,可以看到这个插件已经添加成功。 到这里我们的准备工作就完成了。

对接语音识别

导入sdk

Android sdk可以去科大讯飞开放平台下载。将在官网下载的Android SDK 压缩包中libs目录下所有子文件拷贝至Android工程的libs目录下。如下图所示:

添加权限

在工程 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" />
复制代码

初始化语音识别对象

此处调用的是60秒语音听写功能。excute是在开发插件时,用户的自定义方法,当页面调用插件时系统首先将会运行此方法。

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {this.callbackContext = callbackContext;if (action.equals("record")) {// 初始化语音识别对象SpeechUtility.createUtility(cordova.getActivity(), "appid=yourAppid,force_login=true");// 使用SpeechRecognizer对象,可根据回调消息自定义界面;mIat = SpeechRecognizer.createRecognizer(cordova.getActivity(), mInitListener);// 设置参数setParam();// 监听事件mIat.startListening(mRecognizerListener);return true;}return false;
}
复制代码

初始化监听器

private InitListener mInitListener = new InitListener() {@Overridepublic void onInit(int code) {Log.d(LOG_TAG, "SpeechRecognizer init() code = " + code);if (code != ErrorCode.SUCCESS) {Log.d(LOG_TAG, "初始化失败,错误码:" + code);}}
};
复制代码

设置参数

public void setParam() {// 清空参数mIat.setParameter(SpeechConstant.PARAMS, null);// 设置听写引擎mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);// 设置返回结果格式mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理mIat.setParameter(SpeechConstant.VAD_BOS, "4000");// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音mIat.setParameter(SpeechConstant.VAD_EOS, "1000");// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点mIat.setParameter(SpeechConstant.ASR_PTT, "0");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限// 注:AUDIO_FORMAT参数语记需要更新版本才能生效mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
}
复制代码

识别监听器

private RecognizerListener mRecognizerListener = new RecognizerListener() {@Overridepublic void onVolumeChanged(int volume, byte[] data) {// showTip("当前正在说话,音量大小:" + volume);Log.d(LOG_TAG, "返回音频数据:"+data.length);}@Overridepublic void onResult(final RecognizerResult result, boolean isLast) {//此处有坑,isLast为true时会返回标点符号if (null != result && !isLast) {String text = parseIatResult(result.getResultString());JSONObject obj = new JSONObject();try {obj.put("searchText", text);} catch (JSONException e) {Log.d(LOG_TAG, "This should never happen");}if( null != mIat ){// 退出时释放连接mIat.cancel();mIat.destroy();}getSearchText(obj);} else {Log.d(LOG_TAG, "recognizer result : null");}}@Overridepublic void onEndOfSpeech() {// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入Log.d(LOG_TAG, "结束说话");}@Overridepublic void onBeginOfSpeech() {// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入Log.d(LOG_TAG, "开始说话");}@Overridepublic void onError(SpeechError error) {Log.d(LOG_TAG, "onError Code:"  + error.getErrorCode());}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因// 若使用本地能力,会话id为null}};
复制代码

处理结果并返回App端

// 处理结果
public static String parseIatResult(String json) {StringBuffer ret = new StringBuffer();try {JSONTokener tokener = new JSONTokener(json);JSONObject joResult = new JSONObject(tokener);JSONArray words = joResult.getJSONArray("ws");for (int i = 0; i < words.length(); i++) {// 转写结果词,默认使用第一个结果JSONArray items = words.getJSONObject(i).getJSONArray("cw");JSONObject obj = items.getJSONObject(0);ret.append(obj.getString("w"));}} catch (Exception e) {e.printStackTrace();}return ret.toString();
}
//将结果通过callbackContext返回App端
public void getSearchText(JSONObject obj) {this.callbackContext.success(obj);
}
复制代码

App端调用sdk并监听数据返回

//语音识别
$scope.record = function () {if (window.cordova && window.cordova.plugins) {if(!$scope.recording){//调用sdkcordova.plugins.xFeiVoice.record({}, function (result) {if(result){//返回识别结果$scope.search.goodKey = result.searchText;$scope.openModal();$scope.recording = false;}console.log('success');}, function (result) {console.log('fail');});}else{//$scope.recordMedia.stopRecord();}$scope.recording = !$scope.recording;}
};
复制代码

结语

插件代码我已经上传到github了,有需要的可以clone。走过路过给个star吧~

让你的Hybrid App听懂你的话(Android篇)相关推荐

  1. native app 集成 cocos-2dx-js 3.11 (Android篇)

    接上篇,android的集成相对麻烦一些,其中涉及到修改引擎底层功能,以下只记录一些其过程中关键步骤,有时间在写ndkgdb debug问题定位处理等等填坑过程. 1.添加引擎java部分 2.添加编 ...

  2. 开发Hybrid App的技术选型

    一.前言 如果我们把Hybrid App理解为运行在android或者ios以及其他移动终端设备上的应用,也可以叫做H5 APP,这种开发应用的模式结合web开发技术与Native开发的部分技术,通常 ...

  3. 修图动口不动手,有人把StyleGAN和CLIP组了个CP,能听懂修图指令那种

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要5分钟 Follow小博主,每天更新前沿干货 「求帮忙把背景 P 成五彩斑斓的黑,可以吗?」 有人认为,自然语言将是软件的下一代接口:你有什么 ...

  4. 让机器听懂人话的自然语言处理技术究竟神奇在哪里?

    https://www.toutiao.com/a6680059274095231501/ 一提到"AI"人工智能,很多人脑袋中就会自动冒出"科幻"电影中变幻莫 ...

  5. 人工智能时代,如何让机器狗听懂你说的话?

    [引子]我的专辑<DuerOS 的AI 实战>涵盖了DuerOS应用中较多方向的内容,有点有面,已经有39篇文字,本文是第40篇.四十不惑,如果读者目前还无法掌握DuerOS的应用全貌,或 ...

  6. Hybrid App开发实战

    Hybrid App开发实战 [引言]近年来随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员,技术成熟度,时间,项目需求等一堆的因素.因此,开 ...

  7. 混合开发Hybrid App为何成为热门?

    纵观当前的移动开发,混合开发(Hybird App)的热度日益上升,那么导致这一趋势的是何原因呢? 实际上,除了混合开发,移动端的开发方式还有纯原生(Native App)和网页应用(Web App) ...

  8. Hybrid App 发展史

    目录 1 概述 2 Cordova 平台 3 Web 发展史 3.1 静态网页 3.2 动态网页 3.3 客户端异步交互 3.4 开发效率提速阶段 3.5 移动平台 4 Hybrid App 分类一 ...

  9. AI能听懂你的情绪了,人机交互会变得更好吗?

    作者:小豪来源:脑极体(ID:unity007) 第一次使用手机语音助手的时候,这个令我新奇不已的玩意儿,总是会在我兴冲冲地问一个问题之后,令人失望地回答一句:"我好想听不懂你在说什么--& ...

  10. 「经济理财」32堂你能听懂的理财课

    之前学了一下基金投资课程,作为以后财富管理的积累,可以出门右转看「银行螺丝钉的基金投资课」.但还是觉得应该系统了解一下理财,从小白到理财达人,我需要半年来学习和实践,比较好的是接触到简七理财,结合简七 ...

最新文章

  1. 关于sqlserver和oracle的一点感受
  2. LeetCode 518. 零钱兑换 II(动态规划)
  3. vue2.0 路由不显示router-view
  4. ABS 1.1.0:更多Python和Bash提供最有趣的编程语言
  5. Elasticserch学习之分页
  6. 基于肌电信号(sEMG) 的深度学习手势分类
  7. Python实现重心法
  8. 【论文阅读笔记】Beamforming Optimization for Wireless Network Aided by IRS with Discrete Phase Shifts
  9. 自定义UDF函数:将汉字转换成拼音
  10. 通过R语言实现平稳时间序列的建模--基础(ARMA模型)
  11. 帝国cms插件|支持7.5/7.2 移动同步生成插件|帝国多端访问必备插件
  12. cs1.6 linux,在Ubuntu 8.04下玩CS1.6
  13. 工信部数字电视标准符合性检测中心发布的
  14. 天龙八部TLBB搭建(一)服务器购买及配置
  15. 微信web开发工具如何使用_优秀的设计师和开发人员使用出色的Web开发工具
  16. 搜索android RAM ROM SD区别时找到一篇分析不错的文章
  17. CSS基础 外部样式表 内嵌样式表 行内样式表
  18. EPro-PnP:用于单目物体姿态估计的广义端到端概率 PnP(CVPR 2022)
  19. 计算机一级最新版本,计算机一级掌上通最新版
  20. 2020年全球光伏逆变器市值将超过71亿美元

热门文章

  1. 2、Python_Day_1_作业
  2. 在运行 Red Hat 或 Cent OS 的虚拟机中扩展逻辑卷
  3. silverlight寻奇
  4. 金电容(法拉电容)与可充放电池的相关知识
  5. Linux文本三剑客超详细教程---grep、sed、awk
  6. 43、剑指offer--左旋转字符串
  7. 在Linux下禁用IPv6的方法小结
  8. visual studio 工具的使用
  9. 版本控制系统相关知识
  10. 车牌识别LPR系统系列文章汇总