demo下载地址:https://fir.im/jy28
demo源码查看:https://github.com/wapchief/android-CollectionDemo
效果图:android
选这几个平台的主要也是从多方面考虑。
大概从这几个git
目前只有百度的语音服务支持长语音(60秒以上),和离线语音识别。
固然语音的库(.so)文件也是最大的。足足10多M。github
在集成以前,须要去相应的平台去申请应用。
拿到key等密钥。目前这几个平台都在测试免费层限制中。json
百度是彻底免费,讯飞有免费层日调用次数限制。网络
首先去各大平台下载对于的语音文件库
通常都包含.so和libs两部分。这两部分都须要加入到项目中。架构
不过这里只须要注意一点是,每一个平台的文档不同,有些是使用libs集成第三方库,有些是使用jnilibs加载。app
若是都按照第三方文档来集成,一定会出错。
这里统一使用jniLibs来集成(只适用于AndroidStudio)。若是是eclipse,则须要使用libs集成eclipse
若是在集成中遇到了问题,能够参考我之前写过的解决方案
Android关于libs,jniLibs库的基本使用说明及冲突解决ide
一、(必须)将下载后的全部so库文件(以.so结尾的文件)拷贝至项目下/app/src/main目录,若是没有则建立一个,里面的名字是固定的,注意不能修改,必须按照这样的架构目录集成。测试
二、(必须)将jar文件拷贝到libs目录中
image.png
而后将jar添加到项目。
可使用右键对应的jar包,add-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" />
若是SDK版本在6.0以上须要在项目中手动获取录音权限
/*动态权限申请*/ private void initPermission() { String permission[] = {Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE}; ArrayList<String> applyList = new ArrayList<>(); for (String per : permission) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, per)) { applyList.add(per); } } String tmpList[] = new String[applyList.size()]; if (!applyList.isEmpty()) { ActivityCompat.requestPermissions(this, applyList.toArray(tmpList), 123); } }
各个平台的初始化方法都不同。
但大多数都是在本身项目的Application中初始化。
//初始化讯飞语音 SpeechUtility.createUtility(mContext, SpeechConstant.APPID +"=59daecea," + SpeechConstant.FORCE_LOGIN +"=true"); //讯飞调试日志开启 Setting.setShowLog(true); //初始化阿里语音 NlsClient.openLog(true); NlsClient.configure(mContext);
有些是在AndroidManifest.xml中初始化
<!--******************************百度语音**********************************--> <meta-data android:name="com.baidu.speech.APP_ID" android:value="8172882" /> <meta-data android:name="com.baidu.speech.API_KEY" android:value="R3crsZhvpqQSrLGUvG7kuG0pCnpTbXvb" /> <meta-data android:name="com.baidu.speech.SECRET_KEY" android:value="6MafqZkSLoNYUML1YduHPDYBg1kkPLHj" /> <service android:name="com.baidu.speech.VoiceRecognitionService" android:exported="false"/>
以讯飞为例:
在开始识别前须要初始化识别对象,
SpeechRecognizer recognizer = SpeechRecognizer.createRecognizer(this, null);
而后配置听写参数
/** * 参数设置 */ public void setParam() { //2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类 recognizer.setParameter(SpeechConstant.DOMAIN, "iat"); recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); recognizer.setParameter(SpeechConstant.ACCENT, "mandarin "); //设置音频保存路径 recognizer.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); recognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav"); }
开始识别的开始和终止,及识别过程的内容回调
//开启 private void startXF() { setParam(); recognizer.startListening(recognizerListener); } //中止 private void stopXF() { recognizer.stopListening(); } /*监听*/ private RecognizerListener recognizerListener = new RecognizerListener() { @Override public void onVolumeChanged(int i, byte[] bytes) { //音量变化 } @Override public void onBeginOfSpeech() { //开始说话 Log.e(TAG, "XF开始说话"); } @Override public void onEndOfSpeech() { //结束说话 Log.e(TAG, "XF结束说话"); } @Override public void onResult(RecognizerResult recognizerResult, boolean b) { //返回结果须要判断null text = JsonParser.parseIatResult(recognizerResult.getResultString()); Log.e(TAG, "XFResult:" + text + "\n" + recognizerResult.getResultString()); mVoiceTv.setText(recognizerResult.getResultString()); printResult(recognizerResult); } @Override public void onError(SpeechError speechError) { //错误回调 Log.e(TAG, "XFError:" + speechError.toString()); } @Override public void onEvent(int i, int i1, int i2, Bundle bundle) { //事件拓展 } };
解析语音识别的结果。
//储存听写结果 private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>(); /*解析器*/ private void printResult(RecognizerResult results) { String text = JsonParser.parseIatResult(results.getResultString()); String sn = null; // 读取json结果中的sn字段 try { JSONObject resultJson = new JSONObject(results.getResultString()); sn = resultJson.optString("sn"); } catch (JSONException e) { e.printStackTrace(); } mIatResults.put(sn, text); StringBuffer resultBuffer = new StringBuffer(); for (String key : mIatResults.keySet()) { resultBuffer.append(mIatResults.get(key)); } mVoiceEt.setText("讯飞识别结果:" + resultBuffer.toString()); mVoiceEt.setSelection(mVoiceEt.length()); // mVoiceTv.setText(resultBuffer.toString()); }
SecurityException异常:
若是是在6.0以上版本的sdk可能会出现该问题,主要是临时权限调用,好比调用系统的录音文件播放,或者调用系统的图库。
能够参考调用图库的解决方案,原理同样
Android版本相机适配问题集合(不断整理更新中)
demo下载地址:
https://fir.im/jy28
demo源码:
https://github.com/wapchief/android-CollectionDemo
做者:八怪不姓丑 连接:https://www.jianshu.com/p/950d73234991 来源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。