第一步:下载SDK,将demo运行起来,没问题的话在应用管理 | 控制台创建新的应用,绑定包名,开通语音识别和语音合成的服务。

第二步:在工程中添加jar以及so库,raw,assets(有的话)等,记得这个有个坑,就是在上传svn或者其他什么操作时,授权失败,不识别语音了,看下是不是so库丢失了,重新添加下。

这里因为已经用过了语音识别封装了方法,只要在onCreate方法调用该方法即可进行语音识别,这里是没有百度语音识别的UI界面的,结果在onResult方法里,可以自己直接处理或eventbus post出去操作。

下面是方法:

// 语音识别客户端
private SpeechRecognizer speechRecognizer;
private void initRecognizer() {
        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this, new ComponentName(this, VoiceRecognitionService.class));
        speechRecognizer.setRecognitionListener(new RecognitionListener() {
            @Override
            public void onReadyForSpeech(Bundle params) {
                progressView.start();
                status = STATUS_Ready;
                print("准备就绪,可以开始说话");
            }

            @Override
            public void onBeginningOfSpeech() {

                time = System.currentTimeMillis();
                status = STATUS_Speaking;
                print("检测到用户的已经开始说话");
                Log.e("555555555", "onBeginningOfSpeech: ");
            }

            @Override
            public void onRmsChanged(float rmsdB) {
                if (rmsdB < 100) {
                    rmsdB = 0;
                }
                if (rmsdB > 900) {
                    rmsdB = 900;
                }
                progressView.setVolume((int) (rmsdB / 42f));
                Log.e(TAG, "onRmsChanged: " + rmsdB);
            }

            @Override
            public void onBufferReceived(byte[] buffer) {

            }

            @Override
            public void onEndOfSpeech() {
                speechEndTime = System.currentTimeMillis();
                status = STATUS_Recognition;
                print("检测到用户的已经停止说话");
                Log.e("555555555", "onEndOfSpeech: ");
            }

            @Override
            public void onError(int error) {
                time = 0;
                status = STATUS_None;
                StringBuilder sb = new StringBuilder();
                switch (error) {
                    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(":" + error);
                print("识别失败:" + sb.toString());
                handlerRecognizer.sendEmptyMessage(0);
            }

            @Override
            public void onResults(Bundle results) {
                long end2finish = System.currentTimeMillis() - speechEndTime;
                status = STATUS_None;
                ArrayList<String> nbest = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                print("识别成功:" + Arrays.toString(nbest.toArray(new String[nbest.size()])));
                String json_res = results.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);
                }
                String strEnd2Finish = "";
                if (end2finish < 60 * 1000) {
                    strEnd2Finish = "(waited " + end2finish + "ms)";
                }
                //最终结果
//        txtResult.setText(nbest.get(0) + strEnd2Finish);
                Log.e("111111111111", "onResults: " + nbest.get(0) + strEnd2Finish);
                EventBus.getDefault().post(new EventAction(1002, nbest.get(0)));

                time = 0;
            }

            @Override
            public void onPartialResults(Bundle partialResults) {
                ArrayList<String> nbest = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                if (nbest.size() > 0) {
                    print("~临时识别结果:" + Arrays.toString(nbest.toArray(new String[0])));
//            txtResult.setText(nbest.get(0));
                    Log.e("111111111111", "onPartialResults: " + nbest.get(0));
                }
            }

            @Override
            public void onEvent(int eventType, Bundle params) {
                switch (eventType) {
                    case EVENT_ERROR:
                        String reason = params.get("reason") + "";
                        print("EVENT_ERROR, " + reason);
                        break;
                    case VoiceRecognitionService.EVENT_ENGINE_SWITCH:
                        int type = params.getInt("engine_type");
                        print("*引擎切换至" + (type == 0 ? "在线" : "离线"));
                        break;
                }
            }
        });
    }

第三步:语音合成:和语音识别同样的操作,开通服务,在工程中添加jar和其他so库等,添加完了后,这里也进行了方法封装,只要在onCreate方法里调用该方法就可以开启语音合成。

下面是语音合成的方法:

