Baymax (Android版的Siri)之百度语音识别SDK调用

之前说Baymax 的UI设计,现在UI设计好了,我们得开始讲一讲识别方面的事了。这里我们需要用到百度的语音识别技术,大家可以先上百度语音开放平台,上面有开发手册和demo帮助大家学习。贴上连接:http://yuyin.baidu.com/

       前面注册百度开发者的那些步骤我就跳过了,基本上开发手册写的很详细了。这里我就不再多说。

       首先是注册可能需要用到的权限







 
 
  
 
  
 
  
 
  
 然后是填上自己在百度申请到的秘钥

 




导入所需资源包之后(在百度语音开发平台官网可以下载),就要开始调用了


首先是创建识别器及识别器监听事件

 //创建识别器
speechRecognizer=SpeechRecognizer.createSpeechRecognizer(this,new ComponentName(this,VoiceRecognitionService.class));
 //识别器监听事件
speechRecognizer.setRecognitionListener(this);

监听器需要重写的方法有如下这些,我加以详细说明,开发者根据开发需要重写内容即可

@Override
            public void onReadyForSpeech(Bundle params) {
             //准备监听时事件
            }

            @Override
            public void onBeginningOfSpeech() {
           //开始监听事件
            }

            @Override
            public void onRmsChanged(float rmsdB) {
            //声音级别更改时调用的方法
            }

            @Override
            public void onBufferReceived(byte[] buffer) {
          //反馈给用户捕获的音频
            }

            @Override
            public void onEndOfSpeech() {
          //结束说话时调用此方法
            }

            @Override
            public void onError(int error) {
            //错误时事件
            }

            @Override
            public void onResults(Bundle results) {
                //识别结果事件,识别结果为results,需要进行解析
            }

            @Override
            public void onPartialResults(Bundle partialResults) {
           //这个不太懂
            }
	
            @Override
            public void onEvent(int eventType, Bundle params) {
            //
            }

      以上是我个人的理解,不是很正确,建议大家看一下开发文档,里面有详细的解释,我这里只是做点简单的介绍。里面最重要的方法就是onResults(Bundle results)识别结果就是在这里面处理的,有了识别结果,我们就可以做出各种“动作”了,像什么开灯关灯,打开相机,拍照什么的都可以。只要你愿意,想让手机关机我想也是可以的。

       关于识别监听器就讲完了,没什么好说的,接下来讲识别的参数问题。

       百度语音识别SDK需要设置的参数不少,当然也可以全都默认,个人觉得挺好的,可以适应不同环境做识别,提高准确率。这里也是大概讲一下哪些参数可能要用到


①提示音(默认是静音)
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);

②是否保存录音(默认无)
intent.putExtra(Constant.EXTRA_OUTFILE, "sdcard/outfile.pcm");
③设置采样率(8000为2g/3g网络适用,16000为3g/4g网络)
intent.putExtra(Constant.EXTRA_SAMPLE, 8000/16000);

④设置识别语言(可识别普通话/粤语/四川话/英语)
intent.putExtra(Constant.EXTRA_LANGUAGE,      xxx);

⑤是否进行语义解析(默认否)
intent.putExtra(Constant.EXTRA_NLU,    );

⑥VAD,选择输入关键字或输入长句(默认关键字)
intent.putExtra(Constant.EXTRA_VAD,   );


        其中有一个很重要的参数叫做垂直领域,当时我看了很久都没搞懂是什么,经过后来的实践,我觉得可能是优先识别领域吧。里面可以设置应用、联系人、音乐、输入、视频、地图、网页、电话、联系人……等等等等(好吧我到现在还是不太明白垂直领域的作用,还望哪位大神可以告知一下)。垂直领域的设置可以提高语言识别的准确率,设置的越详细越多就越准确。除此之外,垂直领域里面某些项是支持离线识别的。但据说离线识别不太妥(百度方面说是SDK包的一个BUG,说近期会出一个新的包出来,但是从去年9月份到现在一直有人反映这个问题,百度给出的回答还是这样,估计是bug没解决还是怎样。)总之大家想用离线识别的话就可以看看百度提供的demo,里面就可以。不过有些网友反映还是不可以23333333

        还是那句话,大家要是怕麻烦,只是想试试百度语音识别的效果,那就不用去该参数,默认的就可以了。

设置了参数,可以有两种方式进行识别,一种是有API,一种是无API的,具体是什么区别呢?我说你就明白了,无API会调出百度定制”的dialog(别想了,你改不了),有API就没有那个dialog了,而且识别是一个字一个字识别,当你结束说话时识别结束。论识别准确率嘛,个人觉得是无api比较准确,要好看一点嘛,不想看到百度dialog的话,那就是有api比较妥了。但是无所谓了,能识别出来就是好的。

