■ Android集成百度语音识别

■ Android集成百度语音识别

实现这个功能的目的,是我看见我公司硬件工程师给客户回答问题的时候用公司研发的APP,每次都是手动输入打字,看着他带着老花镜的样子,于心不忍,毕竟咱就是干这个的.

实现效果
在这里插入图片描述

集成 百度语音实时识别
https://ai.baidu.com/sdk#asr
在这里插入图片描述
AndroidManifest.xml 文件

   <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!-- 蓝牙录音使用,不需要可以去除 -->
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        
   <!-- 百度控制台申请的KEY -->
        <meta-data
            android:name="com.baidu.speech.APP_ID"
            android:value="22611822"/>

        <meta-data
            android:name="com.baidu.speech.API_KEY"
            android:value="YoR10GzzuZ58FYLpQ1utD5vy"/>
        <meta-data
            android:name="com.baidu.speech.SECRET_KEY"
            android:value="gGQvipUXC0dSSGmAQNMeHCMKTW4fGGrH"/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

build.gradle

    packagingOptions{
   
        doNotStrip "*/*/libvad.dnn.so"
        doNotStrip "*/*/libbd_easr_s1_merge_normal_20151216.dat.so"
    }

集成jar包

dependencies {
   
//...省略
 implementation files('libs\\bdasr_V3_20191210_81acdf5.jar')
}

在这里插入图片描述
到这里基本就可以集成了百度语音实时识别,但是这里有个坑.就是语音申请的时候得领取配额
在这里插入图片描述
一定要领取配额,不然一顿 4004,一开始我以为是集成错误导致了,包名检查了N次…

使用方法
这里我直接附上我写的代码了


