转载 android语音识别之科大讯飞语音API的使用

Android系统本身其实提供有语音识别模块,在它的APIDemo里也有关于语音识别的sample,不过经过大多开发者的真机测试,发现很多真机并不能使用哪个sample,在网上查找了一下原因,大部分是因为开发者在刷机的时候,大部分的ROM都阉割掉了语音识别和语音合成TTS(Text To Speech)部分,所以运行sample的时候会有异常抛出。

如果不用google提供的语音识别,要怎么实现语音识别喃?科大讯飞的语音API就可以到,这里是关于它的官网介绍:http://dev.voicecloud.cn/developer.php?vt=1 下面我就用一个简单的实例来介绍一下它基本的使用

首先做一个简单的界面

转载 android语音识别之科大讯飞语音API的使用

上面的TextView显示识别的内容,三个Button分别为语音识别,语音合成并朗读和语音后台朗读三个功能

布局文件:

[java] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?> 

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

  3.     android:layout_width="fill_parent" 

  4.     android:layout_height="fill_parent" 

  5.     android:orientation="vertical" > 

  6.  

  7.     <EditText 

  8.         android:id="@+id/et" 

  9.         android:layout_width="fill_parent" 

  10.         android:layout_height="wrap_content" /> 

  11.  

  12.     <Button 

  13.         android:id="@+id/bt_recognize" 

  14.         android:layout_width="fill_parent" 

  15.         android:layout_height="wrap_content" 

  16.         android:gravity="center" 

  17.         android:text="Recognize" /> 

  18.  

  19.     <Button 

  20.         android:id="@+id/bt_speek" 

  21.         android:layout_width="fill_parent" 

  22.         android:layout_height="wrap_content" 

  23.         android:gravity="center" 

  24.         android:text="Speek" /> 

  25.  

  26.     <Button 

  27.         android:id="@+id/bt_speek_bg" 

  28.         android:layout_width="fill_parent" 

  29.         android:layout_height="wrap_content" 

  30.         android:gravity="center" 

  31.         android:text="Speek-Background" /> 

  32.  

  33. </LinearLayout> 

[java] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>  

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  3.     android:layout_width="fill_parent"  

  4.     android:layout_height="fill_parent"  

  5.     android:orientation="vertical" >  

  6.   

  7.     <EditText  

  8.         android:id="@+id/et"  

  9.         android:layout_width="fill_parent"  

  10.         android:layout_height="wrap_content" />  

  11.   

  12.     <Button  

  13.         android:id="@+id/bt_recognize"  

  14.         android:layout_width="fill_parent"  

  15.         android:layout_height="wrap_content"  

  16.         android:gravity="center"  

  17.         android:text="Recognize" />  

  18.   

  19.     <Button  

  20.         android:id="@+id/bt_speek"  

  21.         android:layout_width="fill_parent"  

  22.         android:layout_height="wrap_content"  

  23.         android:gravity="center"  

  24.         android:text="Speek" />  

  25.   

  26.     <Button  

  27.         android:id="@+id/bt_speek_bg"  

  28.         android:layout_width="fill_parent"  

  29.         android:layout_height="wrap_content"  

  30.         android:gravity="center"  

  31.         android:text="Speek-Background" />  

  32.   

  33. </LinearLayout>  


Activity代码如下:

