**给大家带来一个AIUI动态实体使用的简易教程**
**场景:小明想通过AIUI了解西游记里各位角色都是啥样的,小明对AIUI说`我想听孙悟空的故事`,AIUI马上将孙悟空的大闹天宫播放了出来。**
**请跟着我一步步将这个场景实现。**
**小明想说的话我们把它抽象为一个技能,一个技能可以有多种说法,这里我们列举两种说法,在AIUI开放平台上创建出来。①我想听xxx的故事,②介绍一下xxx。**
#### 1. 创建技能
登录[AIUI开放平台](http://aiui.xfyun.cn),选择我的技能->创建新技能,填写技能名称与语料,但是语料该怎么写呢?我们可以把我想听xxx的故事中的xxx抽象出一个动态实体资源出来,用一个代号来命名它,这里我们命名为`{name}`,于是语料产生了,①我想听{name}的故事,②介绍一下{name}。
![](https://box.kancloud.cn/8818a16bac2b8c335a8431199be782ae_1049x706.png)
**但是当创建完技能后,我们去哪儿找人物名的资源呢。这里我们就需要创建一个动态实体资源啦,来与这个技能关联起来**
#### 2. 创建资源
选择我的技能->我的实体->创建新实体->动态实体,即可创建想要的动态实体资源。如下图所示创建了一个应用级的动态实体资源,里面用来定义西游记角色的名字。
![](https://box.kancloud.cn/24ba26f732adcace3affa6523249f811_1098x255.png)
**创建完资源后需要将技能语料中的语义槽与实体关联起来。**
**技能我们创建好了,但是技能在哪儿使用呢,当然是在应用中啦~ 我们需要在自己的应用中添加上我们自定义的技能。**
#### 3. 创建AIUI应用并关联技能
在[AIUI开放平台](http://aiui.xfyun.cn)创建好应用后,再将第2步创建好的技能添加至应用中。
![](https://box.kancloud.cn/ce40a011feeaeeef1ed7d3babacfac31_1016x291.png)
下载SDK,在本地创建相应工程,开始集成AIUI。具体步骤参考[AIUI Mobile Training](https://www.kancloud.cn/aiui_client/aiui_mobile_userguide/405299)。已集成过AIUI的工程可忽略此步骤。
**AIUI基本的功能可以正常使用后,我们马上就可以使用神奇的动态实体功能啦。首先需要将动态实体数据上传到服务器中。**
#### 4. 上传动态实体资源数据
在aiui_phone.cfg文件里添加上login字段,将你应用的appid填写进去,如下图所示:
![](https://box.kancloud.cn/c6cd0dd7b5b484fe837f9d6eb81d6093_369x346.png)
将需要上传的数据通过AIUIAgent上传至AIUI服务器。这里以Android平台为例,介绍下如何上传动态实体资源数据。
~~~
//待上传的数据
String data ="{\"name\": \"孙悟空\", \"alias\": \"齐天大圣\" }\n" +
"{\"name\": \"唐三藏\", \"alias\": \"唐僧\" }\n" +
"{\"name\": \"猪八戒\", \"alias\": \"天蓬元帅\" }";
//应用级参数json
JSONObject paramJson = new JSONObject();
paramJson.put("appid", 你自己的appid); //这里注意填写上你应用的appid,String型
paramJson.put("id_name", "appid");
paramJson.put("id_value", "");
paramJson.put("res_name", "BLACKSHIP.CharacterName");
//数据json
JSONObject syncSchemaJson = new JSONObject();
syncSchemaJson.put("param", paramJson);
syncSchemaJson.put("data", Base64.encodeToString(data.getBytes(), Base64.DEFAULT | Base64.NO_WRAP));
//上传资源数据
byte[] syncData = syncSchemaJson.toString().getBytes("utf-8");
AIUIMessage syncAthenaMessage = new AIUIMessage(AIUIConstant.CMD_SYNC,AIUIConstant.SYNC_DATA_SCHEMA, 0, "", syncData);
mAIUIAgent.sendMessage(syncAthenaMessage);
~~~
上面为上传应用级动态实体示例,如需上传用户级动态实体,将参数json中`id_name`的值从`appid`改为`uid`即可。
如需上传自定义级别动态实体,将参数json中`id_name`的值改为[AIUI开放平台](http://aiui.xfyun.cn)对应资源的维度名,将`id_value`的值修改为自己想要的值即可。如下图所示后台定义的维度名为`area`。
![](https://box.kancloud.cn/2a521def32a54402996655929a9e378f_875x286.png)
**数据我们是上传上去了,但是数据对不对呢?当然得有个反馈来告诉你,数据传得成功与否,对错与否。我们可以在上传结果回调里看到。**
#### 5. 上传结果回调
动态实体资源上传后,会有`EVENT_CMD_RETURN`事件回调,通知开发者数据是否上传成功。如成功可进行下一步,如不成功需要重新检查上传时是否存在参数错误、或数据格式不正确等,再重新上传。代码示例如下:
~~~
private void processCmdReturnEvent(AIUIEvent event) {
switch (event.arg1) {
case AIUIConstant.CMD_SYNC: {
int dtype = event.data.getInt("sync_dtype");
//arg2表示结果
if (0 == event.arg2) { // 同步成功
if (AIUIConstant.SYNC_DATA_SCHEMA == dtype) {
mSyncSid = event.data.getString("sid");
showTip("schema数据同步成功,sid=" + mSyncSid);
}
} else {
if (AIUIConstant.SYNC_DATA_SCHEMA == dtype) {
mSyncSid = event.data.getString("sid");
showTip("schema数据同步出错:" + event.arg2 + ",sid=" + mSyncSid);
}
}
} break;
}
}
~~~
**如果数据上传成功了,我们就可以进行下一步了,查询我们上传的数据服务器是否打包成功了。**
#### 6. 查询打包状态
数据成功上传至后台后,后台会将数据进行打包处理,这个过程是异步的,需要通过`CMD_QUERY_SYNC_STATUS`查询上传的资源数据是否处理成功。只有当处理成功后,后续才可以正常使用。
arg1表示状态查询的类型,动态实体对应`SYNC_DATA_SCHEMA`(常量对应值为3),params为json,包含需要对应同步上传操作的sid,示例如下:
~~~
JSONObject paramsJson = new JSONObject();
paramsJson.put("sid", mSyncSid);
AIUIMessage querySyncMsg = new AIUIMessage(AIUIConstant.CMD_QUERY_SYNC_STATUS,
AIUIConstant.SYNC_DATA_SCHEMA, 0,
paramsJson.toString(), null);
mAIUIAgent.sendMessage(querySyncMsg);
~~~
`CMD_QUERY_SYNC_STATUS`执行完成后会有`EVENT_CMD_RETURN`事件回调,表示查询结果,解析示例如下:
~~~
private void processCmdReturnEvent(AIUIEvent event) {
switch (event.arg1) {
//schema数据打包结果查询结果
case AIUIConstant.CMD_QUERY_SYNC_STATUS: {
int syncType = event.data.getInt("sync_dtype");
if (AIUIConstant.SYNC_DATA_QUERY == syncType) {
String result = event.data.getString("result");
if (0 == event.arg2) {
showTip("查询结果:" + result);
} else {
showTip("schema数据状态查询出错:" + event.arg2 +
", result:" + result);
}
}
} break;
}
}
~~~
**如果数据处理没成功,我们可以稍微等几秒再查询一次,如果数据处理成功了,我们就可以正常来使用我们刚刚上传上去的数据了,是不是很鸡冻٩(๑>◡<๑)۶**
#### 7. 生效使用
**① 通过`CMD_SET_PARAMS`设置`pers_param`即可使用已设置的动态实体**
生效应用级示例如下:
~~~
JSONObject params = new JSONObject();
JSONObject audioParams = new JSONObject();
audioParams.put("pers_param", "{\"appid\":\"\"}");
params.put("audioparams", audioParams);
AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0 , 0, params.toString(), null);
mAgent.sendMessage(setMsg)
String params = "data_type=audio,sample_rate=16000";
AIUIMessage msg = new AIUIMessage(AIUIConstant.START_RECORD, 0, 0, params, null);
mAIUIAgent.sendMessage(msg);
~~~
**注意: set audioParams这种方式只会对语音交互生效,文本语义不生效,可采用第二种方式**
**② 直接带入params参数中**
~~~
//写入音频
byte[] audio = xxx; //初始化
String params = "data_type=audio,sample_rate=16000,pers_param={\"appid\":\"\"}";
AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, audio);
mAIUIAgent.sendMessage(msg);
~~~
~~~
//文本语义
String params = "data_type=text,pers_param={\"appid\":\"\"}";
AIUIMessage writeMsg = new AIUIMessage( AIUIConstant.CMD_WRITE, 0, 0, params, "介绍一下孙悟空".getBytes());
mAIUIAgent.sendMessage(writeMsg);
~~~
**发送了音频或者文本以后,你会收到你的技能语料以及你想听的是哪个人物的故事了。但是怎么去请求该人物的故事呢,这就要靠广大的开发者根据该人物的名称去请求你们自己的服务将故事下发下来了~~**