Android第三方服务(1):语音识别(1)

  App开发中为了让软件功能更加强大,经常会引用许多的第三方框架或服务,其中可能会碰到这样一种场景,让用户语音输入,App接受用户的输入信息,做出相应的相应,这就是所谓的语音识别,当然这也是最基础最简单的语音识别,还有什么语音听写、在线语音合成、开发语义、人脸识别、声纹识别、语音唤醒等等。

  关于Android的语音识别,首先是大多模拟器没法模拟,需要用真机来测试。

  Android原生系统自带有语音识别模块,不过由于后台是访问Google云服务器数据,基于中国的国情,是没法真正的使用的。因此寻找一种替代是自然而然的事情,现在提供语音识别的平台有很多,在此提供两种解决方案,百度语音识别(百度语音官网:http://yuyin.baidu.com/)和讯飞语音识别(讯飞开发平台官网:http://www.xfyun.cn/),以下简单介绍基于它们平台的语音识别开发。

  一、基于百度语音SDK的语音识别功能开发

    第一步:在官网http://yuyin.baidu.com/注册帐号(必须),成为开发者。

     第二步: 在官网创建一个应用(获取相应的APP key,Secret Key),开通服务(语音识别必须开通).      

   第三步:下载SDK,解压。

      

   上图为SDK解压后得到的文件,其中docs文件夹为可参考的文档,libs是自己创建语音识别工程必须导入的包,

res是可能在语音识别需要的一些语音文件,最下面是一个Demo。其实以上三步算起来是一步,不过是为了获取SDK和相应

的key.

  第四步:本地创建Android标准工程,导入SDK中的libs文件夹下所有的文件。

  第五步:工程配置和功能代码实现。

      权限:

1 <!-- 语音识别-->
2     <uses-permission android:name="android.permission.INTERNET" />
3     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
4     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
6 
7     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
8     <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
9     <uses-permission android:name="android.permission.BLUETOOTH"/>

     核心代码:

 1 public void btnVoice(View view) {
 2         Bundle params = new Bundle();
 3 
 4         //设置开放平台 API Key
 5         params.putString(BaiduASRDigitalDialog.PARAM_API_KEY, "3xMq8l8AtQw8WeZjqMaLyd4f");
 6         //设置开放平台 Secret Key
 7         params.putString(BaiduASRDigitalDialog.PARAM_SECRET_KEY, "48b2df134266594bd39b375b40d04e1f");
 8         //设置识别领域:搜索、输入、地图、音乐……,可选。默认为输入。
 9         params.putInt(BaiduASRDigitalDialog.PARAM_PROP, VoiceRecognitionConfig.PROP_INPUT);
10         //设置语种类型:中文普通话,中文粤语,英文,可选。默认为中文普通话
11         params.putString(BaiduASRDigitalDialog.PARAM_LANGUAGE, VoiceRecognitionConfig.LANGUAGE_CHINESE);
12         //如果需要语义解析,设置下方参数。领域为输入不支持
13         params.putBoolean(BaiduASRDigitalDialog.PARAM_NLU_ENABLE, true);
14         // 设置对话框主题,可选。BaiduASRDigitalDialog 提供了蓝、暗、红、绿、橙四中颜色,每种颜色又分亮、暗两种色调。
15         // 共 8 种主题,开发者可以按需选择,取值参考 BaiduASRDigitalDialog 中前缀为 THEME_的常量。默认为亮蓝色
16         params.putInt(BaiduASRDigitalDialog.PARAM_DIALOG_THEME, BaiduASRDigitalDialog.THEME_RED_DEEPBG);
17 
18         voiceDialog = new BaiduASRDigitalDialog(this, params);
19         voiceDialog.setDialogRecognitionListener(new DialogRecognitionListener() {
20             @Override
21             public void onResults(Bundle results) {
22                 // 在Results中获取Key 为DialogRecognitionListener .RESULTS_RECOGNITION的StringArrayList,
23                 // 可能为空。获取到识别结果后执行相应的业务逻辑即可,此回调会在主线程调用。
24                 ArrayList<String> rs = results != null ? results
25                         .getStringArrayList(RESULTS_RECOGNITION) : null;
26                 if (rs != null) {
27                     //此处处理识别结果,识别结果可能有多个,按置信度从高到低排列,第一个元素是置信度最高的结果。
28 
29                     Toast.makeText(MainActivity.this,rs.get(0),Toast.LENGTH_LONG).show();
30                 }
31             }
32         });
33         
34         voiceDialog.show();
35     }

  这里是当点击按钮时,开启语音识别功能。   

  第5行和第7行分别要传入两个参数APP key/Secret key,其中需要注意的是这两个key要和你下载的SDK是一一对应的,也就是说不同的SDK对于的key是不相同的,否则可能没法实现

语音识别。

  

  ----------------------------------------------------必须加以说明的分割线----------------------------------------------------

    完成以上所有的工作可能任然没法实现语音功能(个人使用的是IDEA的Gradle标准Android工程),出现下面的一种情景:

    

    那么该工程对应的libs可能应该这样,so文件对应的多个文件夹

    

    如果任然不能解决问题,提示是这样的,

    

    那么你可以在build.gradle中的android下加上这个

1 sourceSets {
2         main {
3             jniLibs.srcDirs = ['libs']
4         }
5     }

  效果图:

  

  可以看到百度的语音识别带有百度的样式,不太美观,你可以试着修改它的样式,当然还有一种方式是使用下面的基于讯飞语音SDK的语音识别功能开发,实际使用可能更方便一些。

  二、基于讯飞语音SDK的语音识别功能开发

   讯飞开发平台:http://www.xfyun.cn/

   对于讯飞语音识别,可以说是专家级的,在其官网可以看见有很多强大的功能,而百度语音仅仅提供的是语音识别和语音合成,因此推荐使用讯飞的,更加专业。

  

   第一步:在官网注册帐号,创建新应用,开通语音听写服务(基础的,这里要用到),下载该应用对应的SDK,解压,拷相应的文件到本地创建的安卓工程。      

    

  第二步:

  初始化代码,后面参数为创建应用的APPID,需要注意的是这个APPid要和你下载的SDK是一一对应的,也就是说不同的SDK对于的key是不相同的,否则可能没法实现

1         SpeechUtility.createUtility(this, SpeechConstant.APPID+"=563aff8a");

  

  核心代码:

 1 public void btnVoice(View view) {
 2 
 3         RecognizerDialog dialog = new RecognizerDialog(this,null);
 4         dialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");
 5         dialog.setParameter(SpeechConstant.ACCENT,"mandarin");
 6 
 7         dialog.setListener(new RecognizerDialogListener() {
 8             @Override
 9             public void onResult(RecognizerResult recognizerResult, boolean b) {
10                 printResult(recognizerResult);
11             }
12 
13             @Override
14             public void onError(SpeechError speechError) {
15 
16             }
17         });
18 
19         dialog.show();
20         Toast.makeText(this,"请开始说话",Toast.LENGTH_SHORT).show();
21 
22     }
23 
24     private void printResult(RecognizerResult results) {
25         String text = JsonParser.parseIatResult(results.getResultString());
26 
27         TextView textView = (TextView) findViewById(R.id.textView);
28         textView.append(text);
29     }
语音识别

  

  由于语音识别返回的是形如下列的Json字符串,当语音输入"安卓"

1 {"sn":1,"ls":false,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"sc":-108.95,"w":"安卓"}]}]}

 

  因此创建其解析类

 1 public class JsonParser {
 2 
 3     public static String parseIatResult(String json) {
 4         StringBuffer ret = new StringBuffer();
 5         try {
 6             JSONTokener tokener = new JSONTokener(json);
 7             JSONObject joResult = new JSONObject(tokener);
 8 
 9             JSONArray words = joResult.getJSONArray("ws");
10             for (int i = 0; i < words.length(); i++) {
11                 // 转写结果词,默认使用第一个结果
12                 JSONArray items = words.getJSONObject(i).getJSONArray("cw");
13                 JSONObject obj = items.getJSONObject(0);
14                 ret.append(obj.getString("w"));
15 //                如果需要多候选结果,解析数组其他字段
16 //                for(int j = 0; j < items.length(); j++)
17 //                {
18 //                    JSONObject obj = items.getJSONObject(j);
19 //                    ret.append(obj.getString("w"));
20 //                }
21             }
22         } catch (Exception e) {
23             e.printStackTrace();
24         } 
25         return ret.toString();
26     }
27 
28 }
对语音识别返回结果的解析类

 如果出现如下提示,

  

 那么你可以在build.gradle中的android下加上这个

1 sourceSets {
2         main {
3             jniLibs.srcDirs = ['libs']
4         }
5     }

  

 效果图:

  

     源码下载:链接: http://pan.baidu.com/s/1bpozc 密码: 67bz

    未完,待续。

原文地址:https://www.cnblogs.com/enjoy-coding/p/4940752.html