[java] view plaincopy

  1. package sina.CreAmazing.voice; 

  2.  

  3. import java.util.ArrayList; 

  4.  

  5. import com.iflytek.speech.RecognizerResult; 

  6. import com.iflytek.speech.SpeechError; 

  7. import com.iflytek.speech.SynthesizerPlayer; 

  8. import com.iflytek.ui.RecognizerDialog; 

  9. import com.iflytek.ui.RecognizerDialogListener; 

  10. import com.iflytek.ui.SynthesizerDialog; 

  11. import com.iflytek.ui.SynthesizerDialogListener; 

  12.  

  13. import android.app.Activity; 

  14. import android.os.Bundle; 

  15. import android.view.View; 

  16. import android.view.View.OnClickListener; 

  17. import android.widget.Button; 

  18. import android.widget.EditText; 

  19.  

  20. public class Voice1Activity extends Activity { 

  21.     /** Called when the activity is first created. */ 

  22.     // 声明控件 

  23.     private EditText et; 

  24.     private Button bt1; 

  25.     private Button bt2; 

  26.     private Button bt3; 

  27.     //全局只设一个String,因为String为final类型,这样做节省内存 

  28.     String text = ""

  29.     private static final String APPID = "appid=4f2d3a06"

  30.  

  31.     @Override 

  32.     public void onCreate(Bundle savedInstanceState) { 

  33.         super.onCreate(savedInstanceState); 

  34.         setContentView(R.layout.main); 

  35.         bt1 = (Button) findViewById(R.id.bt_recognize); 

  36.         bt2 = (Button) findViewById(R.id.bt_speek); 

  37.         bt3 = (Button) findViewById(R.id.bt_speek_bg); 

  38.         et = (EditText) findViewById(R.id.et); 

  39.         // 初始化监听器 

  40.         initListener(); 

  41.  

  42.     } 

  43.  

  44.     private void initListener() { 

  45.         bt1.setOnClickListener(myListener); 

  46.         bt2.setOnClickListener(myListener); 

  47.         bt3.setOnClickListener(myListener); 

  48.  

  49.     } 

  50.  

  51.     OnClickListener myListener = new OnClickListener() { 

  52.  

  53.         @Override 

  54.         public void onClick(View v) { 

  55.             // 根据不同View的id调用不同方法 

  56.             switch (v.getId()) { 

  57.             case R.id.bt_recognize: 

  58.                 // 这是语言识别部分,最重要的实例化一个 

  59.                 // RecognizerDialog并把你在官方网站申请的appid填入进去,非法id不能进行识别 

  60.                 RecognizerDialog isrDialog = new RecognizerDialog( 

  61.                         Voice1Activity.this, APPID); 

  62.  

  63.                 /*

  64.                  * 设置引擎目前支持五种 ”sms”:普通文本转写 “poi”:地名搜索 ”vsearch”:热词搜索

  65.                  * ”video”:视频音乐搜索 ”asr”:命令词识别

  66.                  */ 

  67.                 isrDialog.setEngine("sms"nullnull); 

  68.                 isrDialog.setListener(recoListener); 

  69.                 isrDialog.show(); 

  70.                 break

  71.             case R.id.bt_speek: 

  72.                 // 这是语言合成部分 同样需要实例化一个SynthesizerDialog ,并输入appid 

  73.                 SynthesizerDialog syn = new SynthesizerDialog( 

  74.                         Voice1Activity.this, APPID); 

  75.                 syn.setListener(new SynthesizerDialogListener() { 

  76.  

  77.                     @Override 

  78.                     public void onEnd(SpeechError arg0) { 

  79.  

  80.                     } 

  81.                 }); 

  82.                 // 根据EditText里的内容实现语音合成 

  83.                 syn.setText(et.getText().toString(), null); 

  84.                 syn.show(); 

  85.                 break

  86.             case R.id.bt_speek_bg: 

  87.                 // 这是后台朗读,实例化一个SynthesizerPlayer 

  88.                 SynthesizerPlayer player = SynthesizerPlayer 

  89.                         .createSynthesizerPlayer(Voice1Activity.this, APPID); 

  90.                 // 设置语音朗读者,可以根据需要设置男女朗读,具体请看api文档和官方论坛 

  91.                 player.setVoiceName("vivixiaomei"); 

  92.                 player.playText(et.getText().toString(), "ent=vivi21,bft=5"

  93.                         null); 

  94.                 break

  95.             default

  96.                 break

  97.             } 

  98.  

  99.         } 

  100.     }; 

  101.     // 语言识别监听器,有两个方法 

  102.     RecognizerDialogListener recoListener = new RecognizerDialogListener() { 

  103.  

  104.         @Override 

  105.         public void onResults(ArrayList<RecognizerResult> results, 

  106.                 boolean isLast) { 

  107.             // 服务器识别完成后会返回集合,我们这里就只得到最匹配的那一项 

  108.             text += results.get(0).text; 

  109.             System.out.println(text); 

  110.         } 

  111.  

  112.         @Override 

  113.         public void onEnd(SpeechError error) { 

  114.             if (error == null) { 

  115.                 // 完成后就把结果显示在EditText上 

  116.                 et.setText(text); 

  117.             } 

  118.  

  119.         } 

  120.  

  121.     }; 

  122.  

[java] view plaincopy

  1. package sina.CreAmazing.voice;  

  2.   

  3. import java.util.ArrayList;  

  4.   

  5. import com.iflytek.speech.RecognizerResult;  

  6. import com.iflytek.speech.SpeechError;  

  7. import com.iflytek.speech.SynthesizerPlayer;  

  8. import com.iflytek.ui.RecognizerDialog;  

  9. import com.iflytek.ui.RecognizerDialogListener;  

  10. import com.iflytek.ui.SynthesizerDialog;  

  11. import com.iflytek.ui.SynthesizerDialogListener;  

  12.   

  13. import android.app.Activity;  

  14. import android.os.Bundle;  

  15. import android.view.View;  

  16. import android.view.View.OnClickListener;  

  17. import android.widget.Button;  

  18. import android.widget.EditText;  

  19.   

  20. public class Voice1Activity extends Activity {  

  21.     /** Called when the activity is first created. */  

  22.     // 声明控件  

  23.     private EditText et;  

  24.     private Button bt1;  

  25.     private Button bt2;  

  26.     private Button bt3;  

  27.     //全局只设一个String,因为String为final类型,这样做节省内存  

  28.     String text = "";  

  29.     private static final String APPID = "appid=4f2d3a06";  

  30.   

  31.     @Override  

  32.     public void onCreate(Bundle savedInstanceState) {  

  33.         super.onCreate(savedInstanceState);  

  34.         setContentView(R.layout.main);  

  35.         bt1 = (Button) findViewById(R.id.bt_recognize);  

  36.         bt2 = (Button) findViewById(R.id.bt_speek);  

  37.         bt3 = (Button) findViewById(R.id.bt_speek_bg);  

  38.         et = (EditText) findViewById(R.id.et);  

  39.         // 初始化监听器  

  40.         initListener();  

  41.   

  42.     }  

  43.   

  44.     private void initListener() {  

  45.         bt1.setOnClickListener(myListener);  

  46.         bt2.setOnClickListener(myListener);  

  47.         bt3.setOnClickListener(myListener);  

  48.   

  49.     }  

  50.   

  51.     OnClickListener myListener = new OnClickListener() {  

  52.   

  53.         @Override  

  54.         public void onClick(View v) {  

  55.             // 根据不同View的id调用不同方法  

  56.             switch (v.getId()) {  

  57.             case R.id.bt_recognize:  

  58.                 // 这是语言识别部分,最重要的实例化一个  

  59.                 // RecognizerDialog并把你在官方网站申请的appid填入进去,非法id不能进行识别  

  60.                 RecognizerDialog isrDialog = new RecognizerDialog(  

  61.                         Voice1Activity.this, APPID);  

  62.   

  63.                 /* 

  64.                  * 设置引擎目前支持五种 ”sms”:普通文本转写 “poi”:地名搜索 ”vsearch”:热词搜索 

  65.                  * ”video”:视频音乐搜索 ”asr”:命令词识别 

  66.                  */  

  67.                 isrDialog.setEngine("sms"nullnull);  

  68.                 isrDialog.setListener(recoListener);  

  69.                 isrDialog.show();  

  70.                 break;  

  71.             case R.id.bt_speek:  

  72.                 // 这是语言合成部分 同样需要实例化一个SynthesizerDialog ,并输入appid  

  73.                 SynthesizerDialog syn = new SynthesizerDialog(  

  74.                         Voice1Activity.this, APPID);  

  75.                 syn.setListener(new SynthesizerDialogListener() {  

  76.   

  77.                     @Override  

  78.                     public void onEnd(SpeechError arg0) {  

  79.   

  80.                     }  

  81.                 });  

  82.                 // 根据EditText里的内容实现语音合成  

  83.                 syn.setText(et.getText().toString(), null);  

  84.                 syn.show();  

  85.                 break;  

  86.             case R.id.bt_speek_bg:  

  87.                 // 这是后台朗读,实例化一个SynthesizerPlayer  

  88.                 SynthesizerPlayer player = SynthesizerPlayer  

  89.                         .createSynthesizerPlayer(Voice1Activity.this, APPID);  

  90.                 // 设置语音朗读者,可以根据需要设置男女朗读,具体请看api文档和官方论坛  

  91.                 player.setVoiceName("vivixiaomei");  

  92.                 player.playText(et.getText().toString(), "ent=vivi21,bft=5",  

  93.                         null);  

  94.                 break;  

  95.             default:  

  96.                 break;  

  97.             }  

  98.   

  99.         }  

  100.     };  

  101.     // 语言识别监听器,有两个方法  

  102.     RecognizerDialogListener recoListener = new RecognizerDialogListener() {  

  103.   

  104.         @Override  

  105.         public void onResults(ArrayList<RecognizerResult> results,  

  106.                 boolean isLast) {  

  107.             // 服务器识别完成后会返回集合,我们这里就只得到最匹配的那一项  

  108.             text += results.get(0).text;  

  109.             System.out.println(text);  

  110.         }  

  111.   

  112.         @Override  

  113.         public void onEnd(SpeechError error) {  

  114.             if (error == null) {  

  115.                 // 完成后就把结果显示在EditText上  

  116.                 et.setText(text);  

  117.             }  

  118.   

  119.         }  

  120.   

  121.     };  

  122.   

  123. }  


最后别忘了把科大讯飞的jar包引入工程的buildPath里面。

运行画面:

语音识别:转载 android语音识别之科大讯飞语音API的使用转载 android语音识别之科大讯飞语音API的使用

语音合成:转载 android语音识别之科大讯飞语音API的使用

其实功能还不止这些,还有数据上传,关键字识别,获取上行下行流量,设置采样频率设置发音人,语速,音量等等等,如果感兴趣可以自己深入研究。

 

 

接上文,如何实现语音控制呢?比如当我们说天气的时候,界面会自动呈现的天气预报的界面,当我们说UC的时候,会自动跳转到UC浏览器上等等。其实方法很简单,仅仅需要对识别到的字符串进行判断,当它符合特定的字符串是就对Activity进行跳转,跳转到自己写好的Activity上,或者跳转到已安装的应用上,下面来看具体怎么实现:

首先我们在layout布局里增加一个ToggleButton用于开关语音控制:

转载 android语音识别之科大讯飞语音API的使用

然后我们就在获取结果的RecognizerDialogListener下面改变几行代码:

[java] view plaincopy

  1. RecognizerDialogListener recoListener = new RecognizerDialogListener() { 

  2.  

  3.         @Override 

  4.         public void onResults(ArrayList<RecognizerResult> results, 

  5.                 boolean isLast) { 

  6. //新增加了一个ToggleButton tb,首先检查tb是否被按下,如果被按下才进行语言控制,没被按下就进行文字识别             

  7.             if (tb.isChecked()) { 

  8. //doVoice方法就是进行识别                

  9.                 doVoice(results); 

  10.             } else { 

  11.                 // 服务器识别完成后会返回集合,我们这里就只得到最匹配的那一项 

  12.                 text += results.get(0).text; 

  13.                 System.out.println(text); 

  14.             } 

  15.  

  16.         } 

[java] view plaincopy

  1. RecognizerDialogListener recoListener = new RecognizerDialogListener() {  

  2.   

  3.         @Override  

  4.         public void onResults(ArrayList<RecognizerResult> results,  

  5.                 boolean isLast) {  

  6. //新增加了一个ToggleButton tb,首先检查tb是否被按下,如果被按下才进行语言控制,没被按下就进行文字识别              

  7.             if (tb.isChecked()) {  

  8. //doVoice方法就是进行识别                 

  9.                 doVoice(results);  

  10.             } else {  

  11.                 // 服务器识别完成后会返回集合,我们这里就只得到最匹配的那一项  

  12.                 text += results.get(0).text;  

  13.                 System.out.println(text);  

  14.             }  

  15.   

  16.         }  

如果进行语言识别就把返回的结果传入上面的doVoice方法里,doVoice如下:

[java] view plaincopy

  1. //首先迭代结果,然后获取每个结果,并进行对比,如果包含有特定字符串,那么就执行相应Intent跳转。 

  2. //注意 凡是Intent能办到的(发邮件,跳到已安装应用,拨号,发短信,发彩信,浏览网页,播放多媒体。。。。),它就都能办到。         

  3.         private void doVoice(ArrayList<RecognizerResult> results) { 

  4.             Intent i = new Intent(); 

  5.             for(RecognizerResult result : results){ 

  6.                 if(result.text.contains("天气")){ 

  7.                     //天气界面的跳转 

  8.                     i.setClass(Voice1Activity.this, Weather.class); 

  9.                     startActivity(i); 

  10.                 }else if(result.text.contains("新闻")){ 

  11.                     //新闻界面的跳转 

  12.                     i.setClass(Voice1Activity.this, News.class); 

  13.                     startActivity(i); 

  14.                 }else if(result.text.contains("短信")){ 

  15.                     //短信界面的跳转 

  16.                     i.setAction(Intent.ACTION_VIEW); 

  17.                     i.setType("vnd.android-dir/mms-sms"); 

  18.                     startActivity(i); 

  19.                 }else

  20.                     //如果没有相应指令就用Toast提示用户 

  21.                     Toast.makeText(Voice1Activity.this"无法识别", Toast.LENGTH_SHORT).show(); 

  22.                 } 

  23.             } 

  24.              

  25.         } 

[java] view plaincopy

  1. //首先迭代结果,然后获取每个结果,并进行对比,如果包含有特定字符串,那么就执行相应Intent跳转。  

  2. //注意 凡是Intent能办到的(发邮件,跳到已安装应用,拨号,发短信,发彩信,浏览网页,播放多媒体。。。。),它就都能办到。          

  3.         private void doVoice(ArrayList<RecognizerResult> results) {  

  4.             Intent i = new Intent();  

  5.             for(RecognizerResult result : results){  

  6.                 if(result.text.contains("天气")){  

  7.                     //天气界面的跳转  

  8.                     i.setClass(Voice1Activity.this, Weather.class);  

  9.                     startActivity(i);  

  10.                 }else if(result.text.contains("新闻")){  

  11.                     //新闻界面的跳转  

  12.                     i.setClass(Voice1Activity.this, News.class);  

  13.                     startActivity(i);  

  14.                 }else if(result.text.contains("短信")){  

  15.                     //短信界面的跳转  

  16.                     i.setAction(Intent.ACTION_VIEW);  

  17.                     i.setType("vnd.android-dir/mms-sms");  

  18.                     startActivity(i);  

  19.                 }else{  

  20.                     //如果没有相应指令就用Toast提示用户  

  21.                     Toast.makeText(Voice1Activity.this"无法识别", Toast.LENGTH_SHORT).show();  

  22.                 }  

  23.             }  

  24.               

  25.         }  

如下是做得相应简单界面:

转载 android语音识别之科大讯飞语音API的使用转载 android语音识别之科大讯飞语音API的使用转载 android语音识别之科大讯飞语音API的使用转载 android语音识别之科大讯飞语音API的使用

其实在主UI里执行那么耗时操作比如语音的识别与控制并不是很好的方法,其实完全可以把这些耗时的操作交给Service来做只要在主Activity的开始,启动一个Service,定义好各种逻辑接口并把那些耗时的操作交给Service就行了,在Service里面实现语音的识别,控制和逻辑的跳转。


你可能感兴趣的:(转载 android语音识别之科大讯飞语音API的使用)