第一步前去科大讯飞开放平台注册后,下载图中SDK
因为选择语音唤醒,下载之前你要设置唤醒词
设置完之后下载后的文件是这样的
他们具体的含义不用多说,如果你要重新做一个demo出来,只识别语音唤醒功能,那么接下来就是步骤,在下一篇博客中我会写一个语音识别,以及下下篇是唤醒和语音识别集合。
第二步新建一个andorid 工程
2.1 首先把上面目录中的libs里面的文件全部放到andorid studio中的libs中去,因为这是添加库的,需要添加依赖,不然这个库无法使用,有的右击根本没有buid path,我的做法是在build.gradle中的依赖加上
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
2.2 在main的下一级建一个assets目录,然后把之前文件夹的assets放进去
2.3 在main的下一级新建一个jniLibs目录,然后把arm64-v8a,armeabi-v7a放进去,虽然这个和libs里面可能重复了,但是如果不放进去,就会造成之后的唤醒未初始化
2.4 权限在androidMainfest.xml添加
<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />
第三步代码方面
MainActivity测试类代码
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
public class MainActivity extends AppCompatActivity {
private TextView mTvLog;
private WakeUpUtil wakeUpUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=" +getString(R.string.app_id));
mTvLog = (TextView) findViewById(R.id.tv_log);
mTvLog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 开启唤醒
wakeUpUtil.wake();
}
});
wakeUpUtil = new WakeUpUtil(this) {
@Override
public void wakeUp() {
Toast.makeText(MainActivity.this, "唤醒成功", Toast.LENGTH_SHORT).show();
// 开启唤醒
// wakeUpUtil.wake();
}
};
}
}
唤醒工具类代码
package com.example.myapplication;
import org.json.JSONException;
import org.json.JSONObject;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
/**
* Created by Administrator on 2018/2/28.
* 讯飞语音唤醒
*/
public abstract class WakeUpUtil {
/**
* 唤醒的回调
*/
public abstract void wakeUp();
// Log标签
private static final String TAG = "WakeUpUtil";
// 上下文
private Context mContext;
// 语音唤醒对象
private VoiceWakeuper mIvw;
private int curThresh = 1450;
public WakeUpUtil(Context context) {
mContext = context;
// 初始化唤醒对象
mIvw = VoiceWakeuper.createWakeuper(context, null);
}
/**
* 获取唤醒词功能
*
* @return 返回文件位置
*/
private String getResource() {
//通过这个找到我们之前在平台上记录的关键词
final String resPath = ResourceUtil.generateResourcePath(mContext,RESOURCE_TYPE.assets, "ivw/" + mContext.getString(R.string.app_id) + ".jet");
Log.d(TAG, resPath);
return resPath;
}
/**
* 唤醒
*/
public void wake() {
// 非空判断,防止因空指针使程序崩溃
mIvw = VoiceWakeuper.getWakeuper();
Log.d(TAG, mIvw+"");
if (mIvw != null) {
// textView.setText(resultString);
// 清空参数
mIvw.setParameter(SpeechConstant.PARAMS, null);
// 设置唤醒资源路径
mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
// 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
// 设置唤醒模式
mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
mIvw.setParameter(SpeechConstant.IVW_SST, "oneshot");
// 设置持续进行唤醒
mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
mIvw.startListening(mWakeuperListener);
} else {
Toast.makeText(mContext, "唤醒未初始化", Toast.LENGTH_SHORT).show();
}
}
public void stopWake() {
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
mIvw.stopListening();
} else {
Toast.makeText(mContext, "唤醒未初始化", Toast.LENGTH_SHORT).show();
}
}
String resultString = "";
private WakeuperListener mWakeuperListener = new WakeuperListener() {
@Override
public void onResult(WakeuperResult result) {
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"));
buffer.append("\n");
buffer.append("【关键词】" + object.optString("keyword"));
resultString = buffer.toString();
Log.d(TAG, resultString);
stopWake();
wakeUp();
} catch (JSONException e) {
resultString = "结果解析出错";
e.printStackTrace();
}
}
@Override
public void onError(SpeechError error) {
Log.i(TAG, error.getPlainDescription(true));
}
@Override
public void onBeginOfSpeech() {
Log.i(TAG, "开始说话");
}
@Override
public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
}
@Override
public void onVolumeChanged(int i) {
}
};
}
MainActivity的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF000000"
android:gravity="center"
android:padding="10dp"
android:text="唤醒词:慧明慧明"
android:textColor="#FFFFFFFF"
android:textSize="20dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#FFFFFFFF" />
<TextView
android:id="@+id/tv_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF000000"
android:gravity="center"
android:padding="10dp"
android:text="点击开始唤醒"
android:textColor="#FFFFFFFF"
android:textSize="10dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#FFFFFFFF" />
</LinearLayout>
然后因为我的id我把它放到valus里面的Strings.xml中去了,实际上我们下载文件的时候是平台已经帮我们这些东西都已经放到这里面去了
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">讯飞语音示例v5+</string>
<!-- 请替换成在语音云官网申请的appid -->
<string name="app_id">5de9a6f7</string>
<string name="example_explain">本示例为讯飞语音Android平台开发者提供语音听写、语法识别、语义理解和语音合成等代码样例,旨在让用户能够依据该示例快速开发出基于语音接口的应用程序。</string>
<string name="text_tts_source">
科大讯飞作为中国最大的智能语音技术提供商,在智能语音技术领域有着长期的研究积累,并在中文语音合成、语音识别、口语评测等多项技术上拥有国际领先的成果。科大讯飞是我国唯一以语音技术为产业化方向的“国家863计划成果产业化基地”…
</string>
<string name="text_tts_source_en">iFLYTEK is a national key software enterprise dedicated to the research of intelligent speech and language technologies, development of software and chip products, provision of speech information services, and integration of E-government systems. The intelligent speech technology of iFLYTEK, the core technology of the company, represents the top level in the world.
</string>
<string name="text_isr_abnf_hint">\t上传内容为:\n\t#ABNF 1.0 gb2312;\n\tlanguage zh-CN;\n\tmode voice;\n\troot $main;\n\t$main = $place1 到$place2 ;\n\t$place1 = 北京 | 武汉 | 南京 | 天津 | 东京;\n\t$place2 = 上海 | 合肥;</string>
<string name="text_understand_hint">\t您可以说:\n\t今天的天气怎么样?\n\t北京到上海的火车?\n\t来首歌吧?\n\n\t更多语义请登录:\n\thttp://aiui.xfyun.cn/ \n\t配置您的专属语义吧!</string>
<!-- 听写 -->
<string name="text_begin">请开始说话…</string>
<string name="text_begin_recognizer">开始音频流识别</string>
<string name="text_upload_contacts">上传联系人</string>
<string name="text_upload_userwords">上传用户词表</string>
<string name="text_upload_success">上传成功</string>
<string name="text_userword_empty">词表下载失败或内容为空</string>
<string name="text_download_success">下载成功</string>
<string name="pref_key_iat_show">iat_show</string>
<string name="pref_title_iat_show">显示听写界面</string>
<string name="pref_key_translate">translate</string>
<string name="pref_title_translate">翻译</string>
<!-- 合成 -->
<string-array name="voicer_cloud_entries">
<item>小燕</item>
<item>小宇</item>
<item>凯瑟琳</item>
<item>亨利</item>
<item>玛丽</item>
<item>小研</item>
<item>小琪</item>
<item>小峰</item>
<item>小梅</item>
<item>小莉</item>
<item>小蓉</item>
<item>小芸</item>
<item>小坤</item>
<item>小强 </item>
<item>小莹</item>
<item>小新</item>
<item>楠楠</item>
<item>老孙</item>
</string-array>
<string-array name="voicer_cloud_values">
<item>xiaoyan</item>
<item>xiaoyu</item>
<item>catherine</item>
<item>henry</item>
<item>vimary</item>
<item>vixy</item>
<item>xiaoqi</item>
<item>vixf</item>
<item>xiaomei</item>
<item>xiaolin</item>
<item>xiaorong</item>
<item>xiaoqian</item>
<item>xiaokun</item>
<item>xiaoqiang</item>
<item>vixying</item>
<item>xiaoxin</item>
<item>nannan</item>
<item>vils</item>
</string-array>
<string-array name="voicer_xtts_entries">
<item>小燕</item>
<item>小峰</item>
</string-array>
<string-array name="voicer_xtts_values">
<item>xiaoyan</item>
<item>xiaofeng</item>
</string-array>
<string-array name="voicer_local_entries">
<item>小燕</item>
<item>小峰</item>
</string-array>
<string-array name="voicer_local_values">
<item>xiaoyan</item>
<item>xiaofeng</item>
</string-array>
<string-array name="stream_entries">
<item>通话</item>
<item>系统</item>
<item>铃声</item>
<item>音乐</item>
<item>闹铃</item>
<item>通知</item>
</string-array>
<string-array name="stream_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
<string
name="tts_toast_format"
formatted="false">缓冲进度为%d%%,播放进度为%d%%</string>
<!-- 语言 -->
<string-array name="language_entries">
<item>普通话</item>
<item>粤语</item>
<item>英语</item>
</string-array>
<string-array name="language_values">
<item>mandarin</item>
<item>cantonese</item>
<item>en_us</item>
</string-array>
<!-- 标点符号 -->
<string-array name="punc_entries">
<item>有标点</item>
<item>无标点</item>
</string-array>
<string-array name="punc_values">
<item>1</item>
<item>0</item>
</string-array>
<!-- 唤醒 -->
<string name="example_explain_wake">唤醒是指通过说出特定的唤醒词来唤醒处于休眠状态下的设备,又分为唤醒和唤醒+识别。</string>
<string name="wake_demo_hint">请点击“开始唤醒”后读出您在开放平台购买的唤醒词,当引擎计算得分大于您设置的门限值时,即可进行唤醒。</string>
<string name="oneshot_demo_hint">请点击“唤醒+识别”后读出您在开放平台购买的唤醒词+语法中指定的识别对象,当引擎计算得分大于您设置的门限值时,即可进行唤醒+识别。</string>
<string name="oneshot_resource_hint">本示例识别词语为“张三|李四|张海洋”,请开发者将语法文件中的唤醒词字段替换,本地语法定义详见demo工程的asset/wake.bnf文件。</string>
</resources>
最后运行的时候,因为权限他不会提示你去开启,你需要找到它,然后开启所有权限即可
最后的代码在GIthub