跳到内容 跳到主导航 跳到页脚

应用基础知识

应用目录结构

以新建项目为例,介绍下App工程的目录结构,以及每种文件类型的作用:

  • app                                                     源码目录
    • App.js                                           App的主界面
    • AppDebug.js                               App的调试主界面(调试的时候启动OPK不带参数,可以在这里模拟数据)
    • demo                                           示例代码
      • DemoScreen                        Demo功能UI界面
      • DemoViewModel                  Demo功能的业务逻辑
      • DemoVoice                           Demo功能的语音指令接收器
      • DemoTrigger                        负责Demo功能与主流程对接(通过trigger可进行OPK间的跳转)
  • extraResource                                    文件资源目录(例如:音视频)
  • img                                                     图片资源目录
  • dist                                                     OPK存储目录(初始可能不存在,打包OPK后自动创建)
  • node_modules                                    App依赖的库(初始可能不存在,可在项目目录下执行npm install,会自动创建)
  • .npmrc                                                npm账号配置
  • package.json                                      App配置及依赖库管理
  • app.json                                              App的基本配置文件(不能修改)

应用组件

应用组件是机器人应用的基本构建模块,每一个应用组件都有自己的专属职责,所有应用组件一块构成一个完整的机器人应用。

Voice

Voice负责接收语音指令及服务端指令,需继承自BaseVoice。

onListenCallback为语音指令回调函数:

public onListenCallback(intent: string, result: any, id: number, text: string): boolean {
    return false;
}

参数说明:

  • intent 语音指令标识
  • result 语音参数
  • text 语音识别出的文本内容

返回值:

  • true 表示该语音指令已被处理,后续不在传递。
  • false 表示当前OPK不处理该指令,交由其它OPK处理。

Trigger

Trigger负责当前业务与主流程对接,可以通过trigger执行OPK间的跳转切换,需继承自Trigger,在初始化时需要一个Channel参数,该参数类型为字符串,是与ViewModel进行通信的标识,必须与ViewModel使用同一个字符串。

trigger函数是用来接收ViewModel发送过来的事件及携带的数据,接收到事件后可根据TriggerProtocol.eventId决定跳转到哪个OPK,以下示例为在接收到1001事件后跳转到机器人唤醒页:

public trigger(protocol: TriggerProtocol): void | boolean {
    switch (protocol.eventId) {
        case 1001:
            this._trigger('home', protocol);
            break;
    }
}

this._trigger(‘home’, protocol )为真正执行OPK跳转的调用,其第一个参数为appKey,每一个OPK在注册信息的时候都会包含一个appKey,这是OPK的标识,第二个参数是我们希望给对方OPK的参数,接收方OPK可在构造函数中,使用props.navigation.state.params获取。

ViewModel

ViewModel主要用来实现当前业务逻辑,需继承自BaseViewModel,其在初始化的时候也需要一个Channel参数,该参数需与Trigger的保持一致,否则可能无法进行OPK的跳转。

ViewModel有两个生命周期函数:onStart 和 onStop , 顾名思义一个在业务开始的时候调用,一个在业务结束的时候调用。

除了两个生命周期函数,还有三个用来与Trigger通信的函数:

  • _uiTrigger(eventId, data) UI事件触发的跳转
  • _voiceTrigger(eventId, data) 语音事件触发的跳转
  • _apiTrigger(eventId, data) Api调用触发的跳转

Screen

Screen是当前业务与用户交互的起始点,负责界面的UI展示及功能组件的加载,需继承自BaseComponent,Screen是整个业务的起始点,也是对外的唯一交互点,Screen的显示与隐藏直接决定当前业务的状态,所以其它组件的生命周期也需要与Screen进行绑定,保持与Screen同生同灭 。

需要在Screen的构造函数中调用接口绑定与其它应用组件的关系:

public constructor(props: BaseComponentProps) {
        super(props);
    this.viewModel = new DemoViewModel();
    let voice = new DemoVoice(this.viewModel);
    //关联ViewModel及Voice的生命周期到当前界面上
    this.setViewModel(this.viewModel);
    this.setVoice(voice);
    //注册trigger跳转,必须添加,否则trigger无效
    triggerManager.addTrigger(new DemoTrigger());
}

生命周期函数,可用来处理业务的启动与停止事件:

//界面显示后的生命周期
public componentDidMount() {
    //重写界面的didMount,必须调用super
    super.componentDidMount();
}
//界面销毁前的生命周期
public componentWillUnmount() {
    //重写界面的Unmount,必须调用
    super super.componentWillUnmount();
}

渲染函数,用来显示UI及加载功能组件,如下所示在界面上显示一个文本,并在界面显示的时候开始导航:

