准备
申请 appid 什么的就不说了。下载 SDK 一定要注意,下载的 SDK 与创建的应用一定要对的上,选择完模块和平台后,在最后的应用选择的时候需要注意选择想要的 appid ,下载后的 SDK 的 zip 文件最后也有 appid 。
下载完成后,将解压文件 lib 目录下的 Msc.jar 拷贝到 Android Studio 的 Project 视图下的 app/libs 目录下,如果目录不存在就新建一个。
将解压文件 lib 下的 armeabi 或者对应平台的文件夹拷贝到 Android Studio 的 Project 视图下的 app/src/main/jniLibs 路径下,如果不存在就自己创建。
将解压文件中的 assets 文件夹拷贝到 Android Studio 的 Project 视图下的 app/src/main 路径下,这些文件是讯飞默认的交互动画资源文件,不过这大概是好几年前的东西,风格整体没那么时尚。
配置
重写自己的 Application 类:1
2
3
4
5
6
7
8
9public class App extends Application {
public void onCreate() {
super.onCreate();
//科大讯飞语音听写初始化
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=" + getString(R.string.iflytek_app_id));
//这里最好不要使用讯飞的标记强制在子线程中初始化,容易导致 用户校验失败 错误
}
}
修改 AndroidManifest.xml 文件:
添加权限:1
2
3
4
5
6
7
8
9
10
11
12
13
14<!--连接网络权限,用于执行云端语音能力 -->
<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"/>
使用自己新建的 Application :1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<application
android:name=".app.App"
android:allowBackup="true"
android:icon="@mipmap/done365"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
开始听写
1 | private void startSpeech() { |
结果演示:
当然现在由于返回的数据还是 json ,没有进行解析,所以看起来非常乱。
返回的 json 的数据:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62{
"sn": 1, //第几句
"ls": false, //是否最后一句
"bg": 0, //开始
"ed": 0, //结束
"ws": [ //词
{
"bg": 0,
"cw": [ //中文分词
{
"sc": 0.00, //分数
"w": "这" //单字
}
]
},
{
"bg": 0,
"cw": [
{
"sc": 0.00,
"w": "是"
}
]
},
{
"bg": 0,
"cw": [
{
"sc": 0.00,
"w": "一"
}
]
},
{
"bg": 0,
"cw": [
{
"sc": 0.00,
"w": "条"
}
]
},
{
"bg": 0,
"cw": [
{
"sc": 0.00,
"w": "测试"
}
]
},
{
"bg": 0,
"cw": [
{
"sc": 0.00,
"w": "信息"
}
]
}
]
}
可以看出来讯飞基本上把所有的字跟词都分割开了。
结果解析
编写一个解析 json 数据的工具类 SpeechResultParse.java :1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class SpeechResultParser {
public static String parseIatResult(String json) {
StringBuffer buffer = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject jResult = new JSONObject(tokener);
JSONArray words = jResult.getJSONArray("ws");//得到 ws ,也就是所有词的集合
for (int i=0;i<words.length();i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");//每个词的中文分词
JSONObject obj = items.getJSONObject(0);
buffer.append(obj.getString("w"));//具体的中文汉字
}
} catch (JSONException e) {
e.printStackTrace();
}
return buffer.toString();
}
}
然后修改下前台代码:1
2
3
4
5
6
7
8
9
10
11
12
13private RecognizerDialogListener dialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult recognizerResult, boolean b) {
Toast.makeText(getActivity(),
SpeechResultParser.parseIatResult(recognizerResult.getResultString()),
Toast.LENGTH_SHORT).show();
}
public void onError(SpeechError speechError) {
}
};
结果就出来了:
但是可以看出 Toast 打印了两次,第二次是空白的没有内容,所以最好将第二次的内容屏蔽掉,再修改下上面监听器的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private RecognizerDialogListener dialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult recognizerResult, boolean b) {
if (!b) {//只需要第一次识别出的字符串,后续会输出空白
Toast.makeText(getActivity(),
SpeechResultParser.parseIatResult(recognizerResult.getResultString()),
Toast.LENGTH_SHORT).show();
}
}
public void onError(SpeechError speechError) {
}
};
再来看一下:
基本的语音听写就这些了,其实还是很容易的,得感谢科大讯飞为广大开发者提供如此便利的开放接口,让语音识别变得不再遥远和艰难。