混合移动应用程序是由自己的浏览器包装而成的web应用程序,可以在任何移动平台(Android、iOS、Windows等)上运行。混合应用程序的最大优势在于它有一个单一的代码库,而必须为每个平台重新编写本机应用程序。
Apach.科尔多瓦是一个用于开发混合应用的开源框架。要使用原生特性(除了那些已经通过hmtl5可用的特性),应用程序可以使用插件。这些插件处理特定于平台的代码,可用于单个或多个平台。例如,插件可以访问GPS、加速计或相机。
SAP写了自己的插件,品牌为Kapsel,以处理登录和离线OData之类的事情。这给混合应用带来了企业风格。
直到最近,SAP推荐的方法是使用混合应用程序工具包(HAT)来构建混合应用程序。应用程序是在开发者的PC或Mac上构建的。HAT因难以设置而获得了声誉,这阻碍了SAP生态系统中混合应用的使用。
Fiori Mobile的核心是云构建服务,因此无需安装帽子。我们可以从WebIDE触发构建。我们指定要打包的(已部署的)Fiori应用程序,几分钟后我们可以下载.apk(适用于Android)和.ipa(适用于iOS)文件,准备安装在移动设备上。
云构建服务运行良好。它通常在大约8分钟内为两个平台建立,而没有发布。由于技术问题,建立失败时只有几次。
技术有一些方面尚未感到成熟。一个区域是脱机ODATA功能。使用FIORI移动内容与更传统的混合动力和本机应用程序不同。一个示例是目的地,因为Fiori移动应用程序使用所生成的目的地,它引用SAP云平台(CP)门户服务。
我的观点不是离线OData看起来不成熟,而是离线功能在与Fiori移动应用程序一起使用时可能会很棘手。我们仍在接受SAP的帮助,以优化我们应用程序的离线功能。这是一个遗憾,因为共享数据和处理增量请求等两个特性证明了SAP采用的“中间件”离线方法的合理性。
身份验证也是一个挑战。在上一个项目上,我使用了Fiori客户与SAP云身份(现在正式)结合SAP云平台标识身份验证).Fiori客户端将用户名和密码存储在设备上,这样用户就不必在每次会话超时时都输入用户名和密码。我们的Fiori移动应用程序尚未实现这一点。
要创建FIORI应用程序,我们需要创建和发布将部署应用程序的站点。
去门户服务然后单击“转到服务”。
在您的浏览器将打开一个新标签。在这个新窗口中,转到网站目录选项卡,然后单击创建站点。
将显示一个弹出窗口。输入您的网站的名字,选择SAP Fiori Launchpad.作为模板源,单击“创建”
接下来,你将被重定向到SAP Fiori配置驾驶舱。关闭选项卡并返回Portal服务的管理空间。
现在我们需要发布此站点并设置为默认值。
一旦我们创建和发布该网站,我们就可以创建我们的Fiori项目。
再次转到服务选项卡,打开SAP Web IDE服务,然后单击转到服务
将打开一个新选项卡。从这里,我们将开始创建我们的Fiori项目。
在SAP Web IDE工作区中,我们可以看到Fiori项目包含的所有文件。
打开Component.js文件。
Component.js是我们应用程序的第一点,可以说它作为索引,封装了我们所有的应用程序细节,即视图名称、路由细节、主视图、应用程序类型(全屏或SplitApp)、应用程序服务配置等。。
在此处初始化功能我们将配置我们的插件。设置我们需要的属性,设置回调函数,调用一些方法等。
定义([“sap/ui/core/UIComponent”、“sap/ui/Device”、“MyFristFioriApp/model/models”]、函数(UIComponent、Device、models){“严格使用”;var oEventBus=sap.ui.getCore().getEventBus();var scannerIsInitialized=false;返回UIComponent.extend(“MyFristFioriApp.Component”,{元数据:{manifest:{manifest:“json”}),//***组件在应用程序启动期间由UI5自动初始化,并调用init方法一次。*@public*@override*/init:function(){//调用基础组件的init函数UIComponent.prototype.init.apply(this,arguments);//将设备模型设置为this.setModel(models.createDeviceModel(),“device”);如果(!scannerIsInitialized){scannerIsInitialized=true;window.readerConnected=0;window.scannerActive=false;cmbScanner.addOnResume(函数(结果){cmbScanner.setAvailabilityCallback((readerAvailability)=>{if(readerAvailability==cmbScanner.CONSTANTS.AVAILABILITY){oEventBus.publish(“ScanView”,“SetConnectionStatus”,{statusText:“可用”});cmbScanner.connect((结果)=>{};}else{oEventBus.publish(“扫描视图”,“设置连接状态”,{statusText:“不可用”};}}});if(Device.os.android){cmbScanner.connect((结果)=>{};});cmbScanner.addOnPause(函数(结果){if(Device.os.android){cmbScanner.disconnectcmbScanner.setAvailabilityCallback();});cmbScanner.setPreviewContainerPositionAndSize(0,0,100,50);cmbScanner.setConnectionStateDidChangeOfReaderCallback((connectionState)=>{if(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){oEventBus.publish(“扫描视图”,“SetConnectionStatus”,“状态文本:{Status:“CONNECTED”});如果(window.readerConnected!=connectionState){cmbScanner.setSymbologyEnabled(“SYMBOL.DATAMATRIX”,true);cmbScanner.setSymbologyEnabled(“SYMBOL.C128”,true);cmbScanner.sendCommand(“SET TRIGGER.TYPE 2”);}var sdkKEY=“”;if(Device.os.android)sdkKEY=this.getModel(“i18n”).getProperty”(“MX_MOBILE_LICENSE_android”);els sdkKEY=this.getModel(“i18n”).getProperty(“MX_MOBILE_LICENSE_iOS”);cmbScanner.registerSDK(sdkKEY,(res)=>{switch(res){case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTER_OK:中断;case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTER_无效_键:中断;case cmbScanner.CONSTANTS.REGISTER_RESU无效_应用程序:中断;case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION\u INVALID\u SDK\u VERSION:break;case cmbScanner.CONSTANTS.REGISTER\u RESULTS.REGISTRATION\u INVALID\u KEY\u VERSION:break;case cmbScanner.CONSTANTS.REGISTER\u RESULTS.REGISTER\u KEY\u过期:break;默认值:break;});}否则如果(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_connected){oEventBus.publish(“扫描视图”,“设置连接状态”,“断开连接”})}如果(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING){oEventBus.publish(“扫描视图”,“设置连接状态”,“状态文本:”连接”})}如果(connectionState==cmbScanner.CONSTANTS.CONNECTION\u STATE\u DISCONNECTING){oEventBus.publish(“扫描视图”、“设置连接状态”、“断开连接”);}window.readerConnected=connectionState;});cmbScanner.setAvailabilityCallback((readerAvailability)=>{if(readerAvailability==cmbScanner.CONSTANTS.AVAILABILITY\u可用){oEventBus.publish(“ScanView”、“SetConnectionStatus”、{statusText:“AVAILABLE”});cmbScanner.connect((结果)=>{});else{oEventBus.publish(“ScanView”、“SetConnectionStatus”、{statusText:“NotAvailable”});cmbScanner.setActiveStartScanningCallback((结果)=>{window.Neractive=result;});cmbScanner.setPreviewOptions(cmbScanner.CONSTANTS.PREVIEW_OPTIONS.DEFAULTS | cmbScanner.CONSTANTS.PREVIEW_OPTIONS.HARDWARE_触发器);cmbScanner.setCameraMode(cmbScanner.CONSTANTS.CAMERA_MODES.NO_AIMER);cmbScanner.loadScanner(0,(result)=>{cmbScanner.connect((result)=>{});oEventBus.subscribe(“组件”,“loadScanner”,this.loadScanner,this)},loadScanner:function(sChanel,sEvent,oData){cmbScanner.disconnect((结果)=>{cmbScanner.loadScanner(oData.selectedDevice,(结果)=>{cmbScanner.connect((结果)=>{};});}),onExit:function(){oEventBus.unsubscribe(“组件”,“loadScanner”,this.loadScanner,this);cmbScanner.disconnect();cmbScanner.setAvailabilityCallback(); } }); });
cmbScanner是一个代表插件的对象。通过这个对象,我们可以访问所有的对象API方法和我们插件中的常量。
这里我们只配置阅读器、处理连接、可用性等。我们将在其他视图中进行扫描并获得结果。如果我们想要通知用户每一个连接状态改变或其他信息,我们将使用的阅读器设备EventBussap对象。通过这个对象,我们可以发布函数,并从应用程序的任何视图中调用它们。在这个例子中,我们调用的EventBus改变了连接状态设置连接状态在执行扫描的视图中实现的函数,并将标签文本设置为显示用户当前连接状态。
现在开始ScanView.view.xml并添加此代码:
<项目>
您可以使用CodeEditor或LayoutEditor设计视图。
在那之后scanview.Controller.js.然后添加以下代码
sap.ui.define([“sap/ui/core/mvc/Controller”]、函数(Controller){“严格使用”;var-oEventBus=sap.ui.getCore().getEventBus();var-oModel=new-sap.ui.model.json.JSONModel();oModel.setData({Devices:[{key:“0”,text:“MX Device”}、{key:“1”,text:“Mobile-Camera”}]));返回Controller.extend(“MyFristFiscanoriApp.Controller.view”,{onInit:function(){this.getView().setModel(oModel);},onAfterRendering:function(){window.scannerActive=false;switch(window.readerConnected){case-cmbScanner.CONSTANTS.CONNECTION\u STATE\u CONNECTED:this.getView().byId(“lblStatus”).setText(“CONNECTED”);break;case-cmbScanner.CONSTANTS.CONNECTION\u STATE\u CONNECTED:this.getView().byId(“lblStatus”).setText(“断开”);break;case-cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING:this.getView().byId(“lblStatus”).setText(“CONNECTING”);break;case-cmbScanner.CONSTANTS.CONNECTION_STATE_断开:this.getView().byId(“lblStatus”).setText(“未知”);break;}oEventBus.subscribe(“ScanView”,“SetConnectionStatus”,this.SetConnectionStatus,this);cmbScanner.setResultCallback((result)=>{if(result&&result.readString){var verticalLayoutContainer=new sap.ui.layout.VerticalLayout(null,{width:“100%”。)).addStyleClass(“sapusmallmargintop”);verticalLayoutContainer.addContent(新的sap.m.Label({text:result.symbologyString+“:”,textAlign:“开始”,design:“粗体”).addStyleClass(“sapUiSmallMarginBegin”);verticalLayoutContainer.addContent(新的sap.m.text({text:result.readString,textAlign:“开始”)).addStyleClass(“sapUiSmallMarginBegin”);this.getView().byId(“flexBoxContainer”).addItem(verticalLayoutContainer);})});},btnScanPress:function(){if(window.readerConnected==cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){if(window.scannerative==true){cmbScanner.stopScanning();}else{cmbScanner.startScanning();},setConnectionStatus:function(sChanel,sEvent,oData){this.getView().byId(“lblStatus”).setText(oData.statusText)},activeDeviceChanged:function(){cmbScanner.disconnect((结果)=>{oEventBus.publish(“组件”,“加载扫描仪”,“选择的设备:parseInt(this.getView().byId(“选择的活动设备”).getSelectedKey())});}),onExit:function(){oEventBus.unsubscribe(“扫描视图”,“设置连接状态”,this.SetConnectionStatus,this);如果(window.readerConnected==cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){if(window.scannerative==true){cmbScanner.stopScanning();}}}cmbScanner.setResultCallback((result)=>{return false;};}}});
在这个视图中,我们有一个扫描按钮startScanning () / stopScanning ()和cmbscanner.setresultcallback.处理成功的扫描结果。
在我们完成创建和开发我们的Fiori项目后,我们需要准备移动部署。
首先我们需要部署我们的项目SAP HANA云平台。
一种
如果你打算使用CMBSDK.要使用智能手机或平板电脑(不使用MX移动终端)进行移动扫描,SDK需要安装许可证密钥。如果没有许可证密钥,SDK仍将运行,尽管扫描结果会模糊(SDK将随机将扫描结果中的字符替换为星号字符)。
联系您的Cognex销售代表,了解如何获得许可证密钥,包括可用于评估SDK 30天的试用许可证。
获取许可证密钥后,在SAP WEB IDE服务上的项目中打开i18n.properties文件,并设置获取的密钥。
然后再回到教室Component.js文件并检查此代码:
cmbScanner.setConnectionStateDidChangeOfReaderCallback((connectionState) => {if (connectionState === cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED) {oEventBus. setconnectionstatedidchangeofreadercallback ((connectionState)) => {publish("ScanView", "SetConnectionStatus", {statusText: "CONNECTED"});如果窗口。{cmbscanner . setsymologyenabled ("SYMBOL. state ");DATAMATRIX”,真正的);cmbScanner.setSymbologyEnabled(“符号。C128”,真正的);cmbScanner。sendCommand("SET TRIGGER.TYPE 2"); } var sdkKEY = ""; if (Device.os.android) sdkKEY = this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_ANDROID"); else sdkKEY = this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_iOS"); cmbScanner.registerSDK(sdkKEY, (res) => { switch (res) { case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_OK: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_CHECKSUM: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_APPLICATION: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_SDK_VERSION: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY_VERSION: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_PLATFORM: break; case cmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_KEY_EXPIRED: break; default: break; } }); ...........
您可以看到,成功连接后,您从i18n.properties读取此密钥并调用cmbScanner.registerSDK方法使用许可证密钥注册SDK。
检查在回调函数中返回的结果对象可以告诉我们注册是否成功或问题是什么。