// 语音合成客户端
private SpeechSynthesizer mSpeechSynthesizer;
// 初始化语音合成客户端并启动
                private void initTTS() {
                    // 获取语音合成对象实例
                    mSpeechSynthesizer = SpeechSynthesizer.getInstance();
                    // 设置context
                    mSpeechSynthesizer.setContext(this);

                    // 设置语音合成状态监听器
                    mSpeechSynthesizer.setSpeechSynthesizerListener(new SpeechSynthesizerListener() {
                        @Override
                        public void onSynthesizeStart(String s) {
                            Log.e("444444444", "onSynthesizeStart: ");
                        }

                        @Override
                        public void onSynthesizeDataArrived(String s, byte[] bytes, int i) {
                            Log.e("444444444", "onSynthesizeDataArrived: ");
                        }

                        @Override
                        public void onSynthesizeFinish(String s) {
                            Log.e("444444444", "onSynthesizeFinish: ");
                        }

                        @Override
                        public void onSpeechStart(String s) {
                            Log.e("444444444", "onSpeechStart: ");
                        }

                        @Override
                        public void onSpeechProgressChanged(String s, int i) {

                        }

                        @Override
                        public void onSpeechFinish(String s) {//监听到播放结束
                            Log.e("444444444", "onSpeechFinish: ");
                if ("我暂时停止接受您的指令,需要恢复,请按恢复按钮。".equals(message)) {

                } else {
                    handlerRecognizer.sendEmptyMessage(0);//由于项目需求在监听到语音播放结束的时候重新开启语音识别,但是语音识别只能在主线程中执行,所以这里用handler起了一个线程,方法在下面赋
                }
            }

            @Override
            public void onError(String s, SpeechError speechError) {
                Log.e("444444444", "onError: ");
            }
        });
        // 设置在线语音合成授权,需要填入从百度语音官网申请的api_key和secret_key
        mSpeechSynthesizer.setApiKey("Uod13Hd6rURLvDLRlVP5PgSB", "cba32e2cc5189a886bd127715dcafabe");
        // 设置离线语音合成授权,需要填入从百度语音官网申请的app_id
        mSpeechSynthesizer.setAppId("9942218");
        // 文本模型文件路径 (离线引擎使用)
        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, mSampleDirPath + "/"
                + TEXT_MODEL_NAME);
        // 声学模型文件路径 (离线引擎使用)
        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, mSampleDirPath + "/"
                + SPEECH_FEMALE_MODEL_NAME);
        // 本地授权文件路径,如未设置将使用默认路径.设置临时授权文件路径,
        // LICENCE_FILE_NAME请替换成临时授权文件的实际路径,仅在使用临时license文件时需要进行设置,
        // 如果在[应用管理]中开通了正式离线授权,不需要设置该参数,建议将该行代码删除(离线引擎)
        // 如果合成结果出现临时授权文件将要到期的提示,说明使用了临时授权文件,请删除临时授权即可。
//        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_LICENCE_FILE, mSampleDirPath + "/"
//                + LICENSE_FILE_NAME);
        // 获取语音合成授权信息---有两种模式:仅在线;混合(离在线)
        //初始化合成引擎,可以指定使用online在线,或者mix离在线混合引擎. mix混合引擎会在online在线不能用的情况下自动使用offline离线引擎。
        AuthInfo authInfo = mSpeechSynthesizer.auth(TtsMode.MIX);
        // 判断授权信息是否正确,如果正确则初始化语音合成器并开始语音合成,如果失败则做错误处理
        if (authInfo.isSuccess()) {
            mSpeechSynthesizer.initTts(TtsMode.MIX);
        } else {
            // 授权失败
            Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();

        }

    }
第四步:重新开启语音识别,用handler起了一个线程
Handler handlerRecognizer = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        startRecognizer();
    }
};

第五步:需要控制语音识别的开始和停止的方法,这里也做了封装,在需要的时候调用即可。

下面是语音识别开始和停止的方法:

/**
     * 开始识别语音
     */
    private void startRecognizer() {
        Intent intent = new Intent();
        intent.putExtra("language", "cmn-Hans-CN");
        intent.putExtra("prop", 10005);
        speechEndTime = -1;
        speechRecognizer.startListening(intent);

    }
//暂停语音识别
    private void stopRecognizer() {
        speechRecognizer.stopListening();
        print("点击了“说完了”");
    }
//停止语音识别
    private void cancelRecognizer() {
        speechRecognizer.cancel();
        status = STATUS_None;
        print("点击了“取消”");
    }
这里需要注意的是,我遇到的一个问题:
在需要停止监听语音的时候,刚开始我调用的是stop方法,但是并不能真正的停止语音监听,在和百度的技术人员沟通后才知道要调用cancle方法才可以,两个方法同时调用也不可取。
第六步:百度语音合成的方法:
//语音开始播报
mSpeechSynthesizer.speak(“text”);
//语音停止播报mSpeechSynthesizer.stop();
第七步:



当然语音合成和识别都要在activity或fragment的生命周期中做相应的操作:



@Override
protected void onResume() {
    if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {//横屏操作
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    mSpeechSynthesizer.resume();
    super.onResume();
}

@Override
protected void onPause() {
    cancelRecognizer();
    if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {//横屏操作
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    mSpeechSynthesizer.pause();
    super.onPause();
}

@Override
protected void onDestroy() {
    if (null != mSpeechSynthesizer) {
        mSpeechSynthesizer.release();
    }
    if (null != speechRecognizer) {
        // 退出时释放连接
        speechRecognizer.destroy();
    }
    super.onDestroy();
}