ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 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; } } }; ~~~