样式:
1.集成科大讯飞:网上有很多集成方法。
2.写布局,注意帧布局有顺序谁在最上面,要在布局文件下面写。下面是我的布局,注意用Scrollview套,是因为要随键盘上下滑动。
<RelativeLayout android:id="@+id/search_voice_bg" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0.8" android:background="@color/white" android:visibility="gone"> <TextView android:id="@+id/search_voice_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="70dp" android:textColor="#333333" android:textSize="20sp" android:visibility="gone" /> <TextView android:id="@+id/voice_result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/search_voice_msg" android:layout_centerHorizontal="true" android:textColor="#f7783f" android:textSize="20sp" android:visibility="gone" /> <RelativeLayout android:id="@+id/search_voice_dialog" android:layout_width="150dp" android:layout_height="150dp" android:layout_centerInParent="true" android:background="@drawable/search_voice_dialog" android:gravity="center" android:visibility="gone"> <TextView android:id="@+id/search_voice_dialog_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_margin="10dp" android:text="@string/search_voice_dialog_title" android:textColor="#fff" android:textSize="15sp" /> <ImageView android:id="@+id/search_voice_dialog_mic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerInParent="true" android:src="@drawable/tmsearch_voice"></ImageView> <ImageView android:id="@+id/search_sound_PRogress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@id/search_voice_dialog_mic" android:layout_marginBottom="1dip" android:layout_marginLeft="30dp" android:background="@drawable/voice_1"></ImageView> </RelativeLayout> </RelativeLayout> </FrameLayout> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="48dp" android:layout_alignParentBottom="true" android:background="#fafafa"> <ImageView android:layout_width="fill_parent" android:layout_height="1dip" android:background="#d4d4d4" /> <RelativeLayout android:id="@+id/search_voice_rl" android:layout_width="280dp" android:layout_height="37dp" android:layout_centerInParent="true" android:background="@drawable/search_top_bg"> <ImageView android:id="@+id/voice_tube" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:src="@drawable/search_icon" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/voice_tube" android:text="@string/search_voice" android:textColor="#444444" android:textSize="18sp" /> </RelativeLayout> </RelativeLayout> </ScrollView>3.代码部分:
1.
/** * 语音搜索 */@BindView(R.id.search_voice_rl)RelativeLayout voice_btn;@BindView(R.id.search_voice_bg)RelativeLayout voice_bg;@BindView(R.id.search_voice_msg)TextView voice_msg;@BindView(R.id.search_voice_dialog)RelativeLayout voice_dialog;@BindView(R.id.search_voice_dialog_tv)TextView dialog_title;@BindView(R.id.search_voice_dialog_mic)ImageView dialog_mic;@BindView(R.id.search_sound_progress)ImageView dialog_progress;@BindView(R.id.voice_result)TextView voice_result;/** * 语音听写对象 */private SpeechRecognizer mIat;/** * 用HashMap存储听写结果 */private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();/** * 引擎类型 */private String mEngineType = SpeechConstant.TYPE_CLOUD;private Drawable[] progressImg = new Drawable[9];private GestureDetector mGestureDetector;float mPosX, mPosY, mCurPosX, mCurPosY;private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: restoreState(); break; } }};boolean isSingleTapUp = false;boolean isOnError = false;HandlerUtil handerUtil;private static final int SHOW_TIME = 1000;2.在onCreate(Bundle savedInstanceState) 中:keyWordRv = (RecyclerView) findViewById(R.id.search_leyWord_listView);//创建SpeechRecognizer对象,第二个参数:本地听写时传InitListenermIat = SpeechRecognizer.createRecognizer(this, null);searchVoice();3./** * 语音搜索 */private void searchVoice() { mGestureDetector = new GestureDetector(this, new MyOnGestureListener()); progressImg[0] = this.getResources().getDrawable(R.drawable.voice_1); progressImg[1] = this.getResources().getDrawable(R.drawable.voice_2); progressImg[2] = this.getResources().getDrawable(R.drawable.voice_3); progressImg[3] = this.getResources().getDrawable(R.drawable.voice_4); progressImg[4] = this.getResources().getDrawable(R.drawable.voice_5); progressImg[5] = this.getResources().getDrawable(R.drawable.voice_6); progressImg[6] = this.getResources().getDrawable(R.drawable.voice_7); progressImg[7] = this.getResources().getDrawable(R.drawable.voice_8); progressImg[8] = this.getResources().getDrawable(R.drawable.voice_9); voice_btn.setFocusable(true); voice_btn.setClickable(true); voice_btn.setLongClickable(true); voice_btn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { //通知父控件勿拦截本控件touch事件 view.getParent().requestDisallowInterceptTouchEvent(true); mGestureDetector.onTouchEvent(motionEvent); switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: voice_msg.setVisibility(View.GONE); mPosX = motionEvent.getX(); mPosY = motionEvent.getY(); break; case MotionEvent.ACTION_MOVE: mCurPosX = motionEvent.getX(); mCurPosY = motionEvent.getY(); if (mCurPosY - mPosY < 0 && (Math.abs(mCurPosY - mPosY) > 100)) { dialog_mic.setImageResource(R.drawable.tbsearch_repeal); dialog_title.setBackgroundResource(R.drawable.tmsearch_btn); dialog_title.setText(R.string.Loosen_the_fingers); startState(); } else if (mCurPosY - mPosY > 0 && (Math.abs(mCurPosY - mPosY) > 100)) { dialog_mic.setImageResource(R.drawable.tbsearch_repeal); dialog_title.setBackgroundResource(R.drawable.tmsearch_btn); dialog_title.setText(R.string.Loosen_the_fingers); } break; case MotionEvent.ACTION_UP: voice_btn.setBackgroundResource(R.drawable.search_top_bg); if (mCurPosY - mPosY > 0 && (Math.abs(mCurPosY - mPosY) > 100)) { //向下滑动 mIat.cancel(); voice_msg.setText(R.string.voice_search_has_been_cancelled); resultState(); handerUtil.sendMessage(SHOW_TIME); } else if (mCurPosY - mPosY < 0 && (Math.abs(mCurPosY - mPosY) > 100)) { //向上滑动 mIat.cancel(); voice_msg.setText(R.string.voice_search_has_been_cancelled); resultState(); handerUtil.sendMessage(SHOW_TIME); } else { if (!isSingleTapUp) { resultState(); recognitionState(); } if (!isOnError) { resultState(); recognitionState(); } mIat.stopListening(); } break; } return true; } });}4.private void setParam() { // 清空参数 mIat.setParameter(SpeechConstant.PARAMS, null); // 引擎 mIat.setParameter(SpeechConstant.DOMAIN, "iat"); // 设置语言 mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); // 普通话 mIat.setParameter(SpeechConstant.ACCENT, "mandarin"); // 设置听写引擎 mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType); // 设置返回结果格式 mIat.setParameter(SpeechConstant.RESULT_TYPE, "json"); // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 mIat.setParameter(SpeechConstant.VAD_BOS, "4000"); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 mIat.setParameter(SpeechConstant.VAD_EOS, "4000"); // 语音输入超时时间 mIat.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, "10000"); // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 mIat.setParameter(SpeechConstant.ASR_PTT, "0"); // 开始听写 mIat.startListening(mRecognizerListener);}/** * 听写监听器 */private RecognizerListener mRecognizerListener = new RecognizerListener() { @Override public void onVolumeChanged(int i, byte[] bytes) { volumeChanged(i); } @Override public void onBeginOfSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 startState(); } @Override public void onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 } @Override public void onResult(RecognizerResult recognizerResult, boolean isLast) { String lastResult = null; if (recognizerResult != null) { lastResult = printResult(recognizerResult); } if (isLast) { // 最后的结果 recognitionState(); mIat.stopListening(); final String finalLastResult = lastResult; handerUtil.postDelayed(new Runnable() { @Override public void run() { voice_msg.setText(R.string.is_the_search_for_you); voice_result.setText(finalLastResult); voice_result.setVisibility(View.VISIBLE); resultState(); } }, SHOW_TIME); handerUtil.postDelayed(new Runnable() { @Override public void run() { toSearchResultActivity(finalLastResult); } }, SHOW_TIME); } } @Override public void onError(SpeechError speechError) { isOnError = true; isSingleTapUp = true; if (speechError.getErrorCode() == 10118 || speechError.getErrorCode() == 10114) { // 可能是录音机权限被禁,需要提示用户打开应用的录音权限。 unidentified(); handerUtil.sendMessage(SHOW_TIME); } else if (speechError.getErrorCode() == 20001 || speechError.getErrorCode() == 20002 || speechError.getErrorCode() == 20003) { voice_msg.setText(R.string.voice_search_no_internet); resultState(); handerUtil.sendMessage(SHOW_TIME); } } @Override public void onEvent(int i, int i1, int i2, Bundle bundle) { }};/** * 声音改变方法(当前音量值,范围[0-30]) */private void volumeChanged(int decibel) { switch (decibel) { case 0: case 1: case 2: dialog_progress.setBackgroundDrawable(progressImg[0]); break; case 3: case 4: case 5: dialog_progress.setBackgroundDrawable(progressImg[1]); break; case 6: case 7: case 8: dialog_progress.setBackgroundDrawable(progressImg[2]); break; case 9: case 10: case 11: dialog_progress.setBackgroundDrawable(progressImg[3]); break; case 12: case 13: case 14: dialog_progress.setBackgroundDrawable(progressImg[4]); break; case 15: case 16: case 17: case 18: dialog_progress.setBackgroundDrawable(progressImg[5]); break; case 19: case 20: case 21: case 22: dialog_progress.setBackgroundDrawable(progressImg[6]); break; case 23: case 24: case 25: case 26: dialog_progress.setBackgroundDrawable(progressImg[7]); break; case 27: case 28: case 29: case 30: dialog_progress.setBackgroundDrawable(progressImg[8]); break; }}/** * 语音返回结果 */private String printResult(RecognizerResult results) { String text = null; String sn = null; if (results != null) { text = JsonParser.parseIatResult(results.getResultString()); } // 读取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)); } return resultBuffer.toString();}class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { isSingleTapUp = true; isOnError = true; unidentified(); mIat.cancel(); handerUtil.sendMessage(SHOW_TIME); return true; } @Override public void onLongPress(MotionEvent e) { // 清空显示内容 voice_msg.setText(null); mIatResults.clear(); setParam(); startState(); } @Override public void onShowPress(MotionEvent e) { voice_btn.setBackgroundColor(Color.parseColor("#888888")); } @Override public boolean onDown(MotionEvent e) { isSingleTapUp = false; isOnError = false; dialog_mic.setImageResource(R.drawable.tmsearch_voice); dialog_title.setText(R.string.search_voice_dialog_title); dialog_title.setBackgroundColor(Color.parseColor("#222222")); startState(); return false; }}/** * 开始听写状态 */private void startState() { voice_bg.setVisibility(View.VISIBLE); voice_dialog.setVisibility(View.VISIBLE); voice_msg.setVisibility(View.GONE); voice_result.setVisibility(View.GONE);}/** * 识别中状态 */private void recognitionState() { voice_bg.setVisibility(View.VISIBLE); voice_msg.setText(R.string.search_voice_msg); voice_msg.setVisibility(View.VISIBLE); voice_dialog.setVisibility(View.GONE);}/** * 未识别状态 */private void unidentified() { voice_bg.setVisibility(View.VISIBLE); voice_result.setVisibility(View.GONE); voice_dialog.setVisibility(View.GONE); voice_msg.setText(R.string.voice_search_error); voice_msg.setVisibility(View.VISIBLE);}/** * 显示结果状态 */private void resultState() { voice_bg.setVisibility(View.VISIBLE); voice_msg.setVisibility(View.VISIBLE); voice_dialog.setVisibility(View.GONE);}/** * 恢复原状状态 */private void restoreState() { voice_bg.setVisibility(View.GONE); voice_msg.setVisibility(View.GONE); voice_dialog.setVisibility(View.GONE);}5这基本就和淘宝的语音搜索差不多了
新闻热点
疑难解答