版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

本Demo将百度语音SDK(其中一部分功能)和自定义的UI对话框封装到一个module中,便于后续的SDK版本更新以及调用。

本Demo使用的百度语音SDK版本是audiobd_speech_sdk_asr_v3.0.7.3_bdasr_20180313_726f26e。

本Demo中使用的appkey已失效,请自行创建应用,使用新的appkey。

效果图

前提

(1)新建项目(获取包名)

(2)在百度AI开发平台上创建应用,获取API Key及Secret Key

官网地址:http://ai.baidu.com/tech/speech

1、成为开发者

参考《接入指南

2、创建应用

2.1、点击百度AI开放平台导航右侧的控制台,选择需要使用的AI服务项【这里选择语音技术】。

2.2、创建应用

2.3、填写应用信息

2.4、创建成功

2.5、应用列表

(3)下载SDK

3.1、管理应用

3.2、下载SDK

下载地址:https://ai.baidu.com/sdk#asr

代码分析

普通话 search搜索模型:参考SpeechBottomSheetDialog.java类

普通话 input输入法模型,适用于长句及长语音,有逗号分割,无语义:参考SpeechLongBottomSheetDialog.java类

注意:关于语音识别状态维护,API调用的代码,是自己根据官网demo的理解进行整理的,可能有所偏颇,仅供参考。【希望官网demo可以添加百度APP的语音对话框效果就好了】

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

(1)新建module,命名为BaiduSpeech

(2)在baiduspeech的AndroidManifest.xml中添加以下代码

从官方demo的AndroidManifest.xml中找到如下信息,然后复制到您自己的同名文件中。此处需要您复制1、权限2、官网申请的应用信息3、SDK的Service。

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2. package="com.why.project.baiduspeech">
  3.  
  4. <!-- ======================百度语音====================== -->
  5. <!-- begin: baidu speech sdk 权限 -->
  6. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  7. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  8. <uses-permission android:name="android.permission.INTERNET" />
  9. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  10. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  11. <!-- end: baidu speech sdk 权限 -->
  12.  
  13. <application>
  14.  
  15. <!-- ======================百度语音========================== -->
  16. <!-- 正式发布时,请替换成您自己的appId 本demo的appId会不定时下线 -->
  17. <meta-data
  18. android:name="com.baidu.speech.APP_ID"
  19. android:value="11588936" />
  20. <meta-data
  21. android:name="com.baidu.speech.API_KEY"
  22. android:value="XRF3IOf2tNGePzlv47cBnvF3" />
  23. <meta-data
  24. android:name="com.baidu.speech.SECRET_KEY"
  25. android:value="diC8lQ7XDcGBKQ6FzCpvnan54F5CnMZI" />
  26. <service
  27. android:name="com.baidu.speech.VoiceRecognitionService"
  28. android:exported="false" />
  29. </application>
  30. </manifest>

注意:此时<service>标签那里是红色错误的标记,暂时不用管,导入jar、so文件后编译下就正常了。

(3)复制jar 文件

将官方demo中的app\libs\bdasr_V3_20180320_9066860.jar复制进您项目的同名目录。

在build.gradle中确认是否含有以下红色标记的代码

(4)复制jni库的so文件

复制官方demo中 app\src\main\jniLibs 至项目的同名目录。

这个时候编译下,就会发现AndroidManifest.xml文件的<service>标签那里正常了。

(5)在官方demo中找到下面的文件复制到项目中(按照下面的包名进行查找)【注意,复制过来后,需要重新import 相关类】

(6)修改MessageStatusRecogListener.java文件【根据实际情况进行修改】

  1. package com.why.project.baiduspeech.recognization;
  2.  
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.util.Log;
  6.  
  7. /**
  8. * Created by fujiayi on 2017/6/16.
  9. */
  10.  
  11. public class MessageStatusRecogListener extends StatusRecogListener {
  12. private Handler handler;
  13.  
  14. private long speechEndTime;
  15.  
  16. private boolean needTime = true;
  17.  
  18. private static final String TAG = "MesStatusRecogListener";
  19.  
  20. public MessageStatusRecogListener(Handler handler) {
  21. this.handler = handler;
  22. }
  23.  
  24. @Override
  25. public void onAsrReady() {
  26. super.onAsrReady();
  27. sendStatusMessage("引擎就绪,可以开始说话。");
  28. }
  29.  
  30. @Override
  31. public void onAsrBegin() {
  32. super.onAsrBegin();
  33. sendStatusMessage("检测到用户说话");
  34. }
  35.  
  36. @Override
  37. public void onAsrEnd() {
  38. super.onAsrEnd();
  39. speechEndTime = System.currentTimeMillis();
  40. sendMessage("检测到用户说话结束");
  41. }
  42.  
  43. @Override
  44. public void onAsrPartialResult(String[] results, RecogResult recogResult) {
  45. sendStatusMessage("临时识别结果,结果是“" + results[0] + "”;原始json:" + recogResult.getOrigalJson());
  46. super.onAsrPartialResult(results, recogResult);
  47. }
  48.  
  49. @Override
  50. public void onAsrFinalResult(String[] results, RecogResult recogResult) {
  51. super.onAsrFinalResult(results, recogResult);
  52. //String message = "识别结束,结果是”" + results[0] + "”";//why 实际中可以去掉,不需要
  53. String message = recogResult.getOrigalJson();//{"results_recognition":["什么什么"],"origin_result":{"corpus_no":6522034498058113957,"err_no":0,"result":{"word":["什么什么"]},"sn":"bfa8b286-ab0e-4f86-9209-1d36d38b1224","voice_energy":16191.7705078125},"error":0,"best_result":"什么什么","result_type":"final_result"}
  54. sendStatusMessage(message + "“;原始json:" + recogResult.getOrigalJson());
  55. if (speechEndTime > 0) {
  56. long diffTime = System.currentTimeMillis() - speechEndTime;
  57. //message += ";说话结束到识别结束耗时【" + diffTime + "ms】";// why 实际中可以去掉,不需要
  58.  
  59. }
  60. speechEndTime = 0;
  61. sendMessage(message, status, true);
  62. }
  63.  
  64. @Override
  65. public void onAsrFinishError(int errorCode, int subErrorCode, String errorMessage, String descMessage,
  66. RecogResult recogResult) {
  67. super.onAsrFinishError(errorCode, subErrorCode, errorMessage, descMessage, recogResult);
  68. //String message = "识别错误, 错误码:" + errorCode + " ," + subErrorCode + " ; " + descMessage;// why 实际中可以去掉,不需要
  69. String message = recogResult.getOrigalJson();//{"origin_result":{"sn":"","error":7,"desc":"No recognition result match","sub_error":7001},"error":7,"desc":"No recognition result match","sub_error":7001}
  70. sendStatusMessage(message + ";错误消息:" + errorMessage + ";描述信息:" + descMessage);
  71. if (speechEndTime > 0) {
  72. long diffTime = System.currentTimeMillis() - speechEndTime;
  73. //message += "。说话结束到识别结束耗时【" + diffTime + "ms】";// why实际中可以去掉,不需要
  74. }
  75. speechEndTime = 0;
  76. sendMessage(message, status, true);
  77. speechEndTime = 0;
  78. }
  79.  
  80. @Override
  81. public void onAsrOnlineNluResult(String nluResult) {
  82. super.onAsrOnlineNluResult(nluResult);
  83. if (!nluResult.isEmpty()) {
  84. sendStatusMessage("原始语义识别结果json:" + nluResult);
  85. }
  86. }
  87.  
  88. @Override
  89. public void onAsrFinish(RecogResult recogResult) {
  90. super.onAsrFinish(recogResult);
  91. sendStatusMessage("识别一段话结束。如果是长语音的情况会继续识别下段话。");
  92.  
  93. }
  94.  
  95. /**
  96. * 长语音识别结束
  97. */
  98. @Override
  99. public void onAsrLongFinish() {
  100. super.onAsrLongFinish();
  101. sendStatusMessage("长语音识别结束。");
  102. }
  103.  
  104. /**
  105. * 使用离线命令词时,有该回调说明离线语法资源加载成功
  106. */
  107. @Override
  108. public void onOfflineLoaded() {
  109. sendStatusMessage("【重要】asr.loaded:离线资源加载成功。没有此回调可能离线语法功能不能使用。");
  110. }
  111.  
  112. /**
  113. * 使用离线命令词时,有该回调说明离线语法资源加载成功
  114. */
  115. @Override
  116. public void onOfflineUnLoaded() {
  117. sendStatusMessage(" 离线资源卸载成功。");
  118. }
  119.  
  120. @Override
  121. public void onAsrExit() {
  122. super.onAsrExit();
  123. sendStatusMessage("识别引擎结束并空闲中");
  124. }
  125.  
  126. private void sendStatusMessage(String message) {
  127. sendMessage(message, status);
  128. }
  129.  
  130. private void sendMessage(String message) {
  131. sendMessage(message, WHAT_MESSAGE_STATUS);
  132. }
  133.  
  134. private void sendMessage(String message, int what) {
  135. sendMessage(message, what, false);
  136. }
  137.  
  138. private void sendMessage(String message, int what, boolean highlight) {
  139.  
  140. if (needTime && what != STATUS_FINISHED) {
  141. message += " ;time=" + System.currentTimeMillis();
  142. }
  143. if (handler == null){
  144. Log.i(TAG, message );
  145. return;
  146. }
  147. Message msg = Message.obtain();
  148. msg.what = what;
  149. msg.arg1 = status;
  150. if (highlight) {
  151. msg.arg2 = 1;
  152. }
  153. msg.obj = message + "\n";
  154. handler.sendMessage(msg);
  155. }
  156. }

