在 科大訊飛開放平台——語音聽寫接口的使用 這篇文章里介紹了科大訊飛語音聽寫接口的簡單使用方法,但是在實際開發中發現僅僅那樣做在使用起來還是不方便,於是想到把語音聽寫接口的調用、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)