混合移动应用程序web应用程序结束了自己的浏览器,可以运行在任何移动平台(Android, iOS、窗户等)。混合应用程序的很大的优势是,它有一个单一的代码库,而本地应用必须为每个平台重写。
Apache科尔多瓦是一个开源框架,发展混合应用。使用本地特性(除了那些已经可以通过hmtl5)应用程序可以使用插件。这些插件处理特定于平台的代码和可用于单个或多个平台。插件可用于访问GPS,加速度计或相机。
SAP编写自己的插件,贴上Kapsel,处理诸如登录和离线OData。这些混合应用程序带来企业的味道。
直到最近,SAP的推荐方法是使用混合应用程序工具包(或帽子)为了建立混合应用。应用程序构建发生在开发人员的PC或Mac。帽子赢得了名声很难设置,阻碍了使用SAP生态系统内的混合应用。
菲奥里移动云计算的组建服务的核心,所以不需要安装的帽子。我们可以从Web触发构建IDE。我们指定(已部署)菲奥里应用(s)我们想要包,几分钟后我们可以下载. apk (Android)和.ipa (iOS)文件准备安装在移动设备上。
云制造服务运作得很好。它通常为平台构建没有issueas约8分钟。只有几次当构建失败了由于技术问题。
有一些方面的技术还不觉得成熟。一个领域是离线OData特性。当使用菲奥里移动不同的事情更传统的混合动力和本地应用。目的地将是其中的一个例子,因为菲奥里移动应用程序使用生成的目标参考SAP (CP)门户服务云平台。
我的观点不是离线OData看起来不成熟,而离线功能使用菲奥里移动应用程序时可能会非常棘手。我们仍然接受援助从SAP应用优化的离线功能。这是一个耻辱,因为共享数据和三角洲请求的处理,例如,两个功能,这证明“中间件”的方法离线SAP。
认证也是一个挑战。在以前的项目中我使用了菲奥里客户与SAP云身份(现在正式SAP云平台的身份认证)。菲奥里客户端存储设备上的用户名和密码,用户不需要输入他们每次会话超时。我们还没有实现,菲奥里移动应用。
创建菲奥里应用程序需要创建和发布应用程序部署的地点。
去门户服务然后点击去服务。
在您的浏览器将打开一个新标签。在这个新窗口去网站目录选项卡,然后点击创建网站。
将显示一个弹出。输入您的网站的名字,选择SAP菲奥里发射台作为模板并点击创建
后你将被重定向到SAP菲奥里配置驾驶舱。关闭选项卡并回到管理门户服务空间。
现在我们需要发布这个站点并设置为默认。
一旦我们创建和发布网站我们可以创建我们的鲜花广场项目。
再次转到服务选项卡,打开IDE SAP Web服务,点击去服务
一个新的选项卡将被打开。从这里我们将开始创建我们的鲜花广场项目。
SAP Web IDE工作区中我们可以看到所有文件inludes鲜花广场项目。
开放Component.js文件。
Component.js第一点我们的应用程序中,我们可以说它是指数封装了所有我们的应用程序的细节,即视图名称,路由信息,主要观点,应用程序类型(全屏幕或SplitApp),应用程序服务配置等。
在这里初始化我们将配置插件功能。我们需要设置属性,设置回调函数,调用一些方法等。
sap.ui.define ([“sap / ui /核心/ UIComponent”、“sap / ui /设备”,“MyFristFioriApp /模型/模型”),函数(UIComponent、设备模型){严格“使用”;.getEventBus var oEventBus = sap.ui.getCore () ();var scannerIsInitialized = false;返回UIComponent.extend (“MyFristFioriApp。组件”,{元数据:{清单:“json”}, / * * *期间,UI5自动初始化组件的启动程序,调用init方法。* @ public * @override * / init函数(){/ / UIComponent.prototype.init调用基础组件的初始化函数。应用(这个参数);/ /设置设备模型this.setModel (models.createDeviceModel(),“设备”);如果(! scannerIsInitialized) {scannerIsInitialized = true;window.readerConnected= 0; window.scannerActive = false; cmbScanner.addOnResume(function(result) { cmbScanner.setAvailabilityCallback((readerAvailability) => { if (readerAvailability === cmbScanner.CONSTANTS.AVAILABILITY_AVAILABLE) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "AVAILABLE" }); cmbScanner.connect((result) => { }); } else { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "NOT AVAILABLE" }); } }); if (Device.os.android) { cmbScanner.connect((result) => { }); } }); cmbScanner.addOnPause(function(result) { if (Device.os.android) { cmbScanner.disconnect(); } cmbScanner.setAvailabilityCallback(); }); cmbScanner.setPreviewContainerPositionAndSize(0, 0, 100, 50); cmbScanner.setConnectionStateDidChangeOfReaderCallback((connectionState) => { if (connectionState === cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "CONNECTED" }); if (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"); 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; } }); } else if (connectionState == cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTED) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "DISCONNECTED" }); } else if (connectionState == cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "CONNECTING" }); } else if (connectionState == cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTING) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "DISCONNECTING" }); } window.readerConnected = connectionState; }); cmbScanner.setAvailabilityCallback((readerAvailability) => { if (readerAvailability === cmbScanner.CONSTANTS.AVAILABILITY_AVAILABLE) { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "AVAILABLE" }); cmbScanner.connect((result) => { }); } else { oEventBus.publish("ScanView", "SetConnectionStatus", { statusText: "NOT AVAILABLE" }); } }); cmbScanner.setActiveStartScanningCallback((result) => { window.scannerActive = result; }); cmbScanner.setPreviewOptions(cmbScanner.CONSTANTS.PREVIEW_OPTIONS.DEFAULTS | cmbScanner.CONSTANTS.PREVIEW_OPTIONS.HARDWARE_TRIGGER); cmbScanner.setCameraMode(cmbScanner.CONSTANTS.CAMERA_MODES.NO_AIMER); cmbScanner.loadScanner(0, (result) => { cmbScanner.connect((result) => { }); }); oEventBus.subscribe("Component", "LoadScanner", this.loadScanner, this); } }, loadScanner: function(sChanel, sEvent, oData) { cmbScanner.disconnect((result) => { cmbScanner.loadScanner(oData.selectedDevice, (result) => { cmbScanner.connect((result) => { }); }); }); }, onExit: function() { oEventBus.unsubscribe("Component", "LoadScanner", this.loadScanner, this); cmbScanner.disconnect(); cmbScanner.setAvailabilityCallback(); } }); });
cmbScanner是一个对象,代表我们的插件。这个对象我们都可以访问API方法从我们的插件和常量。
在这里我们只配置阅读器设备,处理连接、可用性等。我们将在其他视图做扫描和取得成果。如果我们想通知用户每连接状态改变或其他信息阅读器设备我们将使用EventBussap对象。这个对象我们可以发布函数和调用应用程序中的任何视图。在这个例子中与EventBus我们调用连接状态发生了变化SetConnectionStatus功能,实现在视图执行扫描并设置标签文本显示用户当前连接状态。
现在打开ScanView.view.xml加上这段代码:
< mvc视图xmlns: mvc = " sap.ui.core。mvc“xmlns: html = " http://www.w3.org/1999/xhtml " xmlns:核心= " sap.ui。核心”controllerName = " MyFristFioriApp.controller。ScanView”displayBlock = " true " > <应用xmlns = " sap。m”> <页> <页面标题=“MWBCameraDemo showHeader”=“false”> <副标题> <工具栏id =“__toolbar2”宽度=“100%”> <内容> < FlexBox id =“__box0”宽度=“100%”alignContent =“中心”alignItems = =“开始”方向“列”fitContainer = " true " justifyContent = "中心" > <物品> <选择id =“selectActiveDevice”项= "{/设备}" textAlign = "中心" selectedKey = = " 0 "变化" activeDeviceChanged " > <核心:条目文本= "{文本}"键= "{关键}" / > < /选择> < /物品> < / FlexBox > <文本标签id =“lblStatus”=“断开”宽度=“100%”textAlign =“结束”设计= "勇敢" / > < /内容> < /工具栏> < /小标题> <内容> < FlexBox id =“flexBoxContainer”宽度=“100%”alignContent =“开始”alignItems = = "开始"方向"列" fitContainer = " true " / > < /内容> <页脚> <工具栏id =“__toolbar1”宽度=“100%”> <内容> <按钮id =“btnScan”新闻=“btnScanPress”文本=“扫描”宽度= " 100% " / > < /内容> < /工具栏> < /页脚> < /页面> < /页> < /应用程序> < / mvc:视图>
你可以用CodeEditor或LayoutEditor设计视图。
之后,打开ScanView.controller.js并添加此代码
sap.ui.define ([“sap / ui / core / mvc控制器”)、功能(控制器){严格“使用”;.getEventBus var oEventBus = sap.ui.getCore () ();var oModel = new sap.ui.model.json.JSONModel ();oModel。setData({设备:[{关键:“0”、文本:“MX装置”},{关键:“1”,文本:“移动相机”}]});返回Controller.extend (“MyFristFioriApp.controller。ScanView”, {onInit:函数(){this.getView () .setModel (oModel);(){},onAfterRendering:功能窗口。scannerActive = false;开关(window.readerConnected) {cmbScanner.CONSTANTS。CONNECTION_STATE_CONNECTED: this.getView () .byId (“lblStatus”) . settext(“连接”); break; case cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTED: this.getView().byId("lblStatus").setText("DISCONNECTED"); break; case cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING: this.getView().byId("lblStatus").setText("CONNECTING"); break; case cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTING: this.getView().byId("lblStatus").setText("DISCONNECTING"); break default: this.getView().byId("lblStatus").setText("UNKNOWN"); 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("sapUiSmallMarginTop"); verticalLayoutContainer.addContent(new sap.m.Label({ text: result.symbologyString + ":", textAlign: "Begin", design: "Bold" }).addStyleClass("sapUiSmallMarginBegin")); verticalLayoutContainer.addContent(new sap.m.Text({ text: result.readString, textAlign: "Begin" }).addStyleClass("sapUiSmallMarginBegin")); this.getView().byId("flexBoxContainer").addItem(verticalLayoutContainer); } }); }, btnScanPress: function() { if (window.readerConnected === cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED) { if (window.scannerActive === true) { cmbScanner.stopScanning(); } else { cmbScanner.startScanning(); } } }, setConnectionStatus: function(sChanel, sEvent, oData) { this.getView().byId("lblStatus").setText(oData.statusText); }, activeDeviceChanged: function() { cmbScanner.disconnect((result) => { oEventBus.publish("Component", "LoadScanner", { selectedDevice: parseInt(this.getView().byId("selectActiveDevice").getSelectedKey()) }); }); }, onExit: function() { oEventBus.unsubscribe("ScanView", "SetConnectionStatus", this.setConnectionStatus, this); if (window.readerConnected === cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED) { if (window.scannerActive === true) { cmbScanner.stopScanning(); } } cmbScanner.setResultCallback((result) => { return false; }); } }); });
在这个视图中,我们有一个浏览按钮startScanning () / stopScanning ()和cmbScanner.setResultCallback处理成功的扫描结果。
在我们完成创建和发展我们的鲜花广场项目我们需要准备移动部署。
首先,我们需要将我们的项目部署SAP HANA云平台。
一个
如果您计划使用cmbSDK移动扫描与智能手机或平板电脑(没有MX移动终端),SDK要求安装许可证密钥。没有许可密钥,SDK还是操作,虽然扫描结果将模糊随机替换字符(SDK将扫描结果与星号字符)。
联系你Cognex销售代表信息如何获得许可密钥包括30天试用许可证可用于评估SDK。
在获得您的许可密钥公开i18n。属性文件在您的项目在IDE SAP WEB服务,并设定你的获得钥匙。
然后回到Component.js文件,并检查该代码:
cmbScanner.setConnectionStateDidChangeOfReaderCallback ((connectionState) = >{如果(connectionState = = = cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED) {oEventBus。发布(“ScanView”、“SetConnectionStatus”{statusText:“连接”});如果窗口。readerConnected ! = connectionState) {cmbScanner.setSymbologyEnabled(”的象征。DATAMATRIX”,真正的);cmbScanner.setSymbologyEnabled(“符号。C128”,真正的);cmbScanner。sendCommand(“设置触发器。2型”);}var sdkKEY = " ";如果Device.os.android sdkKEY = this.getModel (i18n) . getproperty (“MX_MOBILE_LICENSE_ANDROID”);其他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你读这篇文章的关键。属性和调用cmbScanner.registerSDK与你的许可证密钥方法注册SDK。
检查结果对象发送回调函数可以告诉我们如果注册成功或有什么问题。