至此,百度语音SDK集成到baiduspeech中了,下一步就是在baiduspeech中创建UI对话框。

(7)创建底部对话框SpeechBottomSheetDialog【根据实际情况自行修改UI布局】

1、在baiduspeech的build.gradle中引用recyclerview【版本号和项目的appcompat保持一致】【因为demo中用到了】

  1. apply plugin: 'com.android.library'
  2.  
  3. android {
  4. compileSdkVersion 27
  5.  
  6. defaultConfig {
  7. minSdkVersion 16
  8. targetSdkVersion 27
  9. versionCode 1
  10. versionName "1.0"
  11.  
  12. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  13.  
  14. }
  15.  
  16. buildTypes {
  17. release {
  18. minifyEnabled false
  19. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  20. }
  21. }
  22.  
  23. }
  24.  
  25. dependencies {
  26. implementation fileTree(dir: 'libs', include: ['*.jar'])
  27.  
  28. implementation 'com.android.support:appcompat-v7:27.1.1'
  29. testImplementation 'junit:junit:4.12'
  30. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  31. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  32.  
  33. //RecyclerView
  34. compile "com.android.support:recyclerview-v7:27.1.1"
  35. }

2、对话框类、列表适配器类、布局文件xml文件、图片资源、动画style样式等复制到baiduspeech中

