Providing native barcode scanning on SAP Mobile Start (SAPUI5 & Quagga.js)

Hey everyone!

SAP Fiori Client is going to be removed from app store and google play as mentioned in note 2992772. While it must be noted that SAP Mobile Start is NOT a replacement for the SAP Fiori Client, it is quite natural that SAP Mobile Start will be used as entry point for the mobile users going forward.

Since standard SAPUI5 Barcode Scanning functionalities of SAPUI5 versions below 1.92.0 are reliant on Cordova plugin (accessible via SAP Fiori Client), any apps below version 1.92.0 that are utilizing these features won’t be supported by standard browsers or SAP Mobile Start. The customers who are using native features like camera integration for barcode scanning via SAP Fiori Client must therefore look at other alternatives like QuaggaJS and ZXingJS as suggested in the note.

This blog will help you to make use of one of these alternatives. I will explain how I’ve created a custom SAP UI5 app that uses QuaggaJS library and can be launched on iPhone and iPad using SAP Mobile Start:

This will cover the following:

  • Creation of a simple SAPUI5 App in SAP Business Application Studio
  • Deployment to BTP Subaccount
  • Making the app available in SAP Launchpad Service site
  • Launch the app from SAP Mobile Start


    • Technical:
      • SAP BTP Subaccount with
        • Subscription to SAP Launchpad Service & Business Application Studio
        • Cloud Foundry Org and Space for custom apps deployment
    • Knowledge
      • Basic SAPUI5 Programming / Business Application Studio
      • (optional) SAP Launchpad Service

1. Creation of Simple SAPUI5 Barcode Scanning App

For my own first try of the barcode functionality as part of an POC, I followed this blospost by Ian MacGregor. He provides further inside on the apps development.
Note that this is an example for the most basic app you could think of and the project settings might be different for other purposes. I will explain how to create a project in SAP Business Application Studio and how to deploy to BTP subaccount.

1.1 Create Empty SAP Fiori Project in Business Application Studio

Once you are in the Business Application Studio create a new Dev Space for SAP Fiori:


SAP Fiori space on Business Application Studio

