Android studio整合百度語音識別api
阿新 • • 發佈:2019-01-11
今天 專案中要用到語音功能,所以看了下百度語音api
1,根據百度語音開發文件,建立應用,下載相應的jar包,新增到你的應用
2,清單檔案配置資訊,
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<meta-data android:name="com.baidu.speech.APP_ID" android:value="xxxxxxx" /> <!-- 請填寫應用實際的API_KEY --> <meta-data android:name="com.baidu.speech.API_KEY" android:value="xxxxxxxxxx" /> <!-- 請填寫應用實際的SECRET_KEY --> <meta-data android:name="com.baidu.speech.SECRET_KEY" android:value="xxxxxxxxx" />
3 ,把drawable和raw下的資源全部複製到你的專案,注意:如果缺少資源會報錯
4 ,把so檔案複製到jnilibs目錄,這點很重要,我也是看下面這我博主文章才覺得這個問題
https://my.oschina.net/MStart/blog/637723?p={{page}}
4,按照官方api程式碼編寫,根據自己的需求寫佈局,貼上demo程式碼
public class MainActivity extends Activity implements RecognitionListener { private static final String TAG ="MainActivity" ; private SpeechRecognizer speechRecognizer; private BaiduASRDigitalDialog dialog; public static final int STATUS_None = 0; public static final int STATUS_WaitingReady = 2; public static final int STATUS_Ready = 3; public static final int STATUS_Speaking = 4; public static final int STATUS_Recognition = 5; private Button setting,start; private TextView result,txtLog; private long time; private long speechEndTime=-1; private static final int REQUEST_UI=1; private int status = STATUS_None; private static final int EVENT_ERROR = 11; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setting= (Button) findViewById(R.id.setting); start= (Button) findViewById(R.id.start); result= (TextView) findViewById(R.id.result); txtLog= (TextView) findViewById(R.id.txtLog); // 建立識別器 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this, new ComponentName(this, VoiceRecognitionService.class)); } // 註冊監聽器 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { speechRecognizer.setRecognitionListener(this); } } //設定介面 public void setTing(View view){ Intent intent = new Intent("com.baidu.speech.asr.demo.setting"); startActivity(intent); } //開始 public void start(View view){ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); boolean api = sp.getBoolean("api", false); if (api) { switch (status) { case STATUS_None: startASR(); start.setText("取消"); status = STATUS_WaitingReady; break; case STATUS_WaitingReady: cancel(); status = STATUS_None; start.setText("開始"); break; case STATUS_Ready: cancel(); status = STATUS_None; start.setText("開始"); break; case STATUS_Speaking: stop(); status = STATUS_Recognition; start.setText("識別中"); break; case STATUS_Recognition: cancel(); status = STATUS_None; start.setText("開始"); break; } } else { startASR(); } } private void stop() { speechRecognizer.stopListening(); print("點選了“說完了”"); } private void cancel() { speechRecognizer.cancel(); status = STATUS_None; print("點選了“取消”"); } // 開始識別 void startASR() { // txtLog.setText(""); print("點選了“開始”"); Intent intent = new Intent(); bindParams(intent); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); { String args = sp.getString("args", ""); if (null != args) { print("引數集:" + args); intent.putExtra("args", args); } } boolean api = sp.getBoolean("api", false); if (api) { speechEndTime = -1; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { speechRecognizer.startListening(intent); } } else { intent.setAction("com.baidu.action.RECOGNIZE_SPEECH"); startActivityForResult(intent, REQUEST_UI); } // result.setText(""); } void bindParams(Intent intent) { // 設定識別引數 // intent.putExtra("sample", 16000); // 離線僅支援16000取樣率 // intent.putExtra("language", "cmn-Hans-CN"); // 離線僅支援中文普通話 // intent.putExtra("prop", 20000); // 輸入 // intent.putExtra("prop", 10060); // 地圖 // intent.putExtra("prop", 10001); // 音樂 // intent.putExtra("prop", 10003); // 應用 // intent.putExtra("prop", 10008); // 電話 // intent.putExtra("prop", 100014); // 聯絡人 // intent.putExtra("prop", 100016); // 手機設定 // intent.putExtra("prop", 100018); // 電視指令 // intent.putExtra("prop", 100019); // 播放器指令 // intent.putExtra("prop", 100020); // 收音機指令 // intent.putExtra("prop", 100021); // 命令詞 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); if (sp.getBoolean("tips_sound", true)) { intent.putExtra(Constant.EXTRA_SOUND_START, R.raw.bdspeech_recognition_start); intent.putExtra(Constant.EXTRA_SOUND_END, R.raw.bdspeech_speech_end); intent.putExtra(Constant.EXTRA_SOUND_SUCCESS, R.raw.bdspeech_recognition_success); intent.putExtra(Constant.EXTRA_SOUND_ERROR, R.raw.bdspeech_recognition_error); intent.putExtra(Constant.EXTRA_SOUND_CANCEL, R.raw.bdspeech_recognition_cancel); } if (sp.contains(Constant.EXTRA_INFILE)) { String tmp = sp.getString(Constant.EXTRA_INFILE, "").replaceAll(",.*", "").trim(); intent.putExtra(Constant.EXTRA_INFILE, tmp); } if (sp.getBoolean(Constant.EXTRA_OUTFILE, false)) { intent.putExtra(Constant.EXTRA_OUTFILE, "sdcard/outfile.pcm"); } if (sp.getBoolean(Constant.EXTRA_GRAMMAR, false)) { intent.putExtra(Constant.EXTRA_GRAMMAR, "assets:///baidu_speech_grammar.bsg"); } if (sp.contains(Constant.EXTRA_SAMPLE)) { String tmp = sp.getString(Constant.EXTRA_SAMPLE, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_SAMPLE, Integer.parseInt(tmp)); } } if (sp.contains(Constant.EXTRA_LANGUAGE)) { String tmp = sp.getString(Constant.EXTRA_LANGUAGE, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_LANGUAGE, tmp); } } if (sp.contains(Constant.EXTRA_NLU)) { String tmp = sp.getString(Constant.EXTRA_NLU, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_NLU, tmp); } } if (sp.contains(Constant.EXTRA_VAD)) { String tmp = sp.getString(Constant.EXTRA_VAD, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_VAD, tmp); } } String prop = null; if (sp.contains(Constant.EXTRA_PROP)) { String tmp = sp.getString(Constant.EXTRA_PROP, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_PROP, Integer.parseInt(tmp)); prop = tmp; } } // offline asr { intent.putExtra(Constant.EXTRA_OFFLINE_ASR_BASE_FILE_PATH, "/sdcard/easr/s_1"); if (null != prop) { int propInt = Integer.parseInt(prop); if (propInt == 10060) { intent.putExtra(Constant.EXTRA_OFFLINE_LM_RES_FILE_PATH, "/sdcard/easr/s_2_Navi"); } else if (propInt == 20000) { intent.putExtra(Constant.EXTRA_OFFLINE_LM_RES_FILE_PATH, "/sdcard/easr/s_2_InputMethod"); } } intent.putExtra(Constant.EXTRA_OFFLINE_SLOT_DATA, buildTestSlotData()); } } private String buildTestSlotData() { JSONObject slotData = new JSONObject(); JSONArray name = new JSONArray().put("李湧泉").put("郭下綸"); JSONArray song = new JSONArray().put("七里香").put("發如雪"); JSONArray artist = new JSONArray().put("周杰倫").put("李世龍"); JSONArray app = new JSONArray().put("手機百度").put("百度地圖"); JSONArray usercommand = new JSONArray().put("關燈").put("開門"); try { slotData.put(Constant.EXTRA_OFFLINE_SLOT_NAME, name); slotData.put(Constant.EXTRA_OFFLINE_SLOT_SONG, song); slotData.put(Constant.EXTRA_OFFLINE_SLOT_ARTIST, artist); slotData.put(Constant.EXTRA_OFFLINE_SLOT_APP, app); slotData.put(Constant.EXTRA_OFFLINE_SLOT_USERCOMMAND, usercommand); } catch (JSONException e) { } return slotData.toString(); } @Override public void onReadyForSpeech(Bundle bundle) { // 準備就緒 print("準備就緒,可以開始說話"); } @Override public void onBeginningOfSpeech() { // 開始說話處理 time = System.currentTimeMillis(); status = STATUS_Speaking; start.setText("說完了"); print("檢測到使用者的已經開始說話"); } @Override public void onRmsChanged(float v) { // 音量變化處理 } @Override public void onBufferReceived(byte[] bytes) { // 錄音資料傳出處理 } @Override public void onEndOfSpeech() { // 說話結束處理 speechEndTime = System.currentTimeMillis(); status = STATUS_Recognition; print("檢測到使用者的已經停止說話"); start.setText("識別中"); } @Override public void onError(int i) { // 出錯處理 time = 0; StringBuilder sb = new StringBuilder(); switch (i) { case SpeechRecognizer.ERROR_AUDIO: sb.append("音訊問題"); break; case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: sb.append("沒有語音輸入"); break; case SpeechRecognizer.ERROR_CLIENT: sb.append("其它客戶端錯誤"); break; case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: sb.append("許可權不足"); break; case SpeechRecognizer.ERROR_NETWORK: sb.append("網路問題"); break; case SpeechRecognizer.ERROR_NO_MATCH: sb.append("沒有匹配的識別結果"); break; case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: sb.append("引擎忙"); break; case SpeechRecognizer.ERROR_SERVER: sb.append("服務端錯誤"); break; case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: sb.append("連線超時"); break; } sb.append(":" + i); print("識別失敗:" + sb.toString()); start.setText("開始"); } @Override public void onResults(Bundle bundle) { // 最終結果處理 long end2finish = System.currentTimeMillis() - speechEndTime; status = STATUS_None; ArrayList<String> nbest = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); print("識別成功:" + Arrays.toString(nbest.toArray(new String[nbest.size()]))); String json_res = bundle.getString("origin_result"); try { print("origin_result=\n" + new JSONObject(json_res).toString(4)); } catch (Exception e) { print("origin_result=[warning: bad json]\n" + json_res); } start.setText("開始"); String strEnd2Finish = ""; if (end2finish < 60 * 1000) { strEnd2Finish = "(waited " + end2finish + "ms)"; } result.setText(nbest.get(0) + strEnd2Finish); time = 0; } @Override public void onPartialResults(Bundle bundle) { // 臨時結果處理 ArrayList<String> nbest = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if (nbest.size() > 0) { print("~臨時識別結果:" + Arrays.toString(nbest.toArray(new String[0]))); result.setText(nbest.get(0)); } } @Override public void onEvent(int i, Bundle bundle) { // 處理事件回撥 switch (i) { case EVENT_ERROR: String reason = bundle.get("reason") + ""; print("EVENT_ERROR, " + reason); break; case VoiceRecognitionService.EVENT_ENGINE_SWITCH: int type = bundle.getInt("engine_type"); print("*引擎切換至" + (type == 0 ? "線上" : "離線")); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { onResults(data.getExtras()); } } private void print(String msg) { long t = System.currentTimeMillis() - time; if (t > 0 && t < 100000) { txtLog.append(t + "ms, " + msg + "\n"); } else { txtLog.append("" + msg + "\n"); } ScrollView sv = (ScrollView) txtLog.getParent(); sv.smoothScrollTo(0, 1000000); Log.d(TAG, "----" + msg); } }
因為官方提供的是eclipse 環境demo,所以只要注意 3 ,4兩點,就很簡單了