public render() {
    let navigationParam = new NavigationParam('接待点', 0.5, 30000, 5000, 1000, 4);
    return (    <View>        <Text style={{ fontSize: 17, color: 'red'}}> {'Hello Robot'}</Text>
        <NavigationComponent
            param={navigationParam}
            onFinish={this.onFinish}
            onStatusUpdate={this.onStatusUpdate}
        />
    </View>
    );}

应用资源

图片资源

应用的图片资源需放置到img目录下,使用时通过require进行加载,参数为图片相对路径,如下示例:

<Image
    source={require('../../img/bg.png')}
>

文件资源

文件资源统一放置在extraResource目录下,应用在编译打包时会一块打包到OPK中,随着OPK一起安装到机器人上,可通过以下接口获取到文件资源存放目录:

AppManager.getOpkExtraPath();

应用注册

机器人应用需将自身的信息注册到机器人系统中,机器人系统才能注册的信息结合外部条件(例如:语音指令)判断是否启动该机器人应用,index.js是我们整个机器人应用的入口文件,在加载后就会立即执行,所以我们的注册应该写在index.js文件中。

//上线使用
AppRegistry.registerConfig([{
    appKey: 'Demo',
    component: () => App,
    intent: 'weather&get_weather', //例如:'weather&get_weather'
    appId: appid,
    priority: 1
}]);
//Debug调试使用
AppRegistry.registerComponent(appName, () => AppDebug);

在示例代码里有两个注册,一个是正式注册到机器人系统,一个是Debug调试时使用,这两个可以同时存在,不会影响执行结果,系统会在不同的情况下选择对应的注册信息,Debug调试的时候不涉及语音调度及OPK切换,只需要知道启动界面就可以了,所以只需要把AppDebug调试界面传递进去就可以了。正式注册时需要的信息相对就比较多了:

  • appKey          OPK功能标识 ,不能与其他OPK重名,全局唯一,自己人工定义(切换OPK的时候会根据appKey查找对应的OPK)
  • component    OPK功能启动界面
  • intent             OPK的启动指令,其中weather是domain, get_weather是intent,通过&符号连接,且必须全部为小写字母,有其它OPK指定这个指令做Trigger跳转时,OPK会启动。或全局NLP解析出这个指令时,OPK会启动。(只填写启动OPK的指令就可以,OPK启动后能接收到所有指令)。OPK启动支持填写多个domain&intent,格式是[‘domain1&intent1′,’domain2&intent2’]
  • appId             创建应用时使用的appId
  • priority           功能优先级(OPK切换的时候会比较优先级,优先级低的不能打断优先级高的,OPK会切换失败,优先级为1-3的数组,1优先级最高,3最低)

注意1:intent在应用上线发布后,可通过OrionBase平台动态修改。

注意2:priority在应用上线发布后,可联系我们动态修改。

应用跳转

应用的跳转是通过在trigger里进行,具体可参考应用组件Trigger描述,在应用跳转时需要指定一个appKey,是应用注册时指定,官方标准OPK所包含的场景及其对应的appKey如下表所示:

应用名称appKey参数描述
基础应用(Portal)wakeUp大表情页面
基础应用(Portal)home唤醒首页
问路引领queryLocation{“slots”:”{\”destination\”:[{\”value\”:\”目标点\”}]}”}
注意:slots内的参数需要额外一次json_encode。
问路引领
访客接待reception访客接待
导航navigation{result:{destination: ‘目标点’, distance: -1}}导航
导览guide导览
广告advert直接trigger不可用 1:接待后台需要配置广告 2:获取广告资源数据 3:配置tigger第二个参数数据广告
巡逻cruise巡逻
跳舞dance跳舞
拍照groupPhoto拍照

注意1:在开发时请避免与官方OPK中appKey重复。

注意2:在使用引领功能时,slots内的参数需要额外一次json_encode。

下载trigger跳转示例

应用退出

OPK应用的退出原理:通过trigger跳转,到home页面,实现退出功能。

语音事件分发

语音事件会优先分发给当前正在运行的OPK,当前OPK需要处理并消耗掉该指令,可在Voice的onListenCallback返回true,不处理拦截的话请返回false。当前OPK不处理该语音指令的话,会去查询所有OPK的注册信息,如果该语音指令属于某一OPK的启动指令,则比较OPK的优先级,如果当前OPK优先级较低,则退出当前OPK,切换到新的OPK中去处理。该语音指令如果没有OPK能够处理,则检查下语音指令携带的数据里是否包含answer信息,如果包含answer信息则分发给闲聊模块进行处理。如下图所示:

这篇文章是否有帮助?

0