两种识别调用方式分别如下:

有api:
speechRecognizer.startListening(intent);
无api:
intent.setAction("com.baidu.action.RECOGNIZE_SPEECH");
startActivityForResult(intent, REQUEST_UI);


api识别结果的处理就是上面说到的onResult,具体要进行什么操作就看个位看官的了,然后无API的话要重写一下onActivityResult方法然后在里面调用onResult。这就是全部的识别流程了,贴出效果图

Baymax (Android版的Siri)之百度语音识别SDK调用_第1张图片   Baymax (Android版的Siri)之百度语音识别SDK调用_第2张图片


package chmel.android.baymax;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Contacts;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.speech.RecognitionListener;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.TextView;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.widget.Toast;


import com.baidu.speech.VoiceRecognitionService;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by xuan on 2016/3/10 0010.
 */
public class Mainactivity extends Activity implements RecognitionListener {

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);

        context=this;
        textResult=(TextView)findViewById(R.id.textResult );
        textLog=(TextView)findViewById(R.id.textLog);
        button=(ImageButton)findViewById(R.id.btn);

        //创建识别器
        speechRecognizer=SpeechRecognizer.createSpeechRecognizer(this,new ComponentName(this,VoiceRecognitionService.class));
        //识别器监听事件
        speechRecognizer.setRecognitionListener(this);
        //点击“开始”按钮事件
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                start();
            }
        });

    }

    //start()调用百度语音识别技术进行语音识别
    private void start() {
        Intent intent = new Intent();
        init(intent);
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        {

            String args = sp.getString("args", "");
            if (null != args) {
                intent.putExtra("args", args);
            }
        }


        boolean api = sp.getBoolean("api", false);
        if (api) {
            speechEndTime = -1;
            speechRecognizer.startListening(intent);
        } else {
            intent.setAction("com.baidu.action.RECOGNIZE_SPEECH");
            startActivityForResult(intent, REQUEST_UI);
        }
        textResult.setText("");
        textLog.setText("");
    }

    public void init(Intent intent){
        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);
        intent.putExtra(Constant.EXTRA_OFFLINE_SLOT_DATA, buildTestSlotData());
    }

    //导入离线数据
    private String buildTestSlotData() {
        JSONObject slotData = new JSONObject();
        JSONArray name = new JSONArray().put("张三").put("李四").put("王五");
        JSONArray app = new JSONArray().put("QQ").put("地图").put("微信").put("支付宝").put("知乎").put("网易云音乐")
                .put("美团").put("饿了么").put("京东").put("微博").put("去哪儿").put("贴吧");
        JSONArray usercommand = new JSONArray().put("关灯").put("开灯").put("相机").put("拍照").put("联系人").put("通信录");
        try {
            slotData.put(Constant.EXTRA_OFFLINE_SLOT_NAME, name);
            slotData.put(Constant.EXTRA_OFFLINE_SLOT_APP, app);
            slotData.put(Constant.EXTRA_OFFLINE_SLOT_USERCOMMAND, usercommand);
        } catch (JSONException e) {

        }
        return slotData.toString();
    }

    //识别结束结果返回
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            onResults(data.getExtras());
        }
    }

    @Override
    public void onReadyForSpeech(Bundle params) {

    }

    @Override
    public void onBeginningOfSpeech() {

    }

    @Override
    public void onRmsChanged(float rmsdB) {

    }

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

    }

    @Override
    public void onEndOfSpeech() {
        print("说完了");
    }

    @Override
    public void onError(int error) {

    }

    @Override
    public void onResults(Bundle results) {
        long end2finish = System.currentTimeMillis() - speechEndTime;
        ArrayList nbest = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
//        print("识别成功:" + Arrays.toString(nbest.toArray(new String[nbest.size()])));
        String strEnd2Finish = "";
        if (end2finish < 60 * 1000) {
            strEnd2Finish = "(waited " + end2finish + "ms)";
        }
        textResult.setText(nbest.get(0) + strEnd2Finish);
        //对识别结果进行分析
        recognize(nbest);
    }

    @Override
    public void onPartialResults(Bundle partialResults) {

    }

    @Override
    public void onEvent(int eventType, Bundle params) {

    }

    @Override
    protected void onDestroy() {
        speechRecognizer.destroy();
        super.onDestroy();
    }

    //对识别结果进行分析
    public void recognize(ArrayList nbest) {
        print("");
        int bool=0;
        for(int i=0;i



你可能感兴趣的:(Baymax)