protected TextView txtResult;
private EventManager asr;
protected boolean enableOffline = false; // 测试Unit 2.0 功能,必须一直联网
private EditText etText;
private LinearLayout llView;
private CustomPopWindow mCustomPopWindowCause;
private TextView tvContent;
private TextView tvState;
private LinearLayout llClick;
/** * 基于SDK集成2.2 发送开始事件 * 点击开始按钮 * 测试参数填在这里 */
@SuppressLint("HandlerLeak")
private void start() {

Map<String, Object> params = new LinkedHashMap<String, Object>();
String event = null;
event = SpeechConstant.ASR_START; // 替换成测试的event
if (enableOffline) {

params.put(SpeechConstant.DECODER, 2);
}
// 基于SDK集成2.1 设置识别参数
params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);
params.put(SpeechConstant.PID, 15374); // 或 19364 Unit 2.0 固定pid,仅支持中文普通话
params.put(SpeechConstant.NLU, "enable");
params.put(SpeechConstant.VAD_ENDPOINT_TIMEOUT, 0); // 长语音
String json = null; // 可以替换成自己的json
json = new JSONObject(params).toString(); // 这里可以替换成你需要测试的json
asr.send(event, json, null, 0, 0);
Log.e("X000", json + "");
}
/** * 点击停止按钮 * 基于SDK集成4.1 发送停止事件 */
private void stop() {

asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0); //
}
/** * enableOffline设为true时,在onCreate中调用 * 基于SDK离线命令词1.4 加载离线资源(离线时使用) */
private void loadOfflineEngine() {

Map<String, Object> params = new LinkedHashMap<String, Object>();
params.put(SpeechConstant.DECODER, 2);
params.put(SpeechConstant.ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH, "assets://baidu_speech_grammar.bsg");
asr.send(SpeechConstant.ASR_KWS_LOAD_ENGINE, new JSONObject(params).toString(), null, 0, 0);
}
/** * enableOffline为true时,在onDestory中调用,与loadOfflineEngine对应 * 基于SDK集成5.1 卸载离线资源步骤(离线时使用) */
private void unloadOfflineEngine() {

asr.send(SpeechConstant.ASR_KWS_UNLOAD_ENGINE, null, null, 0, 0); //
}
@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.common_mini);
EventBus.getDefault().register(this);
initView();
initPermission();
// 基于sdk集成1.1 初始化EventManager对象
asr = EventManagerFactory.create(this, "asr");
// 基于sdk集成1.3 注册自己的输出事件类
asr.registerListener(this); // EventListener 中 onEvent方法
if (enableOffline) {

loadOfflineEngine(); // 测试离线命令词请开启, 测试 ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH 参数时开启
}
}
// 基于sdk集成1.2 自定义输出事件类 EventListener 回调方法
// 基于SDK集成3.1 开始回调事件
@Override
public void onEvent(String name, String params, byte[] data, int offset, int length) {

if (params != null && !params.isEmpty()) {

try {

JSONObject object = new JSONObject(params);
JSONArray jsonArray = object.getJSONArray("results_recognition");
StringBuffer str = new StringBuffer();
if (jsonArray != null || jsonArray.length() != 0) {

for (int i = 0; i < jsonArray.length(); i++) {

String msg = jsonArray.getString(i);
str.append(msg + " ");
}
tvContent.setText(str.toString());
}
} catch (JSONException e) {

e.printStackTrace();
}
}
}
private void initView() {

txtResult = (TextView) findViewById(R.id.txtResult);
etText = findViewById(R.id.et_text);
llView = findViewById(R.id.ll_layout);
findViewById(R.id.btn_x).setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {

ShowVoice();
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void ConsultEvent(XYTextEvent item) {

String context = item.getContext();
String trim = etText.getText().toString().trim();
if (!trim.isEmpty()) {

etText.setText(trim + context);
} else {

etText.setText(context);
}
}
/** * 展示语音 */
@SuppressLint("ClickableViewAccessibility")
private void ShowVoice() {

final View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_windows, null);
mCustomPopWindowCause = new CustomPopWindow.PopupWindowBuilder(MainActivity.this)
.setView(contentView)
.enableBackgroundDark(true) //弹出popWindow时,背景是否变暗
.setBgDarkAlpha(0.6f) // 控制亮度
.enableOutsideTouchableDissmiss(true)
.create();
mCustomPopWindowCause.showAtLocation(llView, Gravity.FILL, 0, 0);
tvContent = contentView.findViewById(R.id.tv_content);
tvState = contentView.findViewById(R.id.tv_state);
llClick = contentView.findViewById(R.id.ll_click);
//触摸手势事件
llClick.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
tvState.setText("正在说...~");
llClick.setBackgroundResource(R.drawable.ra_bg);
start();
break;
case MotionEvent.ACTION_UP:
tvState.setText("按住说话~");
llClick.setBackgroundResource(R.drawable.re_bg);
stop();
EventBus.getDefault().post(new XYTextEvent(tvContent.getText().toString()));
mCustomPopWindowCause.dissmiss();
// etText.setText(tvContent.getText().toString());
break;
}
return true;
}
});
}
/** * 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<String> toApplyList = new ArrayList<String>();
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);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

// 此处为android 6.0以上动态授权的回调,用户自行实现。
}
@Override
protected void onPause() {

super.onPause();
asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0);
}
@Override
protected void onDestroy() {

super.onDestroy();
// 基于SDK集成4.2 发送取消事件
asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0);
if (enableOffline) {

unloadOfflineEngine(); // 测试离线命令词请开启, 测试 ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH 参数时开启
}
// 基于SDK集成5.2 退出事件管理器
// 必须与registerListener成对出现,否则可能造成内存泄露
asr.unregisterListener(this);
if (EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this);
}

附带三方库

    implementation 'com.github.pinguo-zhouwei:CustomPopwindow:2.1.1'
implementation 'org.greenrobot:eventbus:3.1.1'

后记 :功能实现了,老工程师很开心.他跟我说他之所以打字,是因为他在给客户回答问题的时候得思索一下…
至于语音输入功能,他说现在的输入法都有这个功能了.要不你打字的时候,试一下长按空格键…-_-||

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/2816.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)
blank

相关推荐

  • 优先队列(堆)priority queue

    优先队列(堆)priority queue优先队列(堆)priorityqueue完全二叉树:除了最底层都被元素填满堆序性:除根节点,最小堆每个节点父亲的Key小于等于该节点的Key,最大堆反之优先队列的申明structHeapStruct;typedefstructHeapStruct*PriorityQueue;PriorityQueueInitialize(intMaxElements);void…

  • ThinkPHP 小于5.0.24 远程代码执行高危漏洞 修复方案

    ThinkPHP 小于5.0.24 远程代码执行高危漏洞 修复方案

  • 【《重构 改善既有代码的设计》学习笔记2】重构原则

    【《重构 改善既有代码的设计》学习笔记2】重构原则本篇文章的内容来自《重构 改善既有代码的设计》一书学习笔记整理并且加上自己的浅显的思考总结!上一篇通过一个简单的例子体验了一把重构过程,现在我们需要回过头看一下重构的一些背景、原理和理论。 并思考一下重构的关键原则是什么,以及重构时需要考虑哪一些问题?一、什么是重构1、 重构的定义“重构” 这个词有两种不同的定义!名称形式重…

  • rpm 安装 忽略依赖_rpm卸载软件忽略循环依赖

    rpm 安装 忽略依赖_rpm卸载软件忽略循环依赖今天由于某些原因需要卸载掉服务器上的php软件,然后我使用下面命令显示出本机安装的所有和php相关的软件,如下:iteblog$rpm-qa|grepphpphp-mysqlnd-5.6.25-0.1.RC1.el6.remi.x86_64php-fpm-5.6.25-0.1.RC1.el6.remi.x86_64php-pecl-jsonc-1.3.10-1.el6.remi.5.6…

  • k8s–证书签发

    k8s–证书签发1.准备签发证书环境运维主机hdss-1-200.host.com上:2.安装CFSSL证书签发工具CFSSL:R1.2cfssl下载地址https://pkg.cfssl.org/R1.2/cfssl_linux-amd64cfssl-json下载地址https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64cfssl-certinfo下载地址https://pkg.cfssl.org/R1.2/cfssl-certinfo_li…

  • 清单程序员修身

    清单程序员修身

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号