3、这里主要标注下SpeechBottomSheetDialog.java中百度语音的相关代码

  1. package com.why.project.baiduspeech.dialog;
  2.  
  3. import android.content.Context;
  4. import android.content.DialogInterface;
  5. import android.graphics.drawable.ColorDrawable;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.support.v4.app.DialogFragment;
  10. import android.support.v7.widget.LinearLayoutManager;
  11. import android.support.v7.widget.RecyclerView;
  12. import android.util.DisplayMetrics;
  13. import android.util.Log;
  14. import android.view.Gravity;
  15. import android.view.LayoutInflater;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.view.Window;
  19. import android.widget.Button;
  20. import android.widget.ImageView;
  21. import android.widget.ProgressBar;
  22. import android.widget.TextView;
  23. import android.widget.Toast;
  24.  
  25. import com.baidu.speech.asr.SpeechConstant;
  26. import com.baidu.speech.utils.LogUtil;
  27. import com.why.project.baiduspeech.R;
  28. import com.why.project.baiduspeech.control.MyRecognizer;
  29. import com.why.project.baiduspeech.recognization.IStatus;
  30. import com.why.project.baiduspeech.recognization.MessageStatusRecogListener;
  31. import com.why.project.baiduspeech.recognization.StatusRecogListener;
  32. import com.why.project.baiduspeech.util.Logger;
  33.  
  34. import org.json.JSONArray;
  35. import org.json.JSONException;
  36. import org.json.JSONObject;
  37.  
  38. import java.util.ArrayList;
  39. import java.util.LinkedHashMap;
  40. import java.util.Map;
  41.  
  42. /**
  43. * Created by HaiyuKing
  44. * Used 语音识别底部对话框
  45. */
  46.  
  47. public class SpeechBottomSheetDialog extends DialogFragment {
  48. private static final String TAG = SpeechBottomSheetDialog.class.getSimpleName();
  49.  
  50. private Context mContext;
  51. /**View实例*/
  52. private View myView;
  53.  
  54. private ImageView img_close;
  55. private ProgressBar loadProgressBar;
  56. private TextView tv_tishi;
  57. private RecyclerView result_list;
  58. private Button btn_start;
  59.  
  60. private ArrayList<String> resultWordList;
  61. private SpeechResultAdapter speechResultAdapter;
  62.  
  63. private String BtnStartText = "按一下开始听音";
  64. private String BtnStopText = "按一下结束听音";
  65. private String BtnSearchingText = "正在识别";
  66.  
  67. private String TishiNoText = "没听清,请重说一遍";
  68.  
  69. /**识别控制器,使用MyRecognizer控制识别的流程*/
  70. protected MyRecognizer myRecognizer;
  71. /**控制UI按钮的状态*/
  72. protected int status;
  73.  
  74. protected Handler handler;
  75.  
  76. public static SpeechBottomSheetDialog getInstance(Context mContext)
  77. {
  78. SpeechBottomSheetDialog speechBottomSheetDialog = new SpeechBottomSheetDialog();
  79. speechBottomSheetDialog.mContext = mContext;
  80.  
  81. return speechBottomSheetDialog;
  82. }
  83.  
  84. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  85. Bundle savedInstanceState) {
  86. getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0));//设置背景为透明,并且没有标题
  87. myView = inflater.inflate(R.layout.dialog_bottomsheet_speech, container, false);
  88. return myView;
  89.  
  90. }
  91.  
  92. @Override
  93. public void onActivityCreated(Bundle savedInstanceState) {
  94. // TODO Auto-generated method stub
  95. super.onActivityCreated(savedInstanceState);
  96.  
  97. initHandler();//初始化handler
  98. initRecog();//初始化语音
  99.  
  100. initViews();
  101. initDatas();
  102. initEvents();
  103. }
  104.  
  105. /**
  106. * 设置宽度和高度值,以及打开的动画效果
  107. */
  108. @Override
  109. public void onStart() {
  110. super.onStart();
  111. //设置对话框的宽高,必须在onStart中
  112. DisplayMetrics metrics = new DisplayMetrics();
  113. this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
  114. Window window = this.getDialog().getWindow();
  115. window.setLayout(metrics.widthPixels, this.getDialog().getWindow().getAttributes().height);
  116. window.setGravity(Gravity.BOTTOM);//设置在底部
  117. //打开的动画效果
  118. //设置dialog的 进出 动画
  119. getDialog().getWindow().setWindowAnimations(R.style.speechbottomsheetdialog_animation);
  120. }
  121.  
  122. @Override
  123. public void onDismiss(DialogInterface dialog) {
  124. super.onDismiss(dialog);
  125. LogUtil.w(TAG,"{onDismiss}");
  126. //当对话框消失的时候统一执行销毁语音功能
  127. destroyRecog();//销毁语音
  128. }
  129.  
  130. private void initViews() {
  131. img_close = (ImageView) myView.findViewById(R.id.img_close);
  132. loadProgressBar = (ProgressBar) myView.findViewById(R.id.loadProgressBar);
  133. tv_tishi = (TextView) myView.findViewById(R.id.tv_tishi);
  134. result_list = (RecyclerView) myView.findViewById(R.id.result_list);
  135. btn_start = (Button) myView.findViewById(R.id.btn_start);
  136. }
  137.  
  138. /**初始化数据*/
  139. private void initDatas() {
  140. resultWordList = new ArrayList<String>();
  141. speechResultAdapter = null;
  142. //设置布局管理器
  143. LinearLayoutManager linerLayoutManager = new LinearLayoutManager(getActivity());
  144. result_list.setLayoutManager(linerLayoutManager);
  145.  
  146. //可以设置为打开后自动识别语音
  147. startRecog();
  148. showProgress();
  149. }
  150.  
  151. private void initEvents() {
  152. //关闭图标的点击事件
  153. img_close.setOnClickListener(new View.OnClickListener() {
  154. @Override
  155. public void onClick(View v) {
  156. dismiss();
  157. }
  158. });
  159.  
  160. //按钮的点击事件
  161. btn_start.setOnClickListener(new View.OnClickListener() {
  162. @Override
  163. public void onClick(View v) {
  164. switch (status) {
  165. case IStatus.STATUS_NONE: // 初始状态
  166. startRecog();
  167. status = IStatus.STATUS_WAITING_READY;
  168. updateBtnTextByStatus();//更改按钮的文本
  169. //显示加载区域
  170. showProgress();
  171. break;
  172. case IStatus.STATUS_WAITING_READY: // 调用本类的start方法后,即输入START事件后,等待引擎准备完毕。
  173. case IStatus.STATUS_READY: // 引擎准备完毕。
  174. case IStatus.STATUS_SPEAKING:
  175. case IStatus.STATUS_FINISHED: // 长语音情况
  176. case IStatus.STATUS_RECOGNITION:
  177. stopRecog();
  178. status = IStatus.STATUS_STOPPED; // 引擎识别中
  179. updateBtnTextByStatus();//更改按钮的文本
  180. break;
  181. case IStatus.STATUS_STOPPED: // 引擎识别中
  182. cancelRecog();
  183. status = IStatus.STATUS_NONE; // 识别结束,回到初始状态
  184. updateBtnTextByStatus();//更改按钮的文本
  185. break;
  186. default:
  187. break;
  188. }
  189. }
  190. });
  191. }
  192.  
  193. /**
  194. * 显示加载进度区域,隐藏其他区域*/
  195. private void showProgress(){
  196. loadProgressBar.setVisibility(View.VISIBLE);
  197. tv_tishi.setVisibility(View.GONE);
  198. result_list.setVisibility(View.GONE);
  199. }
  200.  
  201. /**
  202. * 显示文本提示区域,隐藏其他区域*/
  203. private void showTishi(){
  204. tv_tishi.setVisibility(View.VISIBLE);
  205. loadProgressBar.setVisibility(View.GONE);
  206. result_list.setVisibility(View.GONE);
  207. }
  208.  
  209. /**
  210. * 显示语音结果区域,隐藏其他区域*/
  211. private void showListView(){
  212. result_list.setVisibility(View.VISIBLE);
  213. loadProgressBar.setVisibility(View.GONE);
  214. tv_tishi.setVisibility(View.GONE);
  215. }
  216.  
  217. //======================================语音相关代码==========================================
  218. /**
  219. * 初始化handler*/
  220. private void initHandler(){
  221. handler = new Handler() {
  222. /*@param msg*/
  223. @Override
  224. public void handleMessage(Message msg) {
  225. super.handleMessage(msg);
  226. handleMsg(msg);
  227. }
  228. };
  229. Logger.setHandler(handler);
  230. }
  231.  
  232. /**
  233. * 在onCreate中调用。初始化识别控制类MyRecognizer
  234. */
  235. protected void initRecog() {
  236.  
  237. StatusRecogListener listener = new MessageStatusRecogListener(handler);
  238. myRecognizer = new MyRecognizer(mContext,listener);
  239.  
  240. status = IStatus.STATUS_NONE;//默认什么也没有做
  241. }
  242.  
  243. /**
  244. * 销毁时需要释放识别资源。
  245. */
  246. protected void destroyRecog() {
  247. myRecognizer.release();
  248. Log.i(TAG, "destroyRecog");
  249. }
  250.  
  251. /**
  252. * 开始录音,点击“开始”按钮后调用。
  253. */
  254. protected void startRecog() {
  255. Map<String, Object> params = new LinkedHashMap<String, Object>();
  256. params.put(SpeechConstant.ACCEPT_AUDIO_DATA, false);//是否保存音频
  257. params.put(SpeechConstant.DISABLE_PUNCTUATION, false);//是否禁用标点符号,在选择输入法模型的前提下生效【不禁用的话,说完一段话,就自带标点符号】
  258. params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);//暂时不知道什么意思
  259. params.put(SpeechConstant.PID, 1536); // 普通话 search搜索模型,默认,适用于短句,无逗号,可以有语义
  260. //params.put(SpeechConstant.VAD_ENDPOINT_TIMEOUT, 0); // 长语音,建议搭配input输入法模型
  261. myRecognizer.start(params);
  262. }
  263.  
  264. /**
  265. * 开始录音后,手动停止录音。SDK会识别在此过程中的录音。点击“停止”按钮后调用。
  266. */
  267. private void stopRecog() {
  268. myRecognizer.stop();
  269. }
  270.  
  271. /**
  272. * 开始录音后,取消这次录音。SDK会取消本次识别,回到原始状态。点击“取消”按钮后调用。
  273. */
  274. private void cancelRecog() {
  275. myRecognizer.cancel();
  276. }
  277.  
  278. protected void handleMsg(Message msg) {
  279. Log.e(TAG,"msg.what="+msg.what);
  280. Log.e(TAG,"msg.obj.toString()="+msg.obj.toString());
  281. Log.e(TAG,"msg.arg2="+msg.arg2);
  282. switch (msg.what) { // 处理MessageStatusRecogListener中的状态回调
  283. case IStatus.STATUS_FINISHED:
  284. //识别结束时候的调用【判断显示结果列表区域还是提示区域】
  285. if (msg.arg2 == 1) {
  286. //解析json字符串
  287. try {
  288. JSONObject msgObj = new JSONObject(msg.obj.toString());
  289. String error = msgObj.getString("error");
  290. if(error.equals("0")){
  291. //解析结果集合,展现列表
  292. JSONObject origin_resultObj = msgObj.getJSONObject("origin_result");
  293. JSONObject resultObj = origin_resultObj.getJSONObject("result");
  294. JSONArray wordList = resultObj.getJSONArray("word");
  295.  
  296. initList(wordList);//初始化集合数据
  297.  
  298. showListView();
  299. }else if(error.equals("7")){
  300. tv_tishi.setText(TishiNoText);
  301. showTishi();
  302. }else{//应该根据不同的状态值,显示不同的提示
  303. tv_tishi.setText(TishiNoText);
  304. showTishi();
  305. }
  306. } catch (JSONException e) {
  307. e.printStackTrace();
  308. tv_tishi.setText(TishiNoText);
  309. showTishi();
  310. }
  311. }else if(msg.arg2 == 0){//无网络的情况
  312. //解析json字符串{"origin_result":{"sn":"","error":2,"desc":"Network is not available","sub_error":2100},"error":2,"desc":"Network is not available","sub_error":2100}
  313. try {
  314. JSONObject msgObj = new JSONObject(msg.obj.toString());
  315. JSONObject origin_resultObj = msgObj.getJSONObject("origin_result");
  316. String error = origin_resultObj.getString("error");
  317. if(error.equals("2")){
  318. //解析结果集合,展现列表
  319. String desc = origin_resultObj.getString("desc");
  320. Toast.makeText(mContext,desc,Toast.LENGTH_SHORT).show();
  321. }
  322. } catch (JSONException e) {
  323. e.printStackTrace();
  324. }
  325. }
  326. status = msg.what;
  327. updateBtnTextByStatus();
  328. break;
  329. case IStatus.STATUS_NONE:
  330. case IStatus.STATUS_READY:
  331. case IStatus.STATUS_SPEAKING:
  332. case IStatus.STATUS_RECOGNITION:
  333. status = msg.what;
  334. updateBtnTextByStatus();
  335. break;
  336. default:
  337. break;
  338. }
  339. }
  340.  
  341. /**更改按钮的文本*/
  342. private void updateBtnTextByStatus() {
  343. switch (status) {
  344. case IStatus.STATUS_NONE:
  345. btn_start.setText(BtnStartText);
  346. btn_start.setEnabled(true);
  347. break;
  348. case IStatus.STATUS_WAITING_READY:
  349. case IStatus.STATUS_READY:
  350. case IStatus.STATUS_SPEAKING:
  351. case IStatus.STATUS_RECOGNITION:
  352. btn_start.setText(BtnStopText);
  353. btn_start.setEnabled(true);
  354. break;
  355. case IStatus.STATUS_STOPPED:
  356. btn_start.setText(BtnSearchingText);
  357. btn_start.setEnabled(true);
  358. break;
  359. default:
  360. break;
  361. }
  362. }
  363.  
  364. //========================================更改列表==========================
  365. /**获取集合数据,并显示*/
  366. private void initList(JSONArray wordList){
  367. //先清空
  368. if(resultWordList.size() > 0){
  369. resultWordList.clear();
  370. }
  371. //再赋值
  372. for(int i=0;i<wordList.length();i++){
  373. String wordItem = "";
  374. try {
  375. wordItem = wordList.getString(i);
  376. } catch (JSONException e) {
  377. e.printStackTrace();
  378. }
  379. resultWordList.add(wordItem);
  380. }
  381.  
  382. if(speechResultAdapter == null){
  383. //设置适配器
  384. speechResultAdapter = new SpeechResultAdapter(getActivity(), resultWordList);
  385. result_list.setAdapter(speechResultAdapter);
  386. //添加分割线
  387. //设置添加删除动画
  388.  
  389. //调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
  390. result_list.setSelected(true);
  391. }else{
  392. speechResultAdapter.notifyDataSetChanged();
  393. }
  394.  
  395. speechResultAdapter.setOnItemClickLitener(new SpeechResultAdapter.OnItemClickLitener() {
  396. @Override
  397. public void onItemClick(int position) {
  398. dismiss();
  399. if(mOnResultListItemClickListener != null){
  400. mOnResultListItemClickListener.onItemClick(resultWordList.get(position));
  401. }
  402. }
  403. });
  404. }
  405.  
  406. //=========================语音列表项的点击事件监听==============================
  407. public static abstract interface OnResultListItemClickListener
  408. {
  409. //语音结果列表项的点击事件接口
  410. public abstract void onItemClick(String title);
  411. }
  412.  
  413. private OnResultListItemClickListener mOnResultListItemClickListener;
  414.  
  415. public void seOnResultListItemClickListener(OnResultListItemClickListener mOnResultListItemClickListener)
  416. {
  417. this.mOnResultListItemClickListener = mOnResultListItemClickListener;
  418. }
  419.  
  420. }

