android仿淘宝语音搜索功能集成科大讯飞

样式:

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 isNetwork = false;
HandlerUtil handerUtil;
private static final int SHOW_TIME = 1500;
private static final int SHOW_TIME_RESULT = 2500;

2.在
onCreate(Bundle savedInstanceState) 
中:
keyWordRv = (RecyclerView) findViewById(R.id.search_leyWord_listView);
//创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
mIat = 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:
               startState();
               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_progress.setVisibility(View.GONE);
                  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_progress.setVisibility(View.GONE);
                  dialog_mic.setImageResource(R.drawable.tbsearch_repeal);
                  dialog_title.setBackgroundResource(R.drawable.tmsearch_btn);
                  dialog_title.setText(R.string.Loosen_the_fingers);
               } else {
                  dialog_progress.setVisibility(View.VISIBLE);
                  dialog_mic.setImageResource(R.drawable.tmsearch_voice);
                  dialog_title.setBackgroundColor(Color.parseColor("#222222"));
                  dialog_title.setText(R.string.search_voice_dialog_title);
               }
               break;
            case MotionEvent.ACTION_UP:
               voice_btn.setBackgroundResource(R.drawable.get_code_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 {
                  voice_dialog.setVisibility(View.GONE);
                  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内部录音机已经准备好了,用户可以开始语音输入
   }

   @Override
   public void onEndOfSpeech() {
      // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
   }

   @Override
   public void onResult(RecognizerResult recognizerResult, boolean isLast) {
      String lastResult = null;
      if (recognizerResult != null) {
         lastResult = printResult(recognizerResult);
      }
      if (isLast) {
         // 最后的结果
         recognitionState();
         final String finalLastResult = lastResult;
         //有时语音搜索会识别出或空的时候,为避免这种情况的发生故做此判断,如果出现这种情况显示未识别状态
         if (finalLastResult.equals("") || StringUtils.isEmpty(finalLastResult)) {
            unidentified();
            mIat.cancel();
            handerUtil.sendMessage(SHOW_TIME);
            return;
         }
         mIat.stopListening();
         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() {
               handerUtil.sendMessage(1000);
               toSearchResultActivity(finalLastResult);
            }
         }, SHOW_TIME_RESULT);


      }
   }

   @Override
   public void onError(SpeechError speechError) {
      if (speechError.getErrorCode() == 10118 || speechError.getErrorCode() == 10114) {
         // 可能是录音机权限被禁,需要提示用户打开应用的录音权限。
         unidentified();
         mIat.cancel();
         handerUtil.sendMessage(500);
      } else {
         isNetwork = true;
         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) {
      if (!isNetwork) {
         mIat.cancel();
         restoreState();
      }
      return true;
   }

   @Override
   public void onLongPress(MotionEvent e) {
      // 清空显示内容
      if (!isNetwork) {
         voice_msg.setText(null);
         mIatResults.clear();
         startState();
      }
   }

   @Override
   public void onShowPress(MotionEvent e) {
      voice_btn.setBackgroundResource(R.drawable.gray_round_bg);
      startState();
   }

   @Override
   public boolean onDown(MotionEvent e) {
      isNetwork = false;
      dialog_progress.setVisibility(View.VISIBLE);
      dialog_mic.setImageResource(R.drawable.tmsearch_voice);
      dialog_title.setText(R.string.search_voice_dialog_title);
      dialog_title.setBackgroundColor(Color.parseColor("#222222"));
      startState();
      setParam();
      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这基本就和淘宝的语音搜索差不多了


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值