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 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。