4、如果想要使用长语音功能,请参考SpeechLongBottomSheetDialog.java文件

  1. package com.why.project.baiduspeech.dialog;
  2.  
  3. import android.content.Context;
  4. import android.content.DialogInterface;
  5. import android.graphics.drawable.ColorDrawable;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.support.v4.app.DialogFragment;
  10. import android.support.v7.widget.LinearLayoutManager;
  11. import android.support.v7.widget.RecyclerView;
  12. import android.util.DisplayMetrics;
  13. import android.util.Log;
  14. import android.view.Gravity;
  15. import android.view.LayoutInflater;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.view.Window;
  19. import android.widget.Button;
  20. import android.widget.ImageView;
  21. import android.widget.ProgressBar;
  22. import android.widget.TextView;
  23. import android.widget.Toast;
  24.  
  25. import com.baidu.speech.asr.SpeechConstant;
  26. import com.baidu.speech.utils.LogUtil;
  27. import com.why.project.baiduspeech.R;
  28. import com.why.project.baiduspeech.control.MyRecognizer;
  29. import com.why.project.baiduspeech.recognization.IStatus;
  30. import com.why.project.baiduspeech.recognization.MessageStatusRecogListener;
  31. import com.why.project.baiduspeech.recognization.StatusRecogListener;
  32. import com.why.project.baiduspeech.util.Logger;
  33.  
  34. import org.json.JSONArray;
  35. import org.json.JSONException;
  36. import org.json.JSONObject;
  37.  
  38. import java.util.ArrayList;
  39. import java.util.LinkedHashMap;
  40. import java.util.Map;
  41.  
  42. /**
  43. * Created by HaiyuKing
  44. * Used 普通话 input输入法模型,适用于长句及长语音,有逗号分割,无语义【基本上和SpeechBottomSheetDialog代码相同】
  45. */
  46.  
  47. public class SpeechLongBottomSheetDialog extends DialogFragment {
  48. private static final String TAG = SpeechBottomSheetDialog.class.getSimpleName();
  49.  
  50. private Context mContext;
  51. /**View实例*/
  52. private View myView;
  53.  
  54. private ImageView img_close;
  55. private ProgressBar loadProgressBar;
  56. private TextView tv_tishi;
  57. private RecyclerView result_list;
  58. private Button btn_start;
  59.  
  60. private ArrayList<String> resultWordList;
  61. private SpeechResultAdapter speechResultAdapter;
  62.  
  63. private String BtnStartText = "按一下开始听音";
  64. private String BtnStopText = "按一下结束听音";
  65. private String BtnSearchingText = "正在识别";
  66.  
  67. private String TishiNoText = "没听清,请重说一遍";
  68.  
  69. /**识别控制器,使用MyRecognizer控制识别的流程*/
  70. protected MyRecognizer myRecognizer;
  71. /**控制UI按钮的状态*/
  72. protected int status;
  73.  
  74. protected Handler handler;
  75.  
  76. public static SpeechLongBottomSheetDialog getInstance(Context mContext)
  77. {
  78. SpeechLongBottomSheetDialog speechLongBottomSheetDialog = new SpeechLongBottomSheetDialog();
  79. speechLongBottomSheetDialog.mContext = mContext;
  80.  
  81. return speechLongBottomSheetDialog;
  82. }
  83.  
  84. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  85. Bundle savedInstanceState) {
  86. getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0));//设置背景为透明,并且没有标题
  87. myView = inflater.inflate(R.layout.dialog_bottomsheet_speech, container, false);
  88. return myView;
  89.  
  90. }
  91.  
  92. @Override
  93. public void onActivityCreated(Bundle savedInstanceState) {
  94. // TODO Auto-generated method stub
  95. super.onActivityCreated(savedInstanceState);
  96.  
  97. initHandler();//初始化handler
  98. initRecog();//初始化语音
  99.  
  100. initViews();
  101. initDatas();
  102. initEvents();
  103. }
  104.  
  105. /**
  106. * 设置宽度和高度值,以及打开的动画效果
  107. */
  108. @Override
  109. public void onStart() {
  110. super.onStart();
  111. //设置对话框的宽高,必须在onStart中
  112. DisplayMetrics metrics = new DisplayMetrics();
  113. this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
  114. Window window = this.getDialog().getWindow();
  115. window.setLayout(metrics.widthPixels, this.getDialog().getWindow().getAttributes().height);
  116. window.setGravity(Gravity.BOTTOM);//设置在底部
  117. //打开的动画效果
  118. //设置dialog的 进出 动画
  119. getDialog().getWindow().setWindowAnimations(R.style.speechbottomsheetdialog_animation);
  120. }
  121.  
  122. @Override
  123. public void onDismiss(DialogInterface dialog) {
  124. super.onDismiss(dialog);
  125. LogUtil.w(TAG,"{onDismiss}");
  126. //当对话框消失的时候统一执行销毁语音功能
  127. destroyRecog();//销毁语音
  128. }
  129.  
  130. private void initViews() {
  131. img_close = (ImageView) myView.findViewById(R.id.img_close);
  132. loadProgressBar = (ProgressBar) myView.findViewById(R.id.loadProgressBar);
  133. tv_tishi = (TextView) myView.findViewById(R.id.tv_tishi);
  134. result_list = (RecyclerView) myView.findViewById(R.id.result_list);
  135. btn_start = (Button) myView.findViewById(R.id.btn_start);
  136. }
  137.  
  138. /**初始化数据*/
  139. private void initDatas() {
  140. resultWordList = new ArrayList<String>();
  141. speechResultAdapter = null;
  142. //设置布局管理器
  143. LinearLayoutManager linerLayoutManager = new LinearLayoutManager(getActivity());
  144. result_list.setLayoutManager(linerLayoutManager);
  145.  
  146. btn_start.setText(BtnStartText);//显示文字,和下面的二选一即可 why
  147. //可以设置为打开后自动识别语音
  148. /*startRecog();
  149. showProgress();*/
  150. }
  151.  
  152. private void initEvents() {
  153. //关闭图标的点击事件
  154. img_close.setOnClickListener(new View.OnClickListener() {
  155. @Override
  156. public void onClick(View v) {
  157. dismiss();
  158. }
  159. });
  160.  
  161. //按钮的点击事件
  162. btn_start.setOnClickListener(new View.OnClickListener() {
  163. @Override
  164. public void onClick(View v) {
  165. switch (status) {
  166. case IStatus.STATUS_NONE: // 初始状态
  167. startRecog();
  168. status = IStatus.STATUS_WAITING_READY;
  169. updateBtnTextByStatus();//更改按钮的文本
  170. //显示加载区域
  171. showProgress();
  172. break;
  173. case IStatus.STATUS_WAITING_READY: // 调用本类的start方法后,即输入START事件后,等待引擎准备完毕。
  174. case IStatus.STATUS_READY: // 引擎准备完毕。
  175. case IStatus.STATUS_SPEAKING:
  176. case IStatus.STATUS_FINISHED: // 长语音情况
  177. case IStatus.STATUS_RECOGNITION:
  178. stopRecog();
  179. status = IStatus.STATUS_STOPPED; // 引擎识别中
  180. updateBtnTextByStatus();//更改按钮的文本
  181. //对于长语音来讲,需要手动执行代码,否则还得点击一次才能取消why
  182. btn_start.callOnClick();
  183. break;
  184. case IStatus.STATUS_STOPPED: // 引擎识别中
  185. cancelRecog();
  186. hiddenAll();//隐藏加载区域why
  187. status = IStatus.STATUS_NONE; // 识别结束,回到初始状态
  188. updateBtnTextByStatus();//更改按钮的文本
  189. break;
  190. default:
  191. break;
  192. }
  193. }
  194. });
  195. }
  196.  
  197. /**
  198. * 显示加载进度区域,隐藏其他区域*/
  199. private void showProgress(){
  200. loadProgressBar.setVisibility(View.VISIBLE);
  201. tv_tishi.setVisibility(View.GONE);
  202. result_list.setVisibility(View.GONE);
  203. }
  204.  
  205. /**
  206. * 显示文本提示区域,隐藏其他区域*/
  207. private void showTishi(){
  208. tv_tishi.setVisibility(View.VISIBLE);
  209. loadProgressBar.setVisibility(View.GONE);
  210. result_list.setVisibility(View.GONE);
  211. }
  212.  
  213. /**
  214. * 显示语音结果区域,隐藏其他区域*/
  215. private void showListView(){
  216. result_list.setVisibility(View.VISIBLE);
  217. loadProgressBar.setVisibility(View.GONE);
  218. tv_tishi.setVisibility(View.GONE);
  219. }
  220.  
  221. /**隐藏所有的区域【主要用于长语音】why*/
  222. private void hiddenAll(){
  223. result_list.setVisibility(View.GONE);
  224. loadProgressBar.setVisibility(View.GONE);
  225. tv_tishi.setVisibility(View.GONE);
  226. }
  227.  
  228. //======================================语音相关代码==========================================
  229. /**
  230. * 初始化handler*/
  231. private void initHandler(){
  232. handler = new Handler() {
  233. /*@param msg*/
  234. @Override
  235. public void handleMessage(Message msg) {
  236. super.handleMessage(msg);
  237. handleMsg(msg);
  238. }
  239. };
  240. Logger.setHandler(handler);
  241. }
  242.  
  243. /**
  244. * 在onCreate中调用。初始化识别控制类MyRecognizer
  245. */
  246. protected void initRecog() {
  247.  
  248. StatusRecogListener listener = new MessageStatusRecogListener(handler);
  249. myRecognizer = new MyRecognizer(mContext,listener);
  250.  
  251. status = IStatus.STATUS_NONE;//默认什么也没有做
  252. }
  253.  
  254. /**
  255. * 销毁时需要释放识别资源。
  256. */
  257. protected void destroyRecog() {
  258. myRecognizer.release();
  259. Log.i(TAG, "destroyRecog");
  260. }
  261.  
  262. /**
  263. * 开始录音,点击“开始”按钮后调用。
  264. */
  265. protected void startRecog() {
  266. Map<String, Object> params = new LinkedHashMap<String, Object>();
  267. params.put(SpeechConstant.ACCEPT_AUDIO_DATA, false);//是否保存音频
  268. params.put(SpeechConstant.DISABLE_PUNCTUATION, false);//是否禁用标点符号,在选择输入法模型的前提下生效【不禁用的话,说完一段话,就自带标点符号】
  269. params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);//暂时不知道什么意思
  270. //下面的1936和1537选择其中一个 why
  271. //params.put(SpeechConstant.PID, 1936); // 普通话 far,远场模型,高级,适用于音源离麦克风较远(>1m)的录音,有逗号分隔,可以有语义
  272. params.put(SpeechConstant.PID, 1537); // 普通话 input输入法模型,适用于长句及长语音,有逗号分割,无语义
  273. params.put(SpeechConstant.VAD_ENDPOINT_TIMEOUT, 0); // 长语音,建议搭配input输入法模型
  274. myRecognizer.start(params);
  275. }
  276.  
  277. /**
  278. * 开始录音后,手动停止录音。SDK会识别在此过程中的录音。点击“停止”按钮后调用。
  279. */
  280. private void stopRecog() {
  281. myRecognizer.stop();
  282. }
  283.  
  284. /**
  285. * 开始录音后,取消这次录音。SDK会取消本次识别,回到原始状态。点击“取消”按钮后调用。
  286. */
  287. private void cancelRecog() {
  288. myRecognizer.cancel();
  289. }
  290.  
  291. protected void handleMsg(Message msg) {
  292. switch (msg.what) { // 处理MessageStatusRecogListener中的状态回调
  293. case IStatus.STATUS_FINISHED:
  294. //识别结束时候的调用【判断显示结果列表区域还是提示区域】
  295. if (msg.arg2 == 1) {
  296. //解析json字符串
  297. try {
  298. JSONObject msgObj = new JSONObject(msg.obj.toString());
  299. String error = msgObj.getString("error");
  300. if(error.equals("0")){
  301. //直接输入到文本框中 why
  302. JSONArray recognitionObj = msgObj.getJSONArray("results_recognition");
  303. String result = recognitionObj.getString(0);
  304. if(mOnResultListItemClickListener != null){
  305. mOnResultListItemClickListener.onItemClick(result);
  306. }
  307. }else if(error.equals("7")){
  308. tv_tishi.setText(TishiNoText);
  309. showTishi();
  310. }else{//应该根据不同的状态值,显示不同的提示
  311. tv_tishi.setText(TishiNoText);
  312. showTishi();
  313. }
  314. } catch (JSONException e) {
  315. e.printStackTrace();
  316. tv_tishi.setText(TishiNoText);
  317. showTishi();
  318. }
  319. }else if(msg.arg2 == 0){//无网络的情况
  320. //解析json字符串{"origin_result":{"sn":"","error":2,"desc":"Network is not available","sub_error":2100},"error":2,"desc":"Network is not available","sub_error":2100}
  321. try {
  322. JSONObject msgObj = new JSONObject(msg.obj.toString());
  323. JSONObject origin_resultObj = msgObj.getJSONObject("origin_result");
  324. String error = origin_resultObj.getString("error");
  325. if(error.equals("2")){
  326. //解析结果集合,展现列表
  327. String desc = origin_resultObj.getString("desc");
  328. Toast.makeText(mContext,desc,Toast.LENGTH_SHORT).show();
  329. }
  330. } catch (JSONException e) {
  331. e.printStackTrace();
  332. }
  333. }
  334. status = msg.what;
  335. updateBtnTextByStatus();
  336. break;
  337. case IStatus.STATUS_NONE:
  338. case IStatus.STATUS_READY:
  339. case IStatus.STATUS_SPEAKING:
  340. case IStatus.STATUS_RECOGNITION:
  341. status = msg.what;
  342. updateBtnTextByStatus();
  343. break;
  344. default:
  345. break;
  346. }
  347. }
  348.  
  349. /**更改按钮的文本*/
  350. private void updateBtnTextByStatus() {
  351. switch (status) {
  352. case IStatus.STATUS_NONE:
  353. btn_start.setText(BtnStartText);
  354. btn_start.setEnabled(true);
  355. break;
  356. case IStatus.STATUS_WAITING_READY:
  357. case IStatus.STATUS_READY:
  358. case IStatus.STATUS_SPEAKING:
  359. case IStatus.STATUS_RECOGNITION:
  360. btn_start.setText(BtnStopText);
  361. btn_start.setEnabled(true);
  362. break;
  363. case IStatus.STATUS_STOPPED:
  364. btn_start.setText(BtnSearchingText);
  365. btn_start.setEnabled(true);
  366. break;
  367. default:
  368. break;
  369. }
  370. }
  371.  
  372. //========================================更改列表==========================
  373. /**获取集合数据,并显示*/
  374. private void initList(JSONArray wordList){
  375. //先清空
  376. if(resultWordList.size() > 0){
  377. resultWordList.clear();
  378. }
  379. //再赋值
  380. for(int i=0;i<wordList.length();i++){
  381. String wordItem = "";
  382. try {
  383. wordItem = wordList.getString(i);
  384. } catch (JSONException e) {
  385. e.printStackTrace();
  386. }
  387. resultWordList.add(wordItem);
  388. }
  389.  
  390. if(speechResultAdapter == null){
  391. //设置适配器
  392. speechResultAdapter = new SpeechResultAdapter(getActivity(), resultWordList);
  393. result_list.setAdapter(speechResultAdapter);
  394. //添加分割线
  395. //设置添加删除动画
  396.  
  397. //调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
  398. result_list.setSelected(true);
  399. }else{
  400. speechResultAdapter.notifyDataSetChanged();
  401. }
  402.  
  403. speechResultAdapter.setOnItemClickLitener(new SpeechResultAdapter.OnItemClickLitener() {
  404. @Override
  405. public void onItemClick(int position) {
  406. dismiss();
  407. if(mOnResultListItemClickListener != null){
  408. mOnResultListItemClickListener.onItemClick(resultWordList.get(position));
  409. }
  410. }
  411. });
  412. }
  413.  
  414. //=========================语音列表项的点击事件监听==============================
  415. public static abstract interface OnResultListItemClickListener
  416. {
  417. //语音结果列表项的点击事件接口
  418. public abstract void onItemClick(String title);
  419. }
  420.  
  421. private OnResultListItemClickListener mOnResultListItemClickListener;
  422.  
  423. public void seOnResultListItemClickListener(OnResultListItemClickListener mOnResultListItemClickListener)
  424. {
  425. this.mOnResultListItemClickListener = mOnResultListItemClickListener;
  426. }
  427. }

