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

来源:互联网 发布:python 缺省 编辑:程序博客网 时间:2024/04/29 04:41

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

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

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

<span style="font-size:14px;"><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" /></span> 
 然后是填上自己在百度申请到的秘钥<!--请填写应用实际的APP_ID --> <meta-dataandroid:name="com.baidu.speech.APP_ID"android:value="your app id"/><!--请填写应用实际的API_KEY --><meta-dataandroid:name="com.baidu.speech.API_KEY"android:value="your api key"/><!--请填写应用实际的SECRET_KEY --><meta-dataandroid:name="com.baidu.speech.SECRET_KEY"android:value="your api secret"/>

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


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

<span style="font-size:18px;"> //创建识别器speechRecognizer=SpeechRecognizer.createSpeechRecognizer(this,new ComponentName(this,VoiceRecognitionService.class)); //识别器监听事件speechRecognizer.setRecognitionListener(this);</span>

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

@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需要设置的参数不少,当然也可以全都默认,个人觉得挺好的,可以适应不同环境做识别,提高准确率。这里也是大概讲一下哪些参数可能要用到


<span style="font-size:14px;">①提示音(默认是静音)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,   );</span>


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

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

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

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

<span style="font-size:18px;">有api:speechRecognizer.startListening(intent);无api:intent.setAction("com.baidu.action.RECOGNIZE_SPEECH");startActivityForResult(intent, REQUEST_UI);</span>


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

   


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<String> 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<String> nbest) {        print("");        int bool=0;        for(int i=0;i<nbest.size();i++){            String temp=nbest.get(i);            if(openApp(temp)){                bool++;                break;            }            else if(temp.contains("开")&&temp.contains("灯")){                openCloseLight(0);                bool++;                break;            }else if(temp.contains("关")&&temp.contains("灯")){                openCloseLight(1);                bool++;                break;            }else if(temp.contains("相机")||temp.contains("拍照")||temp.contains("照相")){                bool++;                openCamera();                break;            } else if(temp.contains("电")&&temp.contains("话")){                bool++;                openTel();                break;            }else if(temp.contains("联系人")){                bool++;                openContacts();                break;            }else if(temp.contains("短信")||temp.contains("信息")){                bool++;                openMess();                break;            }else if(temp.contains("搜索")){                bool++;                String keyword=temp.substring(2);                search(keyword);                break;            }            else if(temp.contains("退下") || temp.contains("下去")) {                finish();                break;            }        }        if(bool==0){            print("抱歉我没有听清楚");        }    }       //打印日记    public void print(String msg) {        textLog.setText(msg);        Log.d(TAG, "----" + msg);    }    //打开相机    public void openCamera(){        if(!isOpen) {            print("马上为您打开相机");            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);            startActivity(intent);        }else{            print("相机打开失败");        }    }    //打开短信界面    public void openMess(){        print("马上为您打开短信");        Intent intent = new Intent(Intent.ACTION_VIEW);        intent.setType("vnd.android-dir/mms-sms");        startActivity(intent);    }    //打开联系人界面    public void openContacts(){        print("马上为您打开联系人");        Intent intent = new Intent();        intent.setAction(Intent.ACTION_VIEW);        intent.setData(Contacts.People.CONTENT_URI);        startActivity(intent);    }  }



1 0
原创粉丝点击