语音识别主要的功能就是在用户不方便输入的时候找一个替代输入的选择。
1.本地语音识别
下面的代码首先创建SpeechRecognizer对象,并设置回调函数监听器。当在点击监听器中调用doSpeechRecognition()方法时,会使用语言参数和一个指示要在处理过程中分发部分结果的标志参数初始化语音识别。
public class MainActivity extends Activity implements View.OnClickListener{ private Button speechBut; private TextView result; private SpeechRecognizer mSpeechRecognizer;@Overridepublic void onClick(View v) { switch (v.getId()){ case R.id.speechBut: doSpeechRecognition(v); break;} } @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); this.speechBut=(Button)findViewById(R.id.speechBut); this.speechBut.setOnClickListener(this); this.result=(TextView)findViewById(R.id.result); this.mSpeechRecognizer=SpeechRecognizer.createSpeechRecognizer(this); this.mSpeechRecognizer.setRecognitionListener(new MyRecognitionListener());} public void doSpeechRecognition(View view){ view.setEnabled(false);Intent recognitionIntent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);recognitionIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS,true);recognitionIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"zh-CN"); this.mSpeechRecognizer.startListening(recognitionIntent);} private class MyRecognitionListener implements RecognitionListener{ @Overridepublic void onReadyForSpeech(Bundle params) { } @Overridepublic void onBeginningOfSpeech() { Log.i("llllllllllllllllllll","onBeginningOfSpeech");result.setText("");} @Overridepublic void onRmsChanged(float rmsdB) { } @Overridepublic void onBufferReceived(byte[] buffer) { } @Overridepublic void onEndOfSpeech() { Log.i("llllllllllllllllllll","onEndOfSpeech");speechBut.setEnabled(true);} @Overridepublic void onError(int error) { Log.i("llllllllllllllllllll","onError");speechBut.setEnabled(true);} @Overridepublic void onResults(Bundle results) { Log.i("llllllllllllllllllll","onResults");ArrayListpartialResults=results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if(partialResults!=null && partialResults.size()>0){ String bestResult=partialResults.get(0);result.setText(bestResult+".");} } @Overridepublic void onPartialResults(Bundle bundle) { Log.i("llllllllllllllllllll","onPartialResults");ArrayList partialResults=bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if(partialResults!=null && partialResults.size()>0){ String bestResult=partialResults.get(0);result.setText(bestResult);} } @Overridepublic void onEvent(int eventType, Bundle params) { } } @Overrideprotected void onDestroy() { super.onDestroy(); this.mSpeechRecognizer.destroy();}}
现在监听器会按照顺序接受每个方法的调用。本例在onPartialResult()方法中展现部分识别的结果,直到在onResult()方法中得到最终的结果。
一个更高级的应用程序还可以拦截单词,并监听特定的命令。这样一来,应用程序可以一直进行语音识别,直到用户明确告诉它停止-----例如,一个听写应用允许用户说“停止”单词并暂停一会后在句子间添加句号。
2.第三方语音识别(以讯飞为例)
我们大家都知道,一般Android手机是不支持中文语音识别的,我们有时候连文字转语音都要下载第三方文字转语音(TTS)API,更何况语音转文字。所以一般时候必须利用第三方提供SDK来丰富我们自己的应用功能。
就目前国内而言,在语音方面做的最好的也就属讯飞语音了。下面的开发以讯飞为例。
首先我们得到讯飞开放平台http://www.xfyun.cn/注册一个帐号。
然后如上图所示创建一个新应用,创建完应用后我们会得到如图所示的Appid:
然后下载相关的SDK包放到指定的位置,本文以Android Studio为例:
下面就可以进入开发阶段了,首先本例语音识别必须借助网络,所以本例需要的权限如下:
本来想讲解一下具体的代码突然觉得自己的代码已经注解够详细了,并不需要一句一句的讲解。相信大家都看的懂。
public class MainActivity extends Activity { private static String TAG = MainActivity.class.getSimpleName(); private Toast mToast; private Button showDialogs; private Button stop; private Button cancel; private TextView content;// 语音听写对象private SpeechRecognizer mIat;// 语音听写UIprivate RecognizerDialog mIatDialog;// 用HashMap存储听写结果private HashMapmIatResults = new LinkedHashMap ();// 引擎类型private String mEngineType = SpeechConstant.TYPE_CLOUD;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); this.showDialogs = (Button) findViewById(R.id.showDialogs); this.stop = (Button) findViewById(R.id.stopL); this.cancel=(Button)findViewById(R.id.cancel); this.content = (TextView) findViewById(R.id.content);SpeechUtility.createUtility(this, SpeechConstant.APPID + "=5566a1f6");// 初始化识别无UI识别对象 // 使用SpeechRecognizer对象,可根据回调消息自定义界面;mIat = SpeechRecognizer.createRecognizer(this, mInitListener);// 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源mIatDialog = new RecognizerDialog(MainActivity.this, mInitListener); this.showDialogs.setOnClickListener(new View.OnClickListener() { @Overridepublic void onClick(View v) { content.setText("");// 清空显示内容mIatResults.clear();myRecognize();// 显示听写对话框mIatDialog.show();showTip(getString(R.string.text_begin));} }); this.stop.setOnClickListener(new View.OnClickListener() { @Overridepublic void onClick(View v) { mIat.stopListening();showTip("停止听写");} }); this.cancel.setOnClickListener(new View.OnClickListener() { @Overridepublic void onClick(View v) { mIat.cancel();showTip("取消听写");} });} /** * 初始化监听器。 */private InitListener mInitListener = new InitListener() { @Overridepublic void onInit(int code) { Log.d(TAG, "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { showTip("初始化失败,错误码:" + code);} } }; private void showTip(final String str) { this.mToast.makeText(this,str,Toast.LENGTH_SHORT).show();} private void myRecognize() { // 清空参数mIat.setParameter(SpeechConstant.PARAMS, null);// 设置听写引擎mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);// 设置返回结果格式mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");//设置引擎为转写mIatDialog.setParameter(SpeechConstant.DOMAIN, "iat");//设置识别语言为中文mIatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");//设置方言为普通话mIatDialog.setParameter(SpeechConstant.ACCENT, "mandarin");//设置录音采样率为mIatDialog.setParameter(SpeechConstant.SAMPLE_RATE, "16000");//设置监听对象mIatDialog.setListener(recognizerDialogListener);// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理mIat.setParameter(SpeechConstant.VAD_BOS, "4000");// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音mIat.setParameter(SpeechConstant.VAD_EOS, "4000");// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点mIat.setParameter(SpeechConstant.ASR_PTT, "1");// 设置听写结果是否结果动态修正,为“1”则在听写过程中动态递增地返回结果,否则只在听写结束之后返回最终结果 // 注:该参数暂时只对在线听写有效mIat.setParameter(SpeechConstant.ASR_DWA, "0");} private RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() { @Overridepublic void onError(SpeechError error) { // TODO Auto-generated method stub} //当说话说完后,会回调该方法,JSON字符串在result@Overridepublic void onResult(RecognizerResult result, boolean isLast) { Log.d(TAG, result.getResultString());printResult(result);} }; private void printResult(RecognizerResult results) { String text = JsonParser.parseIatResult(results.getResultString());String sn = null;// 读取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));} content.setText(resultBuffer.toString());} @Overrideprotected void onDestroy() { super.onDestroy();// 退出时释放连接mIat.cancel();mIat.destroy();}}
当然里面有一个JSON解析,你可以自己写,也可以用SDK里面包装好的JsonParser类。
JSON解析不会的可以参考该网址
最后运行结果如下图所示:
版权声明:本文为博主原创文章,未经博主允许不得转载。