三、使用方法

(1)因为需要使用到运行时权限,所以参考《Android6.0运行时权限(基于RxPermission开源库)》在APP的build.gradle中引入第三方库

(2)在APP的build.gradle中引入baiduspeech

(3)在Activity中调用

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. tools:context="com.why.project.baiduspeechdemo.MainActivity">
  9.  
  10. <TextView
  11. android:id="@+id/tv_result"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:text="Hello World!"
  15. app:layout_constraintBottom_toBottomOf="parent"
  16. app:layout_constraintHorizontal_bias="0.448"
  17. app:layout_constraintLeft_toLeftOf="parent"
  18. app:layout_constraintRight_toRightOf="parent"
  19. app:layout_constraintTop_toTopOf="parent"
  20. app:layout_constraintVertical_bias="0.325"/>
  21.  
  22. <Button
  23. android:id="@+id/btn_openSpeechDialog"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_marginEnd="8dp"
  27. android:layout_marginStart="8dp"
  28. android:layout_marginTop="32dp"
  29. android:text="打开搜索模型语音识别对话框"
  30. app:layout_constraintEnd_toEndOf="parent"
  31. app:layout_constraintHorizontal_bias="0.419"
  32. app:layout_constraintStart_toStartOf="parent"
  33. app:layout_constraintTop_toTopOf="parent"/>
  34.  
  35. <Button
  36. android:id="@+id/btn_openSpeechLongDialog"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:layout_marginEnd="8dp"
  40. android:layout_marginStart="8dp"
  41. android:layout_marginTop="16dp"
  42. android:text="打开input输入模型语音识别对话框"
  43. app:layout_constraintEnd_toEndOf="parent"
  44. app:layout_constraintHorizontal_bias="0.4"
  45. app:layout_constraintStart_toStartOf="parent"
  46. app:layout_constraintTop_toBottomOf="@+id/btn_openSpeechDialog"/>
  47.  
  48. </android.support.constraint.ConstraintLayout>

