Technical Articles
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.
The standard SAPUI5 barcode scanning functionalities of older SAPUI5 versions were reliant on the Cordova plugin (accessible via SAP Fiori Client). Therefore some native device capabilities (like barcode scanning) of these versions are not supported by standard browsers or SAP Mobile Start.
The note 2992772 reveals, that barcode scanning within web applications and on mobile devices got updated for the versions as of 1.92.0 in August 2021. In October 2021 the update of SAPUI5 on ABAP version 1.84.18 or above followed. This version is the long term maintenance equivalent for Fiori Frontend Server 2020 FPS1 or higher and can be used with SAP S/4HANA 1809 or higher. (For further information on the deployment options see this blogpost by Carola Steinmaier)
Customers who are using native features like camera integration for barcode scanning via SAP Fiori Client on different versions (1.90 and lower, or long term maintenance version 1.84.17 or lower) must therefore look at alternatives like QuaggaJS and ZXingJS as suggested in the Note.
Customers on SAP S/4HANA 2021 FPS0 who are currently on SAPUI5 1.90 are recommended to move to long term maintenance version 1.96 prior to go-live as discussed in SAP Note 3050199 – SAP Fiori front-end server 2021 for SAP S/4HANA and 2217489 – Maintenance and Update Strategy for SAP Fiori Front-End Server.
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
Prerequisites:
-
- Technical:
- SAP BTP Subaccount with
- Subscription to SAP Launchpad Service & Business Application Studio
- Cloud Foundry Org and Space for custom apps deployment
- SAP BTP Subaccount with
- Knowledge
- Basic SAPUI5 Programming / Business Application Studio
- (optional) SAP Launchpad Service
- Technical:
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:
- Select Template and Target Location:
- SAP Fiori application
- SAP Fiori application
- Floorplan Selection
- Application Type: SAPUI5 freestyle
- Floorplan: SAPUI5 Application
- Data Source and Service Selection:
- None
- None
- View name:
- BarcodeScanner (Or something else you prefer)
- Project Attributes:
- Provide module name and application title
(Make sure to tick “Yes” for “Add
deployment configuration” and “Add FLP
configuration”.)
- Provide module name and application title
- Deployment Configuration
- Target: Cloud Foundry
- Destination: None
- Add application to managed application router: Yes
- Fiori Launchpad Config:
- Semantic Object: barcode
- Action: scan
- Title: Barcode Scanner
- Subtitle: POC for SAP Mobile Start
- Semantic Object: barcode
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">
</Button>
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 " + oError.name), {
onClose: function () {
this._oScanDialog.close();
}.bind(this)
});
}.bind(this));
}.bind(this),
afterClose: function () {
// Dialog closed, stop Quagga
Quagga.stop();
}
});
this.getView().addDependent(this._oScanDialog);
}
this._oScanDialog.open();
},
_initQuagga: function (oTarget) {
var oDeferred = jQuery.Deferred();
// Initialise Quagga plugin - see https://serratus.github.io/quaggaJS/#configobject 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 !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { 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 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
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.
Hi Dennis,
ty for this blog. Everythings works except the SAP Mobile Start access. I was able to onboard my smartphone but i dont see any applications in the app. Do know you what could causing this? I see the UI5 app if i open the Launchpad on a desktop browser.
Any help appreciated 🙂
Best regards,
Nils
Hey Nils,
thank you for your comment and for trying to get SAP Mobile Start running!
Based on your description i'm pretty sure you were early enough to encounter a bug that is already under investigation. The "device type filtering" for apps coming from the HTML5 repository currently has still an issue. (A fix for that will arrive early October 2021)
To make it work immediately I could provide you with a workaround:
After a refresh you should be able to see the app within SAP Mobile Start as well!
Hope that works for you as well as for me!
Best regards,
Dennis
Wonderful, works like a charm
Looking forward for that fix and ty for that fast reply!
Best regards,
Nils
Hi Dennis Koehler ,
Thank you for your blog. I was just gonna ask if you also knew how to create a sapui5 mobile app without using SAP Mobile Start? Maybe the created app could be packaged as well? I found some documentations regarding MDK project, but it is not built in sapui5. I was hoping to see one that is built in sapui5 using business application studio as well.
Hey sopiken sopiken,
from my understanding would need to build your SAPUI5 app mobile responsive and launch it diractly from a browser or use SAP Mobile Start.
I'm not aware of the possibility to create native apps directly with SAPUI5.
Best regards,
Dennis
Hello Dennis Koehler,
Thanks for such a amazing blog. I just want to ask that after scanning barcode it will only give barcode number as a result or it will give all entities which barcode contains.
Best regards,
Sagar
Hi Sagar Thange ,
this depends on the used library of course.
In this case I used Quagga.js and based on the documentation there seems to be a bit more info then just the barcode number.
I would recommend to check out the Documentation here: https://serratus.github.io/quaggaJS/
If you scroll down a bit you will find a paragraph + example on the "result object".
Hope that's what you are searching for. In case Quagga.js does not fit your requirements you could try other js libraries for barcode scanning. They should be easy to find online.
Best regards,
Dennis
Hi Dennis Koehler,
I have deployed this app onpremise and cloud platform. It is working in cloud platform, but when I click on scan button in onpremise system it gives error "getUserMedia is not defined".
Best regards,
Sagar.
I did as instructed and the error occurs:
This page contains the following errors:
warning on line 3 at column 18: xmlns: URI sap.m is not absolute
error on line 7 at column 24: attributes construct error
Below is a rendering of the page up to the first error.
Hi Dennis Koehler
Will a similar approach work if opened from the browser directly, without Mobile Start? If I deploy to my On-Prem environment and open the Fiori Launchpad from a mobile web browser, would the barcode functionality work? Or Mobile Start is mandatory?
Thanks.
Jose Ruz
Hi Dennis Koehler,
Thank you for the blog. Can this be used for devices that have laser scanners for barcode scanning?
Thanks,
Joel
Hi Joel John,
the library Quagga.js which I was using in this example is relying on camera imagery and would probably not work with a laser scanner.
But you could have a look at the SAP UI5 Barcode scanner component though. I'm not an expert but the documentation states the following:
"The Barcode Scanner control integrates with the laser scanner when the page is loaded in the Enterprise Browser on a Zebra device. To enable laser scanning with a Zebra device, two JavaScript files (ebapi.js and eb.barcode.js) need to be loaded during runtime by the Enterprise Browser."
See this: https://sapui5.hana.ondemand.com/sdk/#/api/sap.ndc.BarcodeScanner
Hope that helps! 🙂
Thanks,
Dennis
Hi Dennis,
thank you for the quick response.
Unfortunately, SAP UI5 has rendering issues on the Enterprise Browser and SAP's official position is that Google Chrome is the only supported browser for Android.
SAP Mobile start could have been an option but it also uses web View and like you said, it probably will work only with the device camera. This is not always ideal for productive scenarios.
Thank you for checking though.
Regards,
Joel
Hi Joel John
by my information there have been successful POCs / Smoke Tests for Laser Scanning using SAP Mobile Start as customers have been requesting this. So it might be worth to give it a try.
I think it could be helpful to have a more detailed conversation. Maybe you could provide more detailed information on your use-case, company and the devices in use.
I'm not allowed to share my email here in the comments, but you could go to my profile and find the link to my LinkedIn, where we could exchange email-addresses to follow up on this if you want.
Thanks,
Dennis