Android 集成科大讯飞语音并实现语音识别 | 您所在的位置:网站首页 › 语音唤醒怎么不管用 › Android 集成科大讯飞语音并实现语音识别 |
前言:此博客内容有,集成讯飞语音sdk,实现了语音唤醒,在线语音识别,离线语音识别,更新本地离线语音词典 集成讯飞语音SDK 注册账号下载SDK百度搜索科大讯飞,打开网站,没有账号的根据操作步骤注册账号,注册完成之后,根据个人需求下载sdk,因为咱们要实现的内容有离线语音识别,语音唤醒,以及更新本地离线语音字典,所以在下载SDK之前需要添加唤醒词,添加完之后再去下载SDK 导入demo导入demo,有可能会报错,怕大家不知道怎么解决,这里我就给大家详细介绍一下,会遇到的一些问题都是怎么解决的; 先导入demo 我们仔细观察会发现此项目结构中只有 Project 的build.grade 文件,没有Module 的 build.grade,所以我们在 Project 的build.gradle中添加如下代码,然后try again buildscript { repositories { google() jcenter() } dependencies { //版本号请根据自己的gradle插件版本号自行更改 classpath 'com.android.tools.build:gradle:3.2.0' } }在这里需要注意一下,buildscript 、 android 和 dependencies 他们三个是同级的关系,如下图 第一个错误的意思是:minSdk版本不应该在android manifest文件中声明。您可以将版本从清单移动到构建中的defaultConfig。gradle文件。 那么我们就打开android manifest,找到minSdk,把他删除 讲demo中libs拷贝到自己的lib里 首先添加权限 然后创建一个application,代码如下 public class SpeechApplication extends Application { @Override public void onCreate() { // 5ef048e1 为在开放平台注册的APPID 注意没有空格,直接替换即可 SpeechUtility.createUtility(SpeechApplication.this, "appid=5ef048e1"); super.onCreate(); } }下面是MainActivity里面的代码 public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "yaya"; private SpeechRecognizer mIat;// 语音听写对象 private RecognizerDialog mIatDialog;// 语音听写UI // 用HashMap存储听写结果 private HashMap mIatResults = new LinkedHashMap(); private SharedPreferences mSharedPreferences;//缓存 private String mEngineType = SpeechConstant.TYPE_CLOUD;// 引擎类型 private String language = "zh_cn";//识别语言 private TextView tvResult;//识别结果 private Button btnStart;//开始识别 private String resultType = "json";//结果内容数据格式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvResult = findViewById(R.id.tv_result); btnStart = findViewById(R.id.btn_start); btnStart.setOnClickListener(this);//实现点击监听 initPermission(); // 使用SpeechRecognizer对象,可根据回调消息自定义界面; mIat = SpeechRecognizer.createRecognizer(MainActivity.this, mInitListener); // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源 mIatDialog = new RecognizerDialog(MainActivity.this, mInitListener); mSharedPreferences = getSharedPreferences("ASR", Activity.MODE_PRIVATE); } @Override public void onClick(View v) { if (null == mIat) { // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688 showMsg("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化"); return; } mIatResults.clear();//清除数据 setParam(); // 设置参数 mIatDialog.setListener(mRecognizerDialogListener);//设置监听 mIatDialog.show();// 显示对话框 } /** * android 6.0 以上需要动态申请权限 */ private void initPermission() { String permissions[] = {Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE }; ArrayList toApplyList = new ArrayList(); for (String perm : permissions) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) { toApplyList.add(perm); } } String tmpList[] = new String[toApplyList.size()]; if (!toApplyList.isEmpty()) { ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123); } } /** * 权限申请回调,可以作进一步处理 * * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // 此处为android 6.0以上动态授权的回调,用户自行实现。 } /** * 初始化监听器。 */ private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d(TAG, "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { showMsg("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } }; /** * 听写UI监听器 */ private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() { public void onResult(RecognizerResult results, boolean isLast) { printResult(results);//结果数据解析 } /** * 识别回调错误. */ public void onError(SpeechError error) { showMsg(error.getPlainDescription(true)); } }; /** * 提示消息 * * @param msg */ private void showMsg(String msg) { Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); } /** * 数据解析 * * @param results */ 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)); } tvResult.setText(resultBuffer.toString());//听写结果显示 if (resultBuffer.toString().equals("语音唤醒。")) { startActivity(new Intent(this, WeakUpActivity.class)); } else if (resultBuffer.toString().equals("离线")) { startActivity(new Intent(this, OfflineActivity.class)); } } /** * 参数设置 * * @return */ public void setParam() { // 清空参数 mIat.setParameter(SpeechConstant.PARAMS, null); // 设置听写引擎 mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType); // 设置返回结果格式 mIat.setParameter(SpeechConstant.RESULT_TYPE, resultType); if (language.equals("zh_cn")) { String lag = mSharedPreferences.getString("iat_language_preference", "mandarin"); Log.e(TAG, "language:" + language);// 设置语言 mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); // 设置语言区域 mIat.setParameter(SpeechConstant.ACCENT, lag); } else { mIat.setParameter(SpeechConstant.LANGUAGE, language); } Log.e(TAG, "last language:" + mIat.getParameter(SpeechConstant.LANGUAGE)); //此处用于设置dialog中不显示错误码信息 //mIat.setParameter("view_tips_plain","false"); // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 mIat.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("iat_vadbos_preference", "4000")); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 mIat.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference", "1000")); // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 mIat.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference", "1")); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav"); } @Override protected void onDestroy() { super.onDestroy(); if (null != mIat) { // 退出时释放连接 mIat.cancel(); mIat.destroy(); } } }接下来是MainActivity的布局文件 好了运行起来就可以实现语音识别了 语音唤醒代码如下 public class WeakUpActivity extends AppCompatActivity { //唤醒的阈值,就相当于门限值,当用户输入的语音的置信度大于这一个值的时候,才被认定为成功唤醒。 private int curThresh = 1450; //是否持续唤醒 private String keep_alive = "1"; private String ivwNetMode = "0"; // 语音唤醒对象 private VoiceWakeuper mIvw; //存储唤醒词的ID private String wordID = ""; // 唤醒结果内容 private String resultString; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_weak_up); tv=(TextView)findViewById(R.id.tv); // 初始化唤醒对象 mIvw = VoiceWakeuper.createWakeuper(this, null); //非空判断,防止因空指针使程序崩溃 mIvw = VoiceWakeuper.getWakeuper(); if(mIvw != null) { resultString=""; tv.setText(resultString); // 清空参数 mIvw.setParameter(SpeechConstant.PARAMS, null); // 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入 mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:"+ curThresh); // 设置唤醒模式 mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup"); // 设置持续进行唤醒 mIvw.setParameter(SpeechConstant.KEEP_ALIVE, keep_alive); // 设置闭环优化网络模式 mIvw.setParameter(SpeechConstant.IVW_NET_MODE, ivwNetMode); // 设置唤醒资源路径 mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource()); // 设置唤醒录音保存路径,保存最近一分钟的音频 mIvw.setParameter( SpeechConstant.IVW_AUDIO_PATH, Environment.getExternalStorageDirectory().getPath()+"/msc/ivw.wav" ); mIvw.setParameter( SpeechConstant.AUDIO_FORMAT, "wav" ); // 如有需要,设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节 //mIvw.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" ); // 启动唤醒 mIvw.startListening(new MyWakeuperListener()); }else{ showTip("唤醒未初始化"); } } public void showTip(String str){ Toast.makeText(this,str, Toast.LENGTH_SHORT).show(); } /** * 获取唤醒词功能 * @return 返回文件位置 */ private String getResource() { final String resPath = ResourceUtil.generateResourcePath(this,ResourceUtil.RESOURCE_TYPE.assets, "ivw/"+"a381fd1d"+".jet"); return resPath; } /** * 唤醒词监听类 * @author Administrator * */ private class MyWakeuperListener implements WakeuperListener { //开始说话 @Override public void onBeginOfSpeech() { } //错误码返回 @Override public void onError(SpeechError arg0) { } @Override public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) { } @Override public void onVolumeChanged(int i) { } @Override public void onResult(WakeuperResult result) { if (!"1".equalsIgnoreCase(keep_alive)) { //setRadioEnable(true); } try { String text = result.getResultString(); JSONObject object; object = new JSONObject(text); StringBuffer buffer = new StringBuffer(); buffer.append("【RAW】 " + text); buffer.append("\n"); buffer.append("【操作类型】" + object.optString("sst")); buffer.append("\n"); buffer.append("【唤醒词id】" + object.optString("id")); buffer.append("\n"); buffer.append("【得分】" + object.optString("score")); buffer.append("\n"); buffer.append("【前端点】" + object.optString("bos")); buffer.append("\n"); buffer.append("【尾端点】" + object.optString("eos")); resultString = buffer.toString(); } catch (JSONException e) { e.printStackTrace(); } tv.setText(resultString); } } }对应的布局文件 离线语音识别并更新本地词典命令词在这里需要注意一下啊,命令词的更新词典是更新的槽,主要是为了方便想通讯录的录入,不支持大批量更新词典的,建议在设置命令词的时候就包含完整命令词即可。 代码如下 public class OfflineActivity extends AppCompatActivity { private final static String TAG = "yaya"; private Toast mToast; // 语音识别对象 private SpeechRecognizer mAsr; // 缓存 // private SharedPreferences mSharedPreferences; // 本地语法文件 private String mLocalGrammar = null; // 本地词典 private String mLocalLexicon = null; // 本地语法构建路径 private String grmPath = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/msc/test"; // 返回结果格式,支持:xml,json private String mResultType = "json"; private String mEngineType = "cloud"; private final String GRAMMAR_TYPE_BNF = "bnf"; String mContent;// 语法、词典临时变量 String action;// 语法、词典临时变量 int ret = 0;// 函数调用返回值 private TextView tvResult; private WebView webview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_offline); initPermission(); // 初始化识别对象 mAsr = SpeechRecognizer.createRecognizer(this, mInitListener); if (mAsr == null) { Log.e(TAG, "masr is null"); } // 初始化语法、命令词 mLocalLexicon = "张海洋\n张三\n李四\n王五\n"; mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8"); // 获取联系人,本地更新词典时使用 // ContactManager mgr = ContactManager.createManager(OfflineActivity.this, mContactListener); // mgr.asyncQueryAllContactsName(); // mSharedPreferences = getSharedPreferences(getPackageName(), MODE_PRIVATE); mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT); initView(); } /** * android 6.0 以上需要动态申请权限 */ private void initPermission() { String permissions[] = {Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE }; ArrayList toApplyList = new ArrayList(); for (String perm : permissions) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) { toApplyList.add(perm); } } String tmpList[] = new String[toApplyList.size()]; if (!toApplyList.isEmpty()) { ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123); } } private void initView() { tvResult = findViewById(R.id.tv_result); tvResult.setText(mLocalLexicon); webview = findViewById(R.id.webview); //本地库语音 mEngineType = SpeechConstant.TYPE_LOCAL; showTip("上传预设关键词/语法文件"); // 本地-构建语法文件,生成语法id // if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) { // tvResult.setText(mLocalGrammar); mContent = new String(mLocalGrammar); action = new String(mLocalGrammar); mAsr.setParameter(SpeechConstant.PARAMS, null); // 设置文本编码格式 mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8"); // 设置引擎类型 mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType); // 设置语法构建路径 mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath); //使用8k音频的时候请解开注释 // mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000"); // 设置资源路径 mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath()); ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener); ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, action, grammarListener); if (ret != ErrorCode.SUCCESS) { showTip("语法构建失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } // } /** * 语音识别 * * @param view */ public void start(View view) { if (null == mAsr) { // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688 this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化"); return; } if (!setParam()) { showTip("请先构建语法。"); return; } ret = mAsr.startListening(mRecognizerListener); if (ret != ErrorCode.SUCCESS) { showTip("识别失败,错误码: " + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } /** * 更新本地词库 * * @param view */ public void updata(View view) { tvResult.setText(mLocalLexicon); mContent = new String(mLocalLexicon); mAsr.setParameter(SpeechConstant.PARAMS, null); // 设置引擎类型 mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL); // 设置资源路径 mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath()); //使用8k音频的时候请解开注释 // mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000"); // 设置语法构建路径 mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath); // 设置语法名称 mAsr.setParameter(SpeechConstant.GRAMMAR_LIST, "call"); // 设置文本编码格式 mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8"); //更新词典 ret = mAsr.updateLexicon("contact", mContent, lexiconListener); if (ret != ErrorCode.SUCCESS) { showTip("更新词典失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } /** * 参数设置 * * @return */ public boolean setParam() { boolean result = false; // 清空参数 mAsr.setParameter(SpeechConstant.PARAMS, null); // 设置识别引擎 mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType); // 设置本地识别资源 mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath()); // 设置语法构建路径 mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath); // 设置返回结果格式 mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType); // 设置本地识别使用语法id mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call"); // 设置识别的门限值 mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30"); // 使用8k音频的时候请解开注释 // mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000"); result = true; // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/asr.wav"); return result; } //获取识别资源路径 private String getResourcePath() { StringBuffer tempBuffer = new StringBuffer(); //识别通用资源 tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "asr/common.jet")); return tempBuffer.toString(); } /** * 初始化监听器。 */ private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d(TAG, "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { showTip("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案"); } } }; /** * 更新词典监听器。 */ private LexiconListener lexiconListener = new LexiconListener() { @Override public void onLexiconUpdated(String lexiconId, SpeechError error) { if (error == null) { showTip("词典更新成功" + lexiconId); Log.d("yaya", "=mLocalGrammar=" + mLocalGrammar); } else { showTip("词典更新失败,错误码:" + error.getErrorCode()); } } }; /** * 构建语法监听器。 */ private GrammarListener grammarListener = new GrammarListener() { @Override public void onBuildFinish(String grammarId, SpeechError error) { if(error == null){ showTip("语法构建成功:" + grammarId); }else{ showTip("语法构建失败,错误码:" + error.getErrorCode()); } } }; /** * 获取联系人监听器。 */ private ContactManager.ContactListener mContactListener = new ContactManager.ContactListener() { @Override public void onContactQueryFinish(String contactInfos, boolean changeFlag) { //获取联系人 mLocalLexicon = contactInfos; } }; /** * 识别监听器。 */ private RecognizerListener mRecognizerListener = new RecognizerListener() { @Override public void onVolumeChanged(int volume, byte[] data) { showTip("当前正在说话,音量大小:" + volume); Log.d(TAG, "返回音频数据:" + data.length); } @Override public void onResult(final RecognizerResult result, boolean isLast) { if (null != result && !TextUtils.isEmpty(result.getResultString())) { Log.d(TAG, "recognizer result:" + result.getResultString()); String text = ""; if (mResultType.equals("json")) { text = JsonParser.parseGrammarResult(result.getResultString(), mEngineType); } else if (mResultType.equals("xml")) { text = XmlParser.parseNluResult(result.getResultString()); } else { text = result.getResultString(); } // 显示 tvResult.setText(text); loadWeb(); } else { Log.d(TAG, "recognizer result : null"); } } @Override public void onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 showTip("结束说话"); } @Override public void onBeginOfSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 showTip("开始说话"); } @Override public void onError(SpeechError error) { showTip("onError Code:" + error.getErrorCode()); } @Override public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { } }; private void showTip(final String str) { runOnUiThread(new Runnable() { @Override public void run() { mToast.setText(str); mToast.show(); } }); } private void loadWeb() { String url = "https://www.xfyun.cn/service/commandWord"; // 允许从任何来源加载内容,即使起源是不安全的; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); } webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); webview.getSettings().setSupportMultipleWindows(true); webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);//不加缓存 webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setDomStorageEnabled(true);//设置适应Html5 //重点是这个设置 webview.setWebViewClient(new WebViewClient()); webview.setWebChromeClient(new WebChromeClient()); webview.loadUrl(url); } }xml文件 其实到这里已经结束了,不过里面会涉及到其他几个实体类,讯飞给的sdk包里面就有,这里怕大家懒的去找,我就也贴出来吧 import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceActivity; import android.view.Window; import com.gogowan.xfvoice.R; import com.gogowan.xfvoice.SettingTextWatcher; /** * 听写设置界面 */ public class IatSettings extends PreferenceActivity implements OnPreferenceChangeListener { public static final String PREFER_NAME = "com.iflytek.setting"; private EditTextPreference mVadbosPreference; private EditTextPreference mVadeosPreference; @SuppressWarnings("deprecation") public void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getPreferenceManager().setSharedPreferencesName(PREFER_NAME); addPreferencesFromResource(R.xml.iat_setting); mVadbosPreference = (EditTextPreference)findPreference("iat_vadbos_preference"); mVadbosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadbosPreference,0,10000)); mVadeosPreference = (EditTextPreference)findPreference("iat_vadeos_preference"); mVadeosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadeosPreference,0,10000)); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { return true; } } import android.content.Context; import java.io.IOException; import java.io.InputStream; /** * 功能性函数扩展类 */ public class FucUtil { /** * 读取asset目录下文件。 * @return content */ public static String readFile(Context mContext, String file, String code) { int len = 0; byte []buf = null; String result = ""; try { InputStream in = mContext.getAssets().open(file); len = in.available(); buf = new byte[len]; in.read(buf, 0, len); result = new String(buf,code); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 读取asset目录下音频文件。 * * @return 二进制文件数据 */ public static byte[] readAudioFile(Context context, String filename) { try { InputStream ins = context.getAssets().open(filename); byte[] data = new byte[ins.available()]; ins.read(data); ins.close(); return data; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONTokener; /** * Json结果解析类 */ public class JsonParser { public static String parseIatResult(String json) { StringBuffer ret = new StringBuffer(); try { JSONTokener tokener = new JSONTokener(json); JSONObject joResult = new JSONObject(tokener); JSONArray words = joResult.getJSONArray("ws"); for (int i = 0; i // JSONObject obj = items.getJSONObject(j); // ret.append(obj.getString("w")); // } } } catch (Exception e) { e.printStackTrace(); } return ret.toString(); } public static String parseGrammarResult(String json, String engType) { StringBuffer ret = new StringBuffer(); try { JSONTokener tokener = new JSONTokener(json); JSONObject joResult = new JSONObject(tokener); JSONArray words = joResult.getJSONArray("ws"); // 云端和本地结果分情况解析 if ("cloud".equals(engType)) { for (int i = 0; i JSONObject obj = items.getJSONObject(j); if(obj.getString("w").contains("nomatch")) { ret.append("没有匹配结果."); return ret.toString(); } ret.append("【结果】" + obj.getString("w")); ret.append("【置信度】" + obj.getInt("sc")); ret.append("\n"); } } } else if ("local".equals(engType)) { ret.append("【结果】"); for (int i = 0; i // 可能会有多个联系人供选择,用中括号括起来,这些候选项具有相同的置信度 ret.append("【"); for(int j = 0; j ret.append("没有匹配结果."); return ret.toString(); } ret.append(obj.getString("w")).append("|"); } ret.setCharAt(ret.length() - 1, '】'); } else { //本地多候选按照置信度高低排序,一般选取第一个结果即可 JSONObject obj = items.getJSONObject(0); if(obj.getString("w").contains("nomatch")) { ret.append("没有匹配结果."); return ret.toString(); } ret.append(obj.getString("w")); } } ret.append("【置信度】" + joResult.getInt("sc")); ret.append("\n"); } } catch (Exception e) { e.printStackTrace(); ret.append("没有匹配结果."); } return ret.toString(); } public static String parseGrammarResult(String json) { StringBuffer ret = new StringBuffer(); try { JSONTokener tokener = new JSONTokener(json); JSONObject joResult = new JSONObject(tokener); JSONArray words = joResult.getJSONArray("ws"); for (int i = 0; i JSONObject obj = items.getJSONObject(j); if(obj.getString("w").contains("nomatch")) { ret.append("没有匹配结果."); return ret.toString(); } ret.append("【结果】" + obj.getString("w")); ret.append("【置信度】" + obj.getInt("sc")); ret.append("\n"); } } } catch (Exception e) { e.printStackTrace(); ret.append("没有匹配结果."); } return ret.toString(); } public static String parseTransResult(String json, String key) { StringBuffer ret = new StringBuffer(); try { JSONTokener tokener = new JSONTokener(json); JSONObject joResult = new JSONObject(tokener); String errorCode = joResult.optString("ret"); if(!errorCode.equals("0")) { return joResult.optString("errmsg"); } JSONObject transResult = joResult.optJSONObject("trans_result"); ret.append(transResult.optString(key)); } catch (Exception e) { e.printStackTrace(); } return ret.toString(); } } mport android.content.Context; import android.preference.EditTextPreference; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.widget.Toast; import java.util.regex.Pattern; /** * 输入框输入范围控制 */ public class SettingTextWatcher implements TextWatcher { private int editStart ; private int editCount ; private EditTextPreference mEditTextPreference; int minValue;//最小值 int maxValue;//最大值 private Context mContext; public SettingTextWatcher(Context context, EditTextPreference e, int min, int max) { mContext = context; mEditTextPreference = e; minValue = min; maxValue = max; } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // Log.e("demo", "onTextChanged start:"+start+" count:"+count+" before:"+before); editStart = start; editCount = count; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // Log.e("demo", "beforeTextChanged start:"+start+" count:"+count+" after:"+after); } @Override public void afterTextChanged(Editable s) { if (TextUtils.isEmpty(s)) { return; } String content = s.toString(); // Log.e("demo", "content:"+content); if (isNumeric(content)) { int num = Integer.parseInt(content); if (num > maxValue || num s.delete(editStart, editStart+editCount); mEditTextPreference.getEditText().setText(s); Toast.makeText(mContext, "只能输入数字哦", Toast.LENGTH_SHORT).show(); } } /** * 正则表达式-判断是否为数字 */ public static boolean isNumeric(String str){ Pattern pattern = Pattern.compile("[0-9]*"); return pattern.matcher(str).matches(); } } import org.w3c.dom.Document; import org.w3c.dom.Element; import java.io.ByteArrayInputStream; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; /** * Xml结果解析类 */ public class XmlParser { public static String parseNluResult(String xml) { StringBuffer buffer = new StringBuffer(); try { // DOM builder DocumentBuilder domBuilder = null; // DOM doc Document domDoc = null; // init DOM DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance(); domBuilder = domFact.newDocumentBuilder(); InputStream is = new ByteArrayInputStream(xml.getBytes()); domDoc = domBuilder.parse(is); // 获取根节点 Element root = (Element) domDoc.getDocumentElement(); Element raw = (Element)root.getElementsByTagName("rawtext").item(0); buffer.append("【识别结果】" + raw.getFirstChild().getNodeValue()); buffer.append("\n"); Element e = (Element)root.getElementsByTagName("result").item(0); Element focus = (Element)e.getElementsByTagName("focus").item(0); buffer.append("【FOCUS】" + focus.getFirstChild().getNodeValue()); buffer.append("\n"); Element action = (Element)e.getElementsByTagName("action").item(0); Element operation = (Element)action.getElementsByTagName("operation").item(0); buffer.append("【ACTION】" + operation.getFirstChild().getNodeValue()); buffer.append("\n"); }catch(Exception e){ e.printStackTrace(); }; buffer.append("【ALL】" + xml); return buffer.toString(); } }最后大家需要注意一下啊,如果你只是单单实现某一个功能,一定要记得添加动态权限,我这个有的添加了,有的activity没写上 好了,到这里,功能都已经实现了,代码也全部贴上了 |
CopyRight 2018-2019 实验室设备网 版权所有 |