activity_main.xml

  1. package com.why.project.baiduspeechdemo;
  2.  
  3. import android.Manifest;
  4. import android.os.Bundle;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.util.Log;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.TextView;
  10. import android.widget.Toast;
  11.  
  12. import com.tbruyelle.rxpermissions2.RxPermissions;
  13. import com.why.project.baiduspeech.dialog.SpeechBottomSheetDialog;
  14. import com.why.project.baiduspeech.dialog.SpeechLongBottomSheetDialog;
  15.  
  16. import io.reactivex.functions.Action;
  17. import io.reactivex.functions.Consumer;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20.  
  21. private static final String TAG = MainActivity.class.getSimpleName();
  22.  
  23. private Button mOpenSpeechDialogBtn;
  24. private Button mOpenSpeechLongDialogBtn;
  25. private TextView mResultTv;
  26.  
  27. @Override
  28. protected void onCreate(Bundle savedInstanceState) {
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31.  
  32. onePermission();
  33.  
  34. initViews();
  35. initEvents();
  36. }
  37.  
  38. private void initViews() {
  39. mOpenSpeechDialogBtn = findViewById(R.id.btn_openSpeechDialog);
  40. mOpenSpeechLongDialogBtn = findViewById(R.id.btn_openSpeechLongDialog);
  41. mResultTv = findViewById(R.id.tv_result);
  42. }
  43.  
  44. private void initEvents() {
  45. mOpenSpeechDialogBtn.setOnClickListener(new View.OnClickListener() {
  46. @Override
  47. public void onClick(View view) {
  48. //打开百度语音对话框
  49. SpeechBottomSheetDialog speechBottomSheetDialog = SpeechBottomSheetDialog.getInstance(MainActivity.this);
  50. speechBottomSheetDialog.seOnResultListItemClickListener(new SpeechBottomSheetDialog.OnResultListItemClickListener() {
  51. @Override
  52. public void onItemClick(String title) {
  53. //填充到输入框中
  54. mResultTv.setText(title);
  55. }
  56. });
  57. speechBottomSheetDialog.show(getSupportFragmentManager(), TAG);
  58. }
  59. });
  60. mOpenSpeechLongDialogBtn.setOnClickListener(new View.OnClickListener() {
  61. @Override
  62. public void onClick(View view) {
  63. //打开百度语音对话框
  64. SpeechLongBottomSheetDialog speechLongBottomSheetDialog = SpeechLongBottomSheetDialog.getInstance(MainActivity.this);
  65. speechLongBottomSheetDialog.seOnResultListItemClickListener(new SpeechLongBottomSheetDialog.OnResultListItemClickListener() {
  66. @Override
  67. public void onItemClick(String title) {
  68. //填充到输入框中
  69. mResultTv.setText(mResultTv.getText()+title);
  70. }
  71. });
  72. speechLongBottomSheetDialog.show(getSupportFragmentManager(), TAG);
  73. }
  74. });
  75.  
  76. }
  77.  
  78. /**只有一个运行时权限申请的情况*/
  79. private void onePermission(){
  80. RxPermissions rxPermissions = new RxPermissions(MainActivity.this); // where this is an Activity instance
  81. rxPermissions.request(Manifest.permission.RECORD_AUDIO,
  82. Manifest.permission.READ_PHONE_STATE,
  83. Manifest.permission.WRITE_EXTERNAL_STORAGE) //权限名称,多个权限之间逗号分隔开
  84. .subscribe(new Consumer<Boolean>() {
  85. @Override
  86. public void accept(Boolean granted) throws Exception {
  87. Log.e(TAG, "{accept}granted=" + granted);//执行顺序——1【多个权限的情况,只有所有的权限均允许的情况下granted==true】
  88. if (granted) { // 在android 6.0之前会默认返回true
  89. // 已经获取权限
  90. } else {
  91. // 未获取权限
  92. Toast.makeText(MainActivity.this, "您没有授权该权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();
  93. }
  94. }
  95. }, new Consumer<Throwable>() {
  96. @Override
  97. public void accept(Throwable throwable) throws Exception {
  98. Log.e(TAG,"{accept}");//可能是授权异常的情况下的处理
  99. }
  100. }, new Action() {
  101. @Override
  102. public void run() throws Exception {
  103. Log.e(TAG,"{run}");//执行顺序——2
  104. }
  105. });
  106. }
  107. }

