# 1. 下载SDK
* * * * *
在[AIUI开放平台](http://aiui.xfyun.cn)创建完应用后,即可下载对应的SDK包。SDK包里包含MSC与AIUI库,本文档仅介绍Android版AIUI库的入门使用,如需了解MSC库,请访问[MSC开发指南](http://doc.xfyun.cn/msc_android/299547)。
# 2. 导入SDK
* * * * *
将下载的Android SDK压缩包中libs目录下的libaiui.so以及AIUI.jar拷贝至Android工程的libs目录下,并将SDK包中assets目录下cfg文件夹以及res目录下vad文件夹拷贝至工程中。工程结构如下图所示:
:-: ![](https://box.kancloud.cn/c67806950747ea9abb8ac77241e44794_330x592.png)
将AIUI.jar添加至工程依赖,将app module下的gradle配置文件中指定默认jniLibs目录为libs。
~~~
android {
...
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
...
}
~~~
# 3. 添加用户权限
* * * * *
在工程AndroidManifest.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"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
~~~
注意:如需在打包或者生成APK的时候进行混淆,请在proguard.cfg中添加如下代码:
~~~
-keep class com.iflytek.**{*;}
-keepattributes Signature
~~~
# 4. 修改配置
修改cfg/aiui_phone.cfg中的appid信息,将里面的"XXXXXXXX"替换为您自己应用的appid即可。若您下载下来的SDK包已经自动将appid信息打包在cfg文件中了,则可忽略此步骤。
# 5. 创建AIUIAgent
* * * * *
SDK中提供的AIUIAgent就是和AIUI交互的桥梁。先创建`AIUIAgent`,再发送`CMD_START`消息,使AIUI处于工作状态,示例如下:
~~~
//创建AIUIAgent
AIUIAgent mAIUIAgent = AIUIAgent.createAgent(context,getAIUIParams(),mAIUIListener);
//发送`CMD_START`消息,使AIUI处于工作状态
AIUIMessage startMsg = new AIUIMessage(AIUIConstant.CMD_START, 0, 0, null, null);
mAIUIAgent.sendMessage( startMsg );
~~~
createAgent 方法包含三个参数:
①第一个参数类型为Context;
②第二个参数类型为String,具体值是通过读取assets目录下的cfg/aiui_phone_user.cfg文件而获得的字符串;
③第三个参数类型为AIUIListener,是AIUI事件回调监听器。
getAIUIParams()具体示例如下所示:
~~~
private String getAIUIParams() {
String params = "";
AssetManager assetManager = getResources().getAssets();
try {
InputStream ins = assetManager.open( "cfg/aiui_phone.cfg" );
byte[] buffer = new byte[ins.available()];
ins.read(buffer);
ins.close();
params = new String(buffer);
} catch (IOException e) {
e.printStackTrace();
}
return params;
}
}
~~~
mAIUIListener具体示例如下所示:
~~~
AIUIListener mAIUIListener = new AIUIListener() {
@Override
public void onEvent(AIUIEvent event) {
switch (event.eventType) {
//唤醒事件
case AIUIConstant.EVENT_WAKEUP:
{
break;
}
//结果事件(包含听写,语义,离线语法结果)
case AIUIConstant.EVENT_RESULT:
{
break;
}
//休眠事件
case AIUIConstant.EVENT_SLEEP:
{
break;
}
// 状态事件
case AIUIConstant.EVENT_STATE: {
mAIUIState = event.arg1;
if (AIUIConstant.STATE_IDLE == mAIUIState) {
// 闲置状态,AIUI未开启
} else if (AIUIConstant.STATE_READY == mAIUIState) {
// AIUI已就绪,等待唤醒
} else if (AIUIConstant.STATE_WORKING == mAIUIState) {
// AIUI工作中,可进行交互
}
} break;
//错误事件
case AIUIConstant.EVENT_ERROR:
{
break;
}
}
}
~~~
# 6. 文本语义理解示例
* * * * *
发送CMD_WAKEUP消息至AIUI,使AIUI处于唤醒状态,再通过构造`CMD_WRITE`消息,将要进行语义理解的文本数据发送给AIUI,并通过AIUIListener的回调,获取语义结果。代码示例如下:
~~~
// 先发送唤醒消息,改变AIUI内部状态,只有唤醒状态才能接收语音输入
if( AIUIConstant.STATE_WORKING != mAIUIState ){
AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
mAIUIAgent.sendMessage(wakeupMsg);
}
AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, "data_type=text", "今天天气怎么样".getBytes());
mAIUIAgent.sendMessage(msg);
~~~
其中mAIUIState代表当前AIUI状态,当AIUI状态改变时,会在mAIUIListener中抛出EVENT_STATE事件,可通过其获取AIUI状态。
# 7. 语音语义理解示例
* * * * *
发送CMD_WAKEUP消息至AIUI,使AIUI处于唤醒状态,再发送开始录音消息,使麦克风录入音频,并通过AIUIListener的回调,获取语义结果。代码示例如下:
~~~
// 先发送唤醒消息,改变AIUI内部状态,只有唤醒状态才能接收语音输入
if( AIUIConstant.STATE_WORKING != mAIUIState ){
AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
mAIUIAgent.sendMessage(wakeupMsg);
}
// 打开AIUI内部录音机,开始录音
String params = "sample_rate=16000,data_type=audio";
AIUIMessage writeMsg = new AIUIMessage( AIUIConstant.CMD_START_RECORD, 0, 0, params, null );
mAIUIAgent.sendMessage(writeMsg);
~~~
如出现20006错误,请注意下应用是否拥有录音权限。返回的语义结果,参考[语义结果说明文档](http://aiui.xfyun.cn/help/devDoc#4)
# 8. 结果解析
* * * * *
在AIUIEventListener回调中,可以收到来自AIUI的多种消息,具体示例如下:
~~~
private AIUIListener mAIUIListener = new AIUIListener() {
@Override
public void onEvent(AIUIEvent event) {
switch (event.eventType) {
case AIUIConstant.EVENT_WAKEUP:
//唤醒事件
Log.i( TAG, "on event: "+ event.eventType );
break;
case AIUIConstant.EVENT_RESULT: {
//结果解析事件
try {
JSONObject bizParamJson = new JSONObject(event.info);
JSONObject data = bizParamJson.getJSONArray("data").getJSONObject(0);
JSONObject params = data.getJSONObject("params");
JSONObject content = data.getJSONArray("content").getJSONObject(0);
if (content.has("cnt_id")) {
String cnt_id = content.getString("cnt_id");
JSONObject cntJson = new JSONObject(new String(event.data.getByteArray(cnt_id), "utf-8"));
String sub = params.optString("sub");
if ("nlp".equals(sub)) {
// 解析得到语义结果
String resultStr = cntJson.optString("intent");
Log.i( TAG, resultStr );
}
}
} catch (Throwable e) {
e.printStackTrace();
}
} break;
case AIUIConstant.EVENT_ERROR: {
//错误事件
Log.i( TAG, "on event: "+ event.eventType );
Log.e(TAG, "错误: "+event.arg1+"\n"+event.info );
} break;
case AIUIConstant.EVENT_VAD: {
if (AIUIConstant.VAD_BOS == event.arg1) {
//语音前端点
} else if (AIUIConstant.VAD_EOS == event.arg1) {
//语音后端点
}
} break;
case AIUIConstant.EVENT_START_RECORD: {
Log.i( TAG, "on event: "+ event.eventType );
//开始录音
} break;
case AIUIConstant.EVENT_STOP_RECORD: {
Log.i( TAG, "on event: "+ event.eventType );
// 停止录音
} break;
case AIUIConstant.EVENT_STATE: { // 状态事件
mAIUIState = event.arg1;
if (AIUIConstant.STATE_IDLE == mAIUIState) {
// 闲置状态,AIUI未开启
} else if (AIUIConstant.STATE_READY == mAIUIState) {
// AIUI已就绪,等待唤醒
} else if (AIUIConstant.STATE_WORKING == mAIUIState) {
// AIUI工作中,可进行交互
}
} break;
default:
break;
}
}
};
~~~