Skip to Content
Author's profile photo Ian MacGregor

Barcode scanning with device camera in SAPUI5 applications (without a native container)

The release of iOS 11 (on September 19, 2017) has bought some good news for anyone wanting to incorporate barcode scanning into their SAPUI5 applications – support has been added to for the media capture API. This means there is now the ability to access a device camera (and microphone) directly from Safari (and all other major browsers except Opera mini – see, opening up the possibility to use barcode scanning in applications without the need for a native container (i.e. Cordova).

In this blog I will demonstrate how a device camera can be accessed within a SAPUI5 application to scan a barcode and populate the value of the barcode into an input field. This will be achieved in a plain SAPUI5 web application which can be accessed via any device that has a camera and a supported browser (we will implement a fallback solution when the application is accessed via a desktop or device with no camera). We will make use of an external JavaScript library called QuaggaJS which will handle the detection and decoding of barcodes.

What you will need

  • Some basic SAPUI5 knowledge
  • An IDE or text editor
  • The latest release of QuaggaJS library
  • Somewhere to publish your application
  • A mobile device with a camera

It is assumed that you already have (or know how to create) a UI5 project with a component, manifest, view and controller…if not, then suggest you create one via WebIDE using the “SAPUI5 Application” template.

Once you have your project, create a folder “libs” and add the QuaggaJS library  (quagga.min.js) under it.

Next, specify the resource in your manifest under sap.ui5 > resources > js (you could chose to load the library using an alternate method if preferred)

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

Add a property to the device model to track whether the device accessing our application has video capability. To check this we use method MediaDevices.getUserMedia. Calling this method will prompt the user to allow access to their camera (if the device has one)…note that it is possible to leave this check to a later time (like when the user attempts to click the scan button which is the actual point the application would like to access the camera), however we are doing it here so that the model property can be used in our view to control the visibility of the scan button.

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

Add the following controls to the view: a label, an input control to store the barcode value and a button to trigger the scanning (visible if the device is capable).

<Label text="Barcode value" />
<Input id="scannedValue" placeholder="{= ${device>/barcodeScanEnabled} ? 'Use scan button to enter barcode' : 'Enter barcode manually' }" editable="{= !${device>/barcodeScanEnabled} }" />
<Button icon="sap-icon://bar-code" text="Scan" tooltip="Scan barcode" visible="{device>/barcodeScanEnabled}" press="onScanForValue">
		<l:GridData span="L2 M2" />

Add the two methods below to the controller. The first is the event handler for our scan button press  which will create and open a dialog – the content of the dialog is a single HTML div that is used to display the video feed from the camera. We have attached a handler for the afterOpen event which will call method _initQuagga (our second controller method) to initialise Quagga and then start the video stream. For configuration options see

onScanForValue: function(oEvent){
		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){
			afterOpen			: function(){
					// Initialisation done, start Quagga
					// 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(){
			afterClose			: function(){
				// Dialog closed, stop Quagga

_initQuagga: function(oTarget){
	var oDeferred = jQuery.Deferred();
	// Initialise Quagga plugin - see for details
		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) {
		} else {
		// 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});
		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

			// Close dialog
		// Set flag so that event handlers are only attached once...
		this._oQuaggaEventHandlersAttached = true;
	return oDeferred.promise();

Final step to be able to test your application is to publish it to a location that is accessible by the device you are testing with – this could be a SAP gateway, SCP or any other web server.

A working example can be found here and the full code can be accessed here.

If you need a sample barcode to scan you can use this one or generate your own here.

Note that the code provided is configured to detect barcodes with symbology of Code 128, alternate formats can be specified in the configuration object passed to Quagga.init.

Hopefully you have found parts of this blog useful…feel free to leave any feedback or questions below.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Mike Doyle
      Mike Doyle

      Nice blog Ian, thanks for sharing. Do you know if/when support for this arrived in Android?


      Author's profile photo Ian MacGregor
      Ian MacGregor
      Blog Post Author

      Thanks Mike. It’s already supported in Android if using Android browser, Chrome, Opera (non mini version) or Firefox…other less popular browsers seem to have some support but may require tweaking 🙂

      Author's profile photo vinayaka first
      vinayaka first

      Hi Lan,

      I tested in Web IDE ,but here i am not able to see Barcode scanner via camera thru mobile device(andriod).

      I got below output ,could you please tell me how to scan barcode via camera ( Andriod device ).


      Author's profile photo Former Member
      Former Member

      Hi Lan,

      Did you solved the issue?




      Author's profile photo vinayaka first
      vinayaka first

      Author's profile photo Shashank Shrimal
      Shashank Shrimal


      Hey Lan,
      I am able to scan bar code using my laptop camera, but not with mobile or ipad.. Please suggest how can I ? App is asking to Enter bar code manually. Appreciate help.


      Author's profile photo luis andres hincapie
      luis andres hincapie

      hey blount international how are you,

      you can solve this issue, I have the same issue too.

      thanks regards...

      Author's profile photo venkatasatishreddy karri
      venkatasatishreddy karri


      I am getting "get user media is not defined" while run in tab and android. but it works on browser.

      Can u tell me how to solve the issue for  opening the camera in android and tablet.

      thanks and regards,


      Author's profile photo Wolfgang Mayer
      Wolfgang Mayer

      Hello Ian,

      do you happen to have a solution for scanning QR codes as well?




      Author's profile photo Former Member
      Former Member

      Hey need help please I have this erreur :

      Uncaught TypeError: Cannot read property 'setAttribute' of undefined

      Author's profile photo Selvakumar Mohan
      Selvakumar Mohan

      Did u solve this?

      Author's profile photo C. Ubkcah
      C. Ubkcah

      Maybe I can give some hint regarding QuaggaJS library. It won't work for you if you are using an Apple device with iOS-Version < iOS 11. The versions before don't support getUserMedia/Stream API which is necessary for the live stream scanning. Android should work though (support getUserMedia API).

      Furthermore QuaggaJS can't be used with every browser. These APIs have to be supported.

      Nevertheless I can't confirm this blog example, because I have only an iPhone 5 with iOS 10.3.3.

      You can find more information to QuaggaJS here.

      Author's profile photo Mike Doyle
      Mike Doyle

      Readers of this blog might be interesting in this site, which shows the other features available in the HTML5 API:

      It even detects which features are enabled on your browser/device



      Author's profile photo Binh Thai
      Binh Thai

      Thanks Ian for the code.

      For those concern, I have tested this app in every ways I can think of, below is the result that can save you some times:

      If you are on PC browser then you will be fine.

      If you are on Android, WP (yes Windows Phone), you will be fine too.

      If you are on iOS 11, only Safari will work. Apple only supports getUserMedia to run on their own Safari. Other browsers have to run on a controlled version of WKWebView. Earlier version of iOS won't work either. Well play, Apple!

      This is a well-known issue that you can read more using keyword "getusermedia ios chrome"

      Author's profile photo Alexandra Gherlan
      Alexandra Gherlan

      Thank you, Jan for the code.

      Maybe you can help me. I implemented exactly what you exposed and tried and it works from my iPhone.


      However, my app is deployed: under SCP accound and it doesn;t ask me if I allow my camera to be opened. It only opens the Dialog but no access to camera (neither the pop=up to allow or not as it does when I tried your app). Do you know if this is the reason? Do I need to publishe the application somewhere else?

      Thank you very much.


      Author's profile photo Kumar Gaurav
      Kumar Gaurav


      I have implemented the example by following the blog and deployed the application on launchpad.

      When I navigate back to launchpad and try to open it again, The scan dialog cannot be closed using


      I am getting error : "uncaught typeerror: cannot read property 'getopenstate' of null".


      Please suggest if any tweak in code required.



      Kumar Guarv


      Author's profile photo Narendra Reddy Lokireddy
      Narendra Reddy Lokireddy

      Very useful Blog. Thanks for sharing.

      Author's profile photo Daniel Emmenegger
      Daniel Emmenegger

      Thank you for this blog.

      The detection works well. But the border isn't shown in my example. But I use the same code as you... What could be wrong?


      Author's profile photo Prasenjit Bera
      Prasenjit Bera

      HI Ian MacGregor,

      Thank you for this blog.

      It is working fine for me, but it is working only for code 128 reader, Please help me how the other barcode type will work.