混淆配置

  1. #=====================百度语音混淆=====================
  2. -keep class com.baidu.speech.**{*;}

参考资料

http://ai.baidu.com/tech/speech

集成指南

项目demo下载地址

https://github.com/haiyuKing/BaiduSpeechDemo

BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)的更多相关文章

  1. BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.8.1)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 上一篇集成的是V3.0.7.3版本的SDK<BaiduSpeechDemo[百度语音SDK集成](基于v3.0.7.3)> ...

  2. iOS百度地图SDK集成详细步骤

    1.iOS百度地图下载地址 http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download 根据需要选择不同的版本  ...

  3. 接入百度语音SDK的步骤

    1.导入依赖库 SystemConfiguration.framework AudioToolbox.framework UIkit.framework AVFoundation.framework ...

  4. AEAI BPM流程集成平台V3.0.2版本开源发布

    本次开源发布的是AEAI BPMV3.0.2版流程平台,该版本是数通畅联首次正式对外发布的版本,产品现已开源并上传至开源社区http://www.oschina.net/p/aeai-bpm. 产品说 ...

  5. iOS开发——百度地图SDK集成

    (正在形成文档,待更新……)

  6. Android Studio集成百度地图SDK

    1.建议先阅读百度地图官方的继承指南,针对了Eclipse和Android Studio. 百度官方集成指南 2.下载百度地图SDK Android SDK v4.1.1 下载有两种: 1.一键下载( ...

  7. Xamarin.Android 集成百度地图SDK

    前言:趁着周六闲得没事干,赶紧搞一搞Xamarin,最近也是怪无聊的,枯燥的生活不如打几行代码带劲:好了我们进入正题 我这篇文章时参考一位大佬的博客进行改变的,当然他写的需要一定的经验才可以看得懂,我 ...

  8. 全志tina v3.0系统编译时的时间错误的解决(全志SDK的维护BUG)

    全志tina v3.0系统编译时的时间错误的解决(全志SDK的维护BUG) 2018/6/13 15:52 版本:V1.0 开发板:SC3817R SDK:tina v3.0 1.01原始编译全志r1 ...

  9. 百度地图SDK for Android【检索服务】

    1搜索服务 百度地图SDK集成搜索服务包括:位置检索.周边检索.范围检索.公交检索.驾乘检索.步行检索,通过初始化MKSearch类,注册搜索结果的监听对象MKSearchListener,实现异步搜 ...

随机推荐

  1. Java 保留两位小数填坑

    下面直接上代码: DecimalFormat df1 = new DecimalFormat("#.00");DecimalFormat df2 = new DecimalForm ...

  2. testng生成自定义html报告

    转自:https://blog.csdn.net/kdslkd/article/details/51198433 testng原生的或reportng的报告总有些不符合需要,尝试生成自定义测试报告,用 ...

  3. 在docker上运行.net core程序

    一.安装docker及镜像 1.在centos上安装docker,命令如下: # yum install docker 2.让docker随机启动: # service docker start# c ...

  4. bzoj 3551 kruskal重构树dfs序上的主席树

    强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...

  5. bzoj 3759 Hungergame 博弈论+线性基

    和nim游戏类似 易证必败状态为:当前打开的箱子中石子异或和为0,没打开的箱子中不存在一个子集满足异或和为0 因为先手无论是取石子还是开箱子,后手都可以通过取石子来使状态变回原状态 所以只需判定是否有 ...

  6. jackson xml转对象 对象转xml

    public static void main(String[] args) throws Exception { XnServiceGetUserRequest xnServiceGetUserRe ...

  7. java 关闭钩子函数的应用

    Runtime.getRuntime().addShutdownHook(shutdownHook); 说明:这个方法的意思就是在jvm中增加一个关闭的钩子,当jvm关闭的时候,会执行系统中已经设置的 ...

  8. React Native开发 - 搭建React Native开发环境

    移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...

  9. 干货,一文带你超详细了解 Filter 的原理及应用

    提出问题 1.我们在访问后台很多页面时都需要登录,只有登录的用户才能查看这些页面,我们需要   在每次请求的时候都检查用户是否登陆,这样做很麻烦,有没有一种方法可以在我们请求之   前就帮我们做这些事 ...

  10. SpringCloud分布式微服务搭建(一)

    本例子主要使用了eureka集群作为注册中心来保证高可用,客户端来做ribbon服务提供者的负载均衡. 负载均衡有两种,第一种是nginx,F5这种集中式的LB,对所有的访问按照某种策略分发. 第二种 ...