20202428 2023-2024-2 《移动平台开发与实践》第6次作业

白鹤大人泰库拉 2024-06-25 11:08:45

实验六 语音识别系统

一、实验目标

掌握基于Android平台的程序设计技术,并能够编写完成语音识别系统。

二、实验内容

设计并开发一个语音识别应用系统。

通过使用RecognizerIntent实现语音识别功能,开发一个Android语音识别系统。

三、实验过程

在科大讯飞控制台创建app,下载对应的sdk

 

 

 

 

 

 

将sdk目录下lib中的文件复制到android studio中的项目,同时将Msc.jar文件add as library。

 

 

 

 

 

 

将SDK下载包中的assets文件夹中的包复制到main文件目录下。

 

 

 

将SpeechApplication.java的代码进行调整。首先将appid更改为在科大讯飞控制台申请的appid。

 

 

 

 

修改AndroidManifest.xml中的代码:

 

 

 

在build.gradle(:app)的Android中添加如下代码,重新sync一下。

 
  1. sourceSets{

  2. main{

  3. jniLibs.srcDir 'libs'

  4. }

  5. }

主函数代码如下:

 
  1. package com.example.sr2415;

  2.  
  3. import android.os.Bundle;

  4. import android.speech.SpeechRecognizer;

  5. import android.view.View;

  6. import android.widget.Button;

  7. import android.widget.EditText;

  8.  
  9. import androidx.appcompat.app.AppCompatActivity;

  10.  
  11. import com.iflytek.cloud.ui.RecognizerDialog;

  12.  
  13. import java.util.HashMap;

  14. import java.util.LinkedHashMap;

  15.  
  16. public class MainActivity {

  17. package com.example.sr2415;

  18. import androidx.appcompat.app.AppCompatActivity;

  19. import android.app.AlertDialog;

  20. import android.os.Bundle;

  21. import android.os.Environment;

  22. import android.os.Handler;

  23. import android.os.Message;

  24. import android.util.Log;

  25. import android.view.View;

  26. import android.widget.Button;

  27. import android.widget.EditText;

  28. import android.widget.Toast;

  29.  
  30. import com.iflytek.cloud.ErrorCode;

  31. import com.iflytek.cloud.InitListener;

  32. import com.iflytek.cloud.RecognizerListener;

  33. import com.iflytek.cloud.RecognizerResult;

  34. import com.iflytek.cloud.SpeechConstant;

  35. import com.iflytek.cloud.SpeechError;

  36. import com.iflytek.cloud.SpeechRecognizer;

  37. //import com.iflytek.cloud.SpeechUtility;

  38. import com.iflytek.cloud.SpeechUtility;

  39. import com.iflytek.cloud.ui.RecognizerDialog;

  40. import com.iflytek.cloud.ui.RecognizerDialogListener;

  41. import org.json.JSONException;

  42. import org.json.JSONObject;

  43. import java.util.ArrayList;

  44. import java.util.HashMap;

  45. import java.util.LinkedHashMap;

  46.  
  47.  
  48. public class MainActivity extends AppCompatActivity implements View.OnClickListener {

  49. private static final String TAG = "MainActivity";

  50. private SpeechRecognizer mIat;

  51. private RecognizerDialog mIatDialog;

  52. // 用HashMap存储听写结果

  53. private HashMap<String, String> mIatResults = new LinkedHashMap<>();

  54. private EditText mResultText;

  55. private Button languageText, dialogButton;

  56. private String language = "zh_cn";

  57. private String resultType = "json";

  58. private boolean cyclic = false;//音频流识别是否循环调用

  59. //拼接字符串

  60. private StringBuffer buffer = new StringBuffer();

  61. //Handler码

  62. private int handlerCode = 0x123;

  63. // 函数调用返回值

  64. private int resultCode = 0;

  65. // 切换中英文

  66. private boolean languageType;

  67. // 弹框是否显示

  68. private int dialogType;

  69. @Override

  70. protected void onCreate(Bundle savedInstanceState) {

  71. super.onCreate(savedInstanceState);

  72. setContentView(R.layout.activity_main);

  73. SpeechUtility.createUtility(this, SpeechConstant.APPID +"=6ba03230");

  74. //初始化控件

  75. findViewById(R.id.iat_recognize).setOnClickListener(this);

  76. findViewById(R.id.iat_recognize_stream).setOnClickListener(this);

  77. findViewById(R.id.iat_stop).setOnClickListener(this);

  78. findViewById(R.id.iat_cancel).setOnClickListener(this);

  79. mResultText = this.findViewById(R.id.iat_text);

  80. mIat = SpeechRecognizer.createRecognizer(this, mInitListener);

  81. mIatDialog = new RecognizerDialog(MainActivity.this, mInitListener);

  82. }

  83.  
  84. @Override

  85. public void onClick(View view) {

  86. if (null == mIat) {

  87. showToast("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化");

  88. return;

  89. }

  90. switch (view.getId()) {

  91. case R.id.iat_recognize:

  92. buffer.setLength(0);//长度清空

  93. mResultText.setText(null);// 清空显示内容

  94. mIatResults.clear();//清除存贮结果

  95. // 设置参数

  96. setParam();

  97. if (dialogType == 0) {

  98. // 显示听写对话框

  99. mIatDialog.setListener(mRecognizerDialogListener);

  100. mIatDialog.show();

  101. showToast("开始听写");

  102. } else if (dialogType == 1) {

  103. // 不显示听写对话框

  104. resultCode = mIat.startListening(mRecognizerListener);

  105. if (resultCode != ErrorCode.SUCCESS) {

  106. showToast("听写失败,错误码:" + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");

  107. } else {

  108. showToast("开始听写");

  109. }

  110. } else if (dialogType == 2) {

  111. // 自定义听写对话框

  112. showAlertDialog();

  113. resultCode = mIat.startListening(mRecognizerListener);

  114. if (resultCode != ErrorCode.SUCCESS) {

  115. showToast("听写失败,错误码:" + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");

  116. } else {

  117. showToast("开始听写");

  118. }

  119. }

  120. break;

  121. // 音频流识别

  122. case R.id.iat_recognize_stream:

  123. executeStream();

  124. break;

  125. case R.id.iat_stop:

  126. mIat.stopListening();

  127. showToast("停止听写");

  128. break;

  129. case R.id.iat_cancel:

  130. mIat.cancel();

  131. showToast("取消听写");

  132. break;

  133. }

  134. }

  135.  
  136. /**

  137. * 初始化监听器。

  138. */

  139. private InitListener mInitListener = new InitListener() {

  140.  
  141. @Override

  142. public void onInit(int code) {

  143. Log.e(TAG, "SpeechRecognizer init() code = " + code);

  144. if (code != ErrorCode.SUCCESS) {

  145. showToast("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");

  146. }

  147. }

  148. };

  149.  
  150. /**

  151. * 听写监听器。

  152. */

  153. private RecognizerListener mRecognizerListener = new RecognizerListener() {

  154.  
  155. @Override

  156. public void onBeginOfSpeech() {

  157. // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入

  158. showToast("开始说话");

  159. }

  160.  
  161. @Override

  162. public void onError(SpeechError error) {

  163. // Tips:

  164. // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。

  165. showToast(error.getPlainDescription(true));

  166. if (null != dialog) {

  167. dialog.dismiss();

  168. }

  169. }

  170.  
  171. @Override

  172. public void onEndOfSpeech() {

  173. // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入

  174. showToast("结束说话");

  175. if (null != dialog) {

  176. dialog.dismiss();

  177. }

  178. }

  179.  
  180. @Override

  181. public void onResult(RecognizerResult results, boolean isLast) {

  182. Log.e(TAG, "onResult: " + results.getResultString());

  183. if (resultType.equals(resultType)) {

  184. printResult(results);

  185. } else if (resultType.equals("plain")) {

  186. buffer.append(results.getResultString());

  187. mResultText.setText(buffer.toString());

  188. mResultText.setSelection(mResultText.length());

  189. }

  190. if (isLast & cyclic) {

  191. // TODO 最后的结果

  192. Message message = Message.obtain();

  193. message.what = handlerCode;

  194. handler.sendMessageDelayed(message, 100);

  195. }

  196. }

  197.  
  198. @Override

  199. public void onVolumeChanged(int volume, byte[] data) {

  200. //showToast("当前正在说话,音量大小:" + volume);

  201. Log.e(TAG, "onVolumeChanged: " + data.length);

  202. }

  203.  
  204. @Override

  205. public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {

  206. // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因

  207. // 若使用本地能力,会话id为null

  208. // if (SpeechEvent.EVENT_SESSION_ID == eventType) {

  209. // String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);

  210. // Log.d(TAG, "session id =" + sid);

  211. // }

  212. }

  213. };

  214.  
  215. private Handler handler = new Handler() {

  216. @Override

  217. public void handleMessage(Message msg) {

  218. super.handleMessage(msg);

  219. if (msg.what == handlerCode) {

  220. executeStream();

  221. }

  222. }

  223. };

  224.  
  225. /**

  226. * 听写UI监听器

  227. */

  228. private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {

  229. /**

  230. * 识别回调成功

  231. */

  232. public void onResult(RecognizerResult results, boolean isLast) {

  233. printResult(results);

  234. }

  235.  
  236. /**

  237. * 识别回调错误.

  238. */

  239. public void onError(SpeechError error) {

  240. showToast(error.getPlainDescription(true));

  241. }

  242. };

  243.  
  244. /**

  245. * 打印听写结果

  246. */

  247. private void printResult(RecognizerResult results) {

  248. String text = JsonParser.parseIatResult(results.getResultString());

  249. String sn = null;

  250. // 读取json结果中的sn字段

  251. try {

  252. JSONObject resultJson = new JSONObject(results.getResultString());

  253. sn = resultJson.optString("sn");

  254. } catch (JSONException e) {

  255. e.printStackTrace();

  256. }

  257. mIatResults.put(sn, text);

  258. StringBuffer resultBuffer = new StringBuffer();

  259. for (String key : mIatResults.keySet()) {

  260. resultBuffer.append(mIatResults.get(key));

  261. }

  262. mResultText.setText(resultBuffer.toString());

  263. mResultText.setSelection(mResultText.length());

  264. }

  265.  
  266. /**

  267. * 听写参数设置

  268. */

  269. public void setParam() {

  270. mIat.setParameter(SpeechConstant.PARAMS, null);

  271. mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);

  272. mIat.setParameter(SpeechConstant.RESULT_TYPE, resultType);

  273. mIat.setParameter(SpeechConstant.LANGUAGE, language);

  274. mIat.setParameter(SpeechConstant.ACCENT, "mandarin");

  275. Log.e(TAG, "last language:" + mIat.getParameter(SpeechConstant.LANGUAGE));

  276. mIat.setParameter(SpeechConstant.VAD_BOS, "5000");

  277. mIat.setParameter(SpeechConstant.VAD_EOS, "1800");

  278. mIat.setParameter(SpeechConstant.ASR_PTT, "1");

  279. mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");

  280. mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/helloword.wav");

  281. }

  282.  
  283. //执行音频流识别操作

  284. private void executeStream() {

  285. buffer.setLength(0);

  286. mResultText.setText(null);// 清空显示内容

  287. mIatResults.clear();

  288. setParam();

  289. mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");

  290. mIat.setParameter(SpeechConstant.LANGUAGE, language);

  291. resultCode = mIat.startListening(mRecognizerListener);

  292. if (resultCode != ErrorCode.SUCCESS) {

  293. showToast("识别失败,错误码:" + resultCode + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");

  294. } else {

  295. byte[] audioData = FucUtil.readAudioFile(MainActivity.this, "iattest.wav");

  296. if (null != audioData) {

  297. showToast("开始音频流识别");

  298. ArrayList<byte[]> bytes = FucUtil.splitBuffer(audioData, audioData.length, audioData.length / 3);

  299. for (int i = 0; i < bytes.size(); i++) {

  300. mIat.writeAudio(bytes.get(i), 0, bytes.get(i).length);

  301. try {

  302. Thread.sleep(1000);//休眠1秒

  303. } catch (Exception e) {

  304. }

  305. }

  306. mIat.stopListening();

  307. } else {

  308. mIat.cancel();

  309. showToast("读取音频流失败");

  310. }

  311. }

  312. }

  313.  
  314. @Override

  315. protected void onResume() {

  316. super.onResume();

  317. }

  318.  
  319. @Override

  320. protected void onPause() {

  321. super.onPause();

  322. }

  323. private void showToast(final String str) {

  324. Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

  325. }

  326.  
  327. private AlertDialog dialog;

  328.  
  329. private void showAlertDialog() {

  330. dialog = new AlertDialog.Builder(this)

  331. .setTitle("自定弹框")//标题

  332. .setMessage("正在识别,请稍后...")//内容

  333. .setIcon(R.mipmap.ic_launcher)//图标

  334. .create();

  335. dialog.show();

  336. }

  337. }

  338. }

运行结果如下:

三、遇到的问题以及解决方法

问题:运行app时无法识别。

解决方法:打开手机的录音权限即可。

4.学习感悟、思考等

在实验开始之前,我首先下载并安装了科大讯飞的SDK,阅读了相关的文档和教程。文档中详细介绍了SDK的使用方法和注意事项然而,当我真正开始动手时,发现事情并没有想象中那么简单。在这个实验过程中,我有幸能够使用科大讯飞的语音识别技术,并将其集成到一个Android应用中。整个过程让我学到了许多技术知识。通过这个实验,我掌握了科大讯飞语音识别技术的使用方法,还学会了如何在实际项目中集成第三方服务。这种技能在未来的工作和学习中将大有裨益。最后感谢老师的指导!

参考资料

...全文
216 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

102

社区成员

发帖
与我相关
我的任务
社区描述
实验报告
android 高校
社区管理员
  • blackwall0321
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