技能-客户端FAQ
1 DUI-DEV客户端
1.1 DUI-DEV扫码更新后频繁崩溃?
这个问题一般是解决方案内的语音内核和DUI-DEV比较旧,需要更新; 可以查看APP的版本以及产品语音内核的版本,目前最新的内核版本为1.2.6.1,建议更新到最新。 最新DUI-DEV地址: http://aispeech-dui.oss-cn-shanghai.aliyuncs.com/production/dds/android/V1.2.6.1/dds-demo.apk 如果解决方案的DUI-DEV不方便更新,并且内核已经是最新的,可以使用上面链接的DUI-DEV,版本更新后修改对应版本号链接仍然有效。 |
1.2 DUI-DEV卡在初始化界面启动不了?
检查手机上有没有其他DDS相关的应用在运行,如果有就杀掉,再重启DUI-DEV。 |
1.3 DUI-DEV唤不醒,识别不了?
1.检查APP有没有录音权限。 2.重启手机(可能是偶现的系统录音机异常) |
1.4 DUI-DEV不显示对话记录,只能听见声音?
检查产品配置页的UI样式,需要选择默认样式; 如果已经选了默认样式仍然不显示,检查解决方案内的UI样式资源是否正常,尝试重新上传。 |
1.5 DUI-DEV TTS没有声音?
1.DUI-DEV TTS默认使用的闹钟的通道,调高一下闹钟的音量试试。 2.参考1.1,可能是内核版本与SDK版本不兼容导致,尽量保证一致。 |
1.6 DUI-DEV一直显示授权失败?
1.检查产品内的设备授权个数是否达到上限。 2.如果是test或者dev环境的产品,需要客户端设备连到公司内网才可以请求。 |
2 技能内开发客户端相关问题
2.1 什么时候使用command?什么时候使用nativeApi?
需要回传数据给技能的使用native API,直接下发指令给客户端用command
2.2 技能内如何使用CInfo功能?
cinfo是设备级的存储服务,用来保存联系人、定位信息等数据。
1.首先需要客户端使用SDK接口上传数据到CInfo
Android见https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.18部分
IOS见https://www.duiopen.com/docs/ct_IOSdetail 1.12部分
2.技能内通过$context.system.settings.xxx$(cinfoV2)或$context.xxx$(cinfoV1)来引用
2.3 技能内如何引用客户端nativeApi返回的数据?
客户端nativeApi返回的数据依据协议 https://www.duiopen.com/docs/ct_UI
协议提前定义好的可以直接引用,如$text$引用文本控件的内容,$count$引用列表控件的数目
需要注意:除非是共有的参数,否则引用前必须确定当前控件是否有对应的参数,比如:文本控件条件里不能直接引用$count$,否则dm就会报错;
协议未定义的、额外的参数需要加extra引用,如$extra.name$,$extra.city$等,具体引用的格式需要和客户端进行确认。
需要注意:在条件内引用客户端回传参数时必须对参数进行存在判断,否则条件不会命中,且可能直接播报出$extra.xxx$
2.4 词库相关问题?
参考hotword 常见问题汇总的错误原因
2.5 说法在产品页测试和客户端测试结果不一样?
检查客户端产品版本是否和产品页版本一致。 如果确定客户端产品版本与测试页版本一致,且结果还是不一致,需要服务端排查。 |
2.6 先执行command还是先播报回复?
如果这个command需要等回复语播报完成之后再执行,就选择先播报回复语,再执行command; 反之就选择先执行command,再播报回复语。 举个例子: 有个command是播放音乐, 如果是nlgFirst,那么流程是“好的,即将播放”->客户端开始播放; 如果是commandFirst,那么流程是客户端已经开始播放了->nlg也同时播,会出现音乐和nlg一起播 |
2.7 产品页的错误配置客户端能否修改?
错误播报内容客户端都可以自己配;但是重试次数客户端不能修改。 参考https://www.duiopen.com/docs/ct_common_Andriod_SDK 4.3部分 DDSConfig.K_CUSTOM_TIPS |
2.8 command和nativeApi的传参客户端如何获取?
//command
DDS.getInstance().getAgent().subscribe("DUI.MediaController.SetVolume", new CommandObserver() {
@Override
public void onCall(String command, String data) {
if(command.equals("DUI.MediaController.SetVolume")){
try {
JSONObject object = new JSONObject(data);
String volume = object.optString("volume");//获取command下发的参数
Log.d(TAG, "volume: "+volume);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
//nativeApi
DDS.getInstance().getAgent().subscribe("DUI.System.GetInfo", new NativeApiObserver() {
@Override
public void onQuery(String nativeApi, String data) {
if(nativeApi.equals("DUI.System.GetInfo")){
try {
JSONObject object = new JSONObject(data);
String tgt = object.optString("tgt");//获取nativeApi下发的参数
if(tgt.equals("当前电量")){
String power = DeviceUtils.getBatteryLevel() + "%";
TextWidget textWidget = new TextWidget();
textWidget.addExtra("errId", "0");//nativeApi回传的参数
textWidget.addExtra("power", power);//nativeApi回传的参数
DDS.getInstance().getAgent().feedbackNativeApiResult(nativeApi,textWidget);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
|
2.9 nativeApi回传的数据如何通过recordId查询?
1.通过recordId在大数据平台查找对应的json日志 2.找到recordId对应的sessionId 3.以sessionId为查询条件重新查找 4.在新的查询结果内找最新一条数据 5.nativeApi回传数据的位置为dm-message-input-widget ps:如果没有的话,可能是客户端没有回传 |
2.10 nativeApi回传的数据格式及示例代码
### 文本控件的nativeApi客户端返回示例 JSON格式
```json
{
"type":"text",
"name":"default",
"extra": {
"errId":"78208",//技能内引用这个参数的方式为 $extra.errId$
"xxx":"xxx" //技能内引用这个参数的方式为 $extra.xxx$
}
}
```
### 列表控件的nativeApi客户端返回示例 JSON格式
```json
{
"type" : "list",
"name":"default",
"intentName":"导航",
"content": [{
"title": "金鸡湖摩天轮",
"subTitle": "观枫街1号",
"imageUrl": "https://img.api.aispeech.com/s/3724150899028.png",
"linkUrl": "https://map.amap.com/m/7867766776.html",
"label": "3.6km",
"extra": {
"latitude": 120.733062,//技能内引用这个参数的方式为 $content[1].extra.latitude$
"longitude": 31.26473,
"tel": "0512-66666666"
}
},
{
"title": "金鸡湖李公堤",
"subTitle": "金鸡湖大道888号",
"imageUrl": "https://img.api.aispeech.com/s/3724150899030.png",
"linkUrl": "https://map.amap.com/m/78979878979.html",
"label": "2.6km",
"extra": {
"latitude": 124.783483,//技能内引用这个参数的方式为 $content[2].extra.latitude$
"longitude": 37.324893,
"tel": "0512-88888888"
}
}
],
"totalPages": 5,
"itemsPerPage": 5,
"currentPage": 2,
"recommendations": "[\"第3个\", \"下一页\"]",
"extra": {
"source": "amap",//技能内引用这个参数的方式为 $extra.source$
"apiVersion": "0.3.2"
}
}
```
### 文本控件的nativeApi客户端返回示例 DDS-Android-SDK格式
```java
DDS.getInstance().getAgent().subscribe("DUI.System.GetInfo", new NativeApiObserver() {
@Override
public void onQuery(String nativeApi, String data) {
if(nativeApi.equals("DUI.System.GetInfo")){
try {
JSONObject object = new JSONObject(data);
String tgt = object.optString("tgt");//获取nativeApi下发的参数
TextWidget textWidget = new TextWidget();
textWidget.addExtra("errId", "0");//nativeApi回传的参数
DDS.getInstance().getAgent().feedbackNativeApiResult(nativeApi,textWidget);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
```
### 列表控件的nativeApi客户端返回示例 DDS-Android-SDK格式
```java
DDS.getInstance().getAgent().subscribe("phone.acquire.contacts", new NativeApiObserver() {
@Override
public void onQuery(String nativeApi, String data) {
if (nativeApi.equals("phone.acquire.contacts")) {
try {
JSONObject object = new JSONObject(data);
String name = object.optString("name");//获取nativeApi下发的参数
ListWidget listWidget = new ListWidget();
for (int i = 0; i < 10; i++) {
ContentWidget widget = new ContentWidget();
widget.setTitle("张三" + i);
widget.setSubTitle("10086" + i);
widget.addExtra("name", "张三" + i);//nativeApi回传的参数,技能内引用方式为$content[i+1].extra.name$
widget.addExtra("phone", "10086" + i);
listWidget.addContentWidget(widget);
}
listWidget.addExtra("errId","0");//nativeApi回传的参数,技能内引用方式为$extra.errId$
DDS.getInstance().getAgent().feedbackNativeApiResult(nativeApi, listWidget);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
```
|
3 客户端DDS SDK功能
什么情况下需要客户端配合SDK的接口去完善技能的体验。
3.1 在技能内使用客户端数据?使用Cinfo接口。
1.使用词库
https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.12部分
2.使用Cinfo上传定位信息
https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.18部分
//如下
try {
JSONObject object = new JSONObject();
object.put("city", "苏州");
object.put("longitude", "120.73696");
object.put("latitude", "31.254458");
object.put("time", "2018-08-22T12:46:16+0800");
ContextIntent in = new ContextIntent("location", object);
DDS.getInstance().getAgent().updateProductContext(in);
} catch (DDSNotInitCompleteException | JSONException e) {
e.printStackTrace();
}
|
3.2 客户端如何在静默情况下命中这个技能?使用triggerIntent接口。
triggerIntent是不通过用户语音,而是通过代码形式去触发技能的一种方式。 通过传入技能名称、任务名称、意图名称、语义槽去命中技能。会跳过识别和语义,直接进入对话。典型场景是按钮点击触发技能。 见https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.11部分 |
3.3 手写的一句话怎么进入技能?使用sendText接口。
sendText接口和triggerIntent功能比较类似。 通过传入一句话代替用户语音输入。只跳过识别,继续进行语义和对话。典型场景是通过输入框输入文字代替语音。 见https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.15部分 |
3.4 动态修改识别模型?
1.技能内修改,见https://wiki.aispeech.com.cn/pages/viewpage.action?pageId=55282017#command%E6%8C%87%E4%BB%A4%E9%9B%86%E5%90%88-%E5%88%87%E6%8D%A2%E8%AF%86%E5%88%AB%E8%B5%84%E6%BA%90%E6%A8%A1%E5%9E%8B 2.客户端修改,见https://www.duiopen.com/docs/ct_common_Andriod_SDK 3.20部分 |
4 技能SDK
技能SDK相关问题请咨询技能同学
4.1 技能SDK是什么?
技能SDK是把需要客户端配合开发的技能的客户端代码集成起来,不用每次对接技能都需要客户端去写这些代码。 |
5 客户端常用文档
5.1 对外文档
1.DDS Android SDK开发文档(https://www.duiopen.com/docs/ct_common_Andriod_SDK)
2.DDS IOS SDK开发文档(https://www.duiopen.com/docs/ct_common_iOS_SDK)
3.DDS Linux SDK开发文档(https://www.duiopen.com/docs/ct_common_Embedded_SDK)
4.服务对接文档(https://www.duiopen.com/docs/websocket)(https://www.duiopen.com/docs/product_http)
5.UI事件及数据定义,Widget相关(https://www.duiopen.com/docs/ct_UI)
6.DCA Android SDK开发文档(https://www.duiopen.com/docs/DCA_SDK_Android)
7.DCA IOS 开发文档(https://www.duiopen.com/docs/DCA_SDK_iOS)