Launch it by clicking the title. You will see a welcome page, where you can create a new project from template:

  1. Select Template and Target Location:           
    • SAP Fiori application

  2. Floorplan Selection
    • Application Type: SAPUI5 freestyle
    • Floorplan: SAPUI5 Application
  1. Data Source and Service Selection:
  2. View name:
    • BarcodeScanner (Or something else you prefer)
  3. Project Attributes:
    • Provide module name and application title
      (Make sure to tick “Yes” for “Add
      deployment configuration”
      and “Add FLP

  1. Deployment Configuration
    • Target:  Cloud Foundry
    • Destination: None
    • Add application to managed application router: Yes

  1. Fiori Launchpad Config:
    • Semantic Object:  barcode
    • Action:      scan
    • Title:         Barcode Scanner
    • Subtitle:   POC for SAP Mobile Start

1.2 Develop Basic Barcode Scanning App

First you need to download the latest version of Quagga.js library from here.
Download the page and you will get the quagga.min.js file.

Open the project folder in a workspace, so that you can proceed with the development.
Once you are in the workspace go to the webapp folder, create a subfolder named libs and paste the downloaded quagga.min.js file there. Your folder should look like this:

Next, open the manifest.json file and search for the “resources” node and add the path to the library:

"resources": { "css": [ { "uri": "css/style.css" } ], "js": [ { "uri": "libs/quagga.min.js" } ] },

In the folder webapp > model > models.js replace the createDeviceModel function with this one:

createDeviceModel: function () { var oModel = new JSONModel(Device); oModel.setDefaultBindingMode("OneWay"); // Disable the scan barcode button by default oModel.setProperty("/barcodeScanEnabled",false); if(navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia){ navigator.mediaDevices.getUserMedia({video:true}).then(function(stream){ // device supports video, which means will enable the scan button oModel.setProperty("/barcodeScanEnabled",true); }).catch(function(err){ // not supported, barcodeScanEnabled already default to false }); } return oModel;

On webapp > view > BarcodeScanner.view.xml add the following Label, Input and Button to the <Page>-Tag:
(Just replace the <content/> tag by the below)

<Label text="Barcode value" />
<Input id="scannedValue" placeholder="Use scan button to enter barcode" />
<Button icon="sap-icon://bar-code" text="Scan" tooltip="Scan barcode" press="onScanForValue">

On webapp > controller >BarcodeScanner.controller.js add the following functions below the onInit-function:

(Note: In this code snipped also the QR-Code format get’s selected. In this case the standard “code_128_reader”, you can change the format by adding different readers from Quagga.js documentation)

onScanForValue: function (oEvent) { if (!this._oScanDialog) { this._oScanDialog = new sap.m.Dialog({ title: "Scan barcode", contentWidth: "640px", contentHeight: "480px", horizontalScrolling: false, verticalScrolling: false, stretchOnPhone: true, content: [new sap.ui.core.HTML({ id: this.createId("scanContainer"), content: "<div />" })], endButton: new sap.m.Button({ text: "Cancel", press: function (oEvent) { this._oScanDialog.close(); }.bind(this) }), afterOpen: function () { this._initQuagga(this.getView().byId("scanContainer").getDomRef()).done(function () { // Initialisation done, start Quagga Quagga.start(); }).fail(function (oError) { // Failed to initialise, show message and close dialog...this should not happen as we have // already checked for camera device ni /model/models.js and hidden the scan button if none detected MessageBox.error(oError.message.length ? oError.message : ("Failed to initialise Quagga with reason code " +, { onClose: function () { this._oScanDialog.close(); }.bind(this) }); }.bind(this)); }.bind(this), afterClose: function () { // Dialog closed, stop Quagga Quagga.stop(); } }); this.getView().addDependent(this._oScanDialog); }; }, _initQuagga: function (oTarget) { var oDeferred = jQuery.Deferred(); // Initialise Quagga plugin - see for details Quagga.init({ inputStream: { type: "LiveStream", target: oTarget, constraints: { width: { min: 640 }, height: { min: 480 }, facingMode: "environment" } }, locator: { patchSize: "medium", halfSample: true }, numOfWorkers: 2, frequency: 10, decoder: { readers: [{ format: "code_128_reader", config: {} }] }, locate: true }, function (error) { if (error) { oDeferred.reject(error); } else { oDeferred.resolve(); } }); if (!this._oQuaggaEventHandlersAttached) { // Attach event handlers... Quagga.onProcessed(function (result) { var drawingCtx = Quagga.canvas.ctx.overlay, drawingCanvas = Quagga.canvas.dom.overlay; if (result) { // The following will attempt to draw boxes around detected barcodes if (result.boxes) { drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height"))); result.boxes.filter(function (box) { return box !==; }).forEach(function (box) { Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 }); }); } if ( { Quagga.ImageDebug.drawPath(, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 }); } if (result.codeResult && result.codeResult.code) { Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 }); } } }.bind(this)); Quagga.onDetected(function (result) { // Barcode has been detected, value will be in result.codeResult.code. If requierd, validations can be done // on result.codeResult.code to ensure the correct format/type of barcode value has been picked up // Set barcode value in input field this.getView().byId("scannedValue").setValue(result.codeResult.code); // Close dialog this._oScanDialog.close(); }.bind(this)); // Set flag so that event handlers are only attached once... this._oQuaggaEventHandlersAttached = true; } return oDeferred.promise(); } 

This is it for the coding. Once you are done save all the files (if not autosaved) and open a terminal.
Make sure to change the directory to your project folder and type:

npm run start

This will start your application and open it in a new window so that you can test it. If it won’t open in a new window you might need to open it manually.

On startup the app should ask for camera access, you need to allow it. Otherwise the scan button will not be visible. After that it should look like below:

Via the Scan-Button you will open a context for scanning, which holds your camera view.
If you copied the code snippet given above, make sure to test it with a Code128-Barcode like the following:


Sample Code128-Barcode

2. Deploy app on Subaccount

To deploy an app to a Subaccount you need to log in to Cloud Foundry and select the right Cloud Foundry Organization and Space. You can do that by opening a terminal and type:

cf login

You will be prompted to enter your email & password for BTP authentication. After that you need to select the Org of your subaccount and a space, if more than one is available.

Next, you can build your project for deployment by right-clicking the mta.yaml file and selecting Build MTA Project.

This will take a moment and will create the MTA archive that is necessary for deployment on BTP.
As a final step right-click the mtar file within the newly created mta_archives folder and select Deploy MTA Archive.

This might take some time, but after it’s done you should be able to see your application deployed on your Subaccount in the HTML5 Applications tab:

You can open and test it by clicking the application name.

3. Integrate HTML5 apps to your launchpad

In this step you will have to refresh the HTML5 content provider within the Site Manager to add your newly created HTML5 app to your content there.

After that you will need to add the app to a catalog, role and group.
You can follow this blogpost by Murali Shanmugham which briefly shows the steps of integrating HTML5 apps to your launchpad site.

4. Open the launchpad site within SAP Mobile Start app

To access your site within the SAP Mobile Start app you need to access the QR code in the site settings. (SAP Mobile Start Application)

Once onboarded on your mobile device, you should see your newly created app as a tile. When you open it, it should look like that:


Screenshot of the app in SAP Mobile Start

Note:  Persist camera access in Mobile Start Safari View Controller

You might have realized, that the popup for camera access comes up only the first time in the browser. After that your setting is persisted and your browser won’t ask for this again. When accessing your app via SAP Mobile Start, you will be asked for camera access every time by default. If necessary, it’s possible to persist the setting in the Safari View Controller. Therefore, you need to click the aA Icon in the top of the Shell and navigate to Website Settings. Next, for Camera select Allow.

5. Wrap Up

In this blog I covered the creation and deployment of a very simple barcode scanning custom-SAP UI5 app, that can also be launched from SAP Mobile Start.

Thank you for following this blog till the end. I hope you can make use of the information in your own implementation and use SAP Mobile Start as the native entry point. If you have any feedback feel free to share them below!

We look forward to your comments.

Stay up to date with latest news and post your questions or feedback about SAP Mobile Start in the Q&A area. Start by visiting your SAP Mobile Experience community page and click “follow”. We’ll be publishing more informative blog posts.

Want to be notified? Check your profile settings to ensure you have your settings activated.