在 科大讯飞开放平台——语音听写接口的使用 这篇文章里介绍了科大讯飞语音听写接口的简单使用方法,但是在实际开发中发现仅仅那样做在使用起来还是不方便,于是想到把语音听写接口的调用、Json数据解析、听写结果的处理等操作进行封装,使用异步回调的方式进行调用,这样在使用到语音听写的地方只需创建一个监听接口并重写语音识别返回结果的处理方法即可。梳理了一下步骤如下:
(一)前期准备工作(略,见科大讯飞开放平台——语音听写接口的使用一文)
注:将获取到的AppId存到一个常量类里,后面便于管理:
1 public class GlobalConfig { 2 // 科大讯飞语音SDK AppID 3 public static final String IFLY_VOICE_SDK_APP_ID = "570657ad"; 4 }
(二)创建用GSON解析Json数据的通用工具类GsonUtil,用于为解析语音听写服务器返回的Json格式数据做准备:
1 import java.util.ArrayList; 2 import java.util.List; 3 4 import com.google.gson.Gson; 5 import com.google.gson.JsonArray; 6 import com.google.gson.JsonElement; 7 import com.google.gson.JsonParser; 8 9 /* 10 * 封装的GSON解析工具类,提供泛型参数方法 11 * 12 */ 13 public class GsonUtil { 14 // 将单条Json数据解析成相应的映射对象 15 public static <T> T parseJsonWithGson(String jsonData, Class<T> type) { 16 Gson gson = new Gson(); 17 T result = gson.fromJson(jsonData, type); 18 return result; 19 } 20 21 // 将Json数组解析成相应的映射对象列表 22 public static <T> List<T> parseJsonArrayWithGson(String jsonData, 23 Class<T> type) { 24 Gson gson = new Gson(); 25 List<T> result = new ArrayList<T>(); 26 27 // 下面这句因为泛型在编译期类型会被擦除,从而导致如下错误: 28 // java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap 29 // cannot be cast to DictationResult 30 // List<T> result = gson.fromJson(jsonData, new TypeToken<List<T>>() { 31 // }.getType()); 32 33 // 正确写法 34 JsonArray array = new JsonParser().parse(jsonData).getAsJsonArray(); 35 for (final JsonElement elem : array) { 36 result.add(new Gson().fromJson(elem, type)); 37 } 38 39 return result; 40 } 41 }
(三)创建专门解析语音听写结果Json数据的工具类DictationJsonParseUtil,用于解析科大讯飞语音听写服务器返回的Json数据:
1 import java.util.List; 2 3 /** 4 * 用于解析科大讯飞语音听写服务器返回的Json数据 5 * 6 * 语音识别结果Json数据格式: 7 * {"sn":1,"ls":true,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"w":"今天","sc":0}]}, 8 * {"bg":0,"cw":[{"w":"的","sc":0}]},{"bg":0,"cw":[{"w":"天气","sc":0}]}, 9 * {"bg":0,"cw":[{"w":"怎么样","sc":0}]},{"bg":0,"cw":[{"w":"。","sc":0}]}]} 10 */ 11 public class DictationJsonParseUtil { 12 13 // 解析服务器返回的语音听写结果Json格式数据的静态方法,返回值为语音的字符串 14 public static String parseJsonData(String jsonDataStr) { 15 String speechStr = ""; 16 List<DictationResult> resultList = GsonUtil.parseJsonArrayWithGson( 17 jsonDataStr, DictationResult.class); 18 19 for (int i = 0; i < resultList.size() - 1; i++) { // 这里减1是因为最后有一组作为结尾的标点符号数据,要舍去 20 speechStr += resultList.get(i).toString(); 21 } 22 23 return speechStr; 24 } 25 } 26 27 // 语音听写结果类 28 class DictationResult { 29 private String sn; 30 private String ls; 31 private String bg; 32 private String ed; 33 34 private List<Words> ws; 35 36 public static class Words { 37 private String bg; 38 private List<Cw> cw; 39 40 public static class Cw { 41 private String w; 42 private String sc; 43 44 public String getW() { 45 return w; 46 } 47 48 public void setW(String w) { 49 this.w = w; 50 } 51 52 public String getSc() { 53 return sc; 54 } 55 56 public void setSc(String sc) { 57 this.sc = sc; 58 } 59 60 @Override 61 public String toString() { 62 return w; 63 } 64 } 65 66 public String getBg() { 67 return bg; 68 } 69 70 public void setBg(String bg) { 71 this.bg = bg; 72 } 73 74 public List<Cw> getCw() { 75 return cw; 76 } 77 78 public void setCw(List<Cw> cw) { 79 this.cw = cw; 80 } 81 82 @Override 83 public String toString() { 84 String result = ""; 85 for (Cw cwTmp : cw) { 86 result += cwTmp.toString(); 87 } 88 return result; 89 } 90 } 91 92 public String getSn() { 93 return sn; 94 } 95 96 public void setSn(String sn) { 97 this.sn = sn; 98 } 99 100 public String getLs() { 101 return ls; 102 } 103 104 public void setLs(String ls) { 105 this.ls = ls; 106 } 107 108 public String getBg() { 109 return bg; 110 } 111 112 public void setBg(String bg) { 113 this.bg = bg; 114 } 115 116 public String getEd() { 117 return ed; 118 } 119 120 public void setEd(String ed) { 121 this.ed = ed; 122 } 123 124 public List<Words> getWs() { 125 return ws; 126 } 127 128 public void setWs(List<Words> ws) { 129 this.ws = ws; 130 } 131 132 @Override 133 public String toString() { 134 String result = ""; 135 for (Words wsTmp : ws) { 136 result += wsTmp.toString(); 137 } 138 return result; 139 } 140 }
(四)创建语音听写结果监听接口DictationListener,提供一个onDictationListener(String dictationResultStr)方法,调用方可以重写该方法,对语音听写结果进行其他操作。
1 /** 2 * 科大讯飞语音解析结果返回监听接口 3 * 4 */ 5 public interface DictationListener { 6 public abstract void onDictationListener(String dictationResultStr); 7 }
(五)创建DictationUtil类,其showDictationDialog方法会弹出语音听写Dialog窗口,并对语音返回结果进行解析得到最终结果,最后用onDictationListener接口来将最终结果传送给调用方。
1 import android.content.Context; 2 3 import com.easydo.constant.GlobalConfig; 4 import com.iflytek.cloud.RecognizerResult; 5 import com.iflytek.cloud.SpeechConstant; 6 import com.iflytek.cloud.SpeechError; 7 import com.iflytek.cloud.SpeechRecognizer; 8 import com.iflytek.cloud.SpeechUtility; 9 import com.iflytek.cloud.ui.RecognizerDialog; 10 import com.iflytek.cloud.ui.RecognizerDialogListener; 11 12 /** 13 * 语音听写工具类,用于弹出语音听写Dialog进行听写 14 * 15 */ 16 17 public class DictationUtil { 18 private static final String DICTATION_APPID = GlobalConfig.IFLY_VOICE_SDK_APP_ID; 19 20 private static SpeechRecognizer mIat; 21 private static RecognizerDialog iatDialog; 22 private static String dictationResultStr; 23 private static String finalResult; 24 25 public static void showDictationDialog(final Context context, 26 final DictationListener listener) { 27 // 初始化语音配置 28 initConfig(context); 29 30 // 开始听写 31 iatDialog.setListener(new RecognizerDialogListener() { 32 33 @Override 34 public void onResult(RecognizerResult results, boolean isLast) { 35 if (!isLast) { 36 dictationResultStr += results.getResultString() + ","; 37 } else { 38 dictationResultStr += results.getResultString() + "]"; 39 40 finalResult = DictationJsonParseUtil 41 .parseJsonData(dictationResultStr); 42 43 listener.onDictationListener(finalResult); 44 } 45 46 } 47 48 @Override 49 public void onError(SpeechError error) { 50 error.getPlainDescription(true); 51 } 52 }); 53 54 // 开始听写 55 iatDialog.show(); 56 } 57 58 private static void initConfig(Context context) { 59 dictationResultStr = "["; 60 finalResult = ""; 61 62 // 语音配置对象初始化 63 SpeechUtility.createUtility(context, SpeechConstant.APPID + "=" 64 + DICTATION_APPID); 65 66 // 1.创建SpeechRecognizer对象,第2个参数:本地听写时传InitListener 67 mIat = SpeechRecognizer.createRecognizer(context, null); 68 // 交互动画 69 iatDialog = new RecognizerDialog(context, null); 70 71 // 2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类 72 mIat.setParameter(SpeechConstant.DOMAIN, "iat"); // domain:域名 73 mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); 74 mIat.setParameter(SpeechConstant.ACCENT, "mandarin"); // mandarin:普通话 75 } 76 }
(六)最后就是在需要语音听写的地方进行调用了,调用起来很简单,只需调用DictationUtil类的静态方法showDictationDialog,第一个参数传入Context,第二个参数创建DictationListener匿名内部类,重写其onDictationListener方法,在该方法中对语音听写最终结果进行处理即可(比如为EditText设置文本等)。
1 import com.easydo.util.DictationListener; 2 import com.easydo.util.DictationUtil; 3 import com.jiayongji.easydo.R; 4 5 import android.os.Bundle; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.EditText; 9 import android.widget.ImageButton; 10 11 public class CreateScheduleActivity extends BaseActivity implements 12 OnClickListener { 13 14 // 日程内容et 15 private EditText createScheduleContentEt; 16 // 日程内容语音听写ib 17 private ImageButton createScheduleContentDictationIb; 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_create_schedule); 23 24 createScheduleContentEt = (EditText) findViewById(R.id.create_schedule_content_et); 25 createScheduleContentDictationIb = (ImageButton) findViewById(R.id.create_schedule_content_dictation_ib); 26 27 createScheduleContentDictationIb.setOnClickListener(this); 28 } 29 30 @Override 31 public void onClick(View v) { 32 switch (v.getId()) { 33 case R.id.create_schedule_content_dictation_ib: 34 DictationUtil.showDictationDialog(this, new DictationListener() { 35 36 @Override 37 public void onDictationListener(String dictationResultStr) { 38 createScheduleContentEt.setText(dictationResultStr); 39 createScheduleContentEt.requestFocus(); 40 createScheduleContentEt.setSelection(dictationResultStr 41 .length()); 42 } 43 }); 44 break; 45 default: 46 break; 47 } 48 } 49 }
(欢迎转载!作者:jiayongji 分享请保留地址:http://www.cnblogs.com/jiayongji/p/5366171.html)