Ionic Angular QR Code Scanner with Cordova
The Ionic framework has shifted its native runtime from Cordova to Capacitor. But we can still create Ionic Angular projects based on Cordova.
In this article, we are going to create an Ionic Angular QR code scanning app based on Cordova using the cordova-plugin-dynamsoft-barcode-reader and the ionic wrapper.
Preview of the final result:
The app will have two pages: a home page and a scanner page. After the user touches the Scan Barcodes
button, it will navigate to the scanner page to scan barcodes and QR codes. If it finds a barcode, then return the result to the home page. The user can set the reader to read QR codes only at the home page.
Getting started with Dynamsoft Barcode Reader
Writing an Ionic Angular QR Code Scanner
Let’s do this in steps.
New Project
Use the Ionic cli tool to create a new project.
ionic start qr-code-scanner --type=angular --cordova
Add iOS and Android platforms:
ionic cordova platforms add ios
ionic cordova platforms add android
Run the app:
ionic cordova run android
ionic cordova run ios
Add Camera Permission
For iOS, add the following to its Info.plist
:
<key>NSCameraUsageDescription</key>
<string>For barcode scanning</string>
Install Dependencies
npm install cordova-plugin-dynamsoft-barcode-reader @awesome-cordova-plugins/core @awesome-cordova-plugins/dynamsoft-barcode-scanner
Create a Scanner Page and Manage Navigation
-
Generate a page named
scanner
.ionic generate page scanner
-
In
home.page.html
, add the following template:<ion-header [translucent]="true"> <ion-toolbar> <ion-title> Home </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-button expand="full" (click)="navigate()">Scan Barcodes</ion-button> <ion-list> <ion-item *ngFor="let entry of scanOptions"> <ion-label>{{entry.val}}</ion-label> <ion-checkbox slot="end" [(ngModel)]="entry.isChecked"></ion-checkbox> </ion-item> <ion-item *ngFor="let result of barcodeResults"> <ion-label>{{result.barcodeFormat + ": " + result.barcodeText}}</ion-label> </ion-item> </ion-list> </ion-content>
-
In
home.page.ts
, add ascanOptions
property.public scanOptions = [ { val: 'Scan QR Code Only', isChecked: false } ];
-
In
home.page.ts
, add anavigate
function which navigates to the scanner page.navigate(){ let qrcodeonly = this.scanOptions[0].isChecked; this.router.navigate(['/scanner'],{ state: { qrcodeonly: qrcodeonly } }); }
-
In
home.page.ts
, add anionViewWillEnter
lifecycle hook to check whether there are barcodes found and update thebarcodeResults
property. The HTML will be updated if the property is updated.ionViewWillEnter(){ if (history.state.barcodeResults) { this.barcodeResults = history.state.barcodeResults; } }
-
In
scanner.page.ts
, add the following tongOnInit
to check the navigation with a dummy barcode result.ngOnInit() { let dummyBarcodeResult:BarcodeResult; dummyBarcodeResult = { barcodeFormat:"QR_CODE", barcodeText:"Dynamsoft", barcodeBytesBase64:"base64", x1:0, x2:0, x3:0, x4:0, y1:0, y2:0, y3:0, y4:0 } this.router.navigate(['/home'],{ state: { barcodeResults:[dummyBarcodeResult] } }); }
Create a Barcode Scanner Component
We need to create a barcode scanner component to use in the scanner page.
-
Run the following command to create the component:
ionic generate component BarcodeScanner
-
Initialize Dynamsoft Barcode Reader with a license in the
ngOnInit
hook.import { BarcodeScanner as DBR, FrameResult } from '@awesome-cordova-plugins/dynamsoft-barcode-scanner/'; @Input() license?:string async ngOnInit():Promise<void> { if (!this.license) { this.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; } let result = await DBR.init(this.license); }
You can apply for a trial license here.
-
Update the runtime settings in the
ngOnInit
hook as well:@Input() runtimeSettings:string; async ngOnInit():Promise<void> { if (this.runtimeSettings) { DBR.initRuntimeSettingsWithString(this.runtimeSettings); } }
We can modify the runtime settings of Dynamsoft Barcode Reader with a JSON template. For example, the following template specifies the barcode format to QR code:
{"ImageParameter":{"BarcodeFormatIds":["BF_QR_CODE"],"Description":"","Name":"Settings"},"Version":"3.0"}
You can learn about the runtime settings by checkout the docs.
-
Add an
isActive
property. When it is set to true, start scanning. Otherwise, stop scanning.private _isActive: boolean; onFrameRead = new EventEmitter<FrameResult>(); @Input() set isActive(isActive: boolean) { this._isActive= isActive; if (isActive === true) { DBR.startScanning({dceLicense:this.license}).subscribe((result:FrameResult) => { if (this.onFrameRead) { this.onFrameRead.emit(result); } }); }else{ console.log("stop scanning"); DBR.stopScanning(); } } get isActive(): boolean{ return this._isActive; }
The barcode results will be sent to the component’s parent through an
EventEmitter
. -
Add a
torchOn
property. When it is set to true, turn on torch. Otherwise, turn off torch.@Input() set torchOn(torchOn: boolean) { this._torchOn= torchOn; if (torchOn === true) { DBR.switchTorch("on"); }else{ DBR.switchTorch("off"); } } get torchOn(): boolean{ return this._torchOn; }
Add the Barcode Scanner Component to the Scanner Page
-
In
scanner.page.html
, add the following template:<app-barcode-scanner [isActive] = "isActive" [runtimeSettings] = "runtimeSettings" [torchOn] = "torchOn" (onFrameRead)="onFrameRead($event)"> </app-barcode-scanner>
-
In
scanner.module.ts
, add the component declaration:@NgModule({ imports: [ CommonModule, FormsModule, IonicModule, ScannerPageRoutingModule ], declarations: [ ScannerPage, + BarcodeScannerComponent ] })
-
Switch to
scanner.page.ts
, in theconstructor
, update the runtime settings based on the user’s selection of whether to scan QR codes only in the home page.isActive: boolean; qrcodeonly: boolean; torchOn: boolean; runtimeSettings: string; constructor(private router: Router) { if (this.router.getCurrentNavigation().extras.state) { const routeState = this.router.getCurrentNavigation().extras.state; if (routeState) { this.qrcodeonly = routeState.qrcodeonly; } } if (this.qrcodeonly === true) { this.runtimeSettings = "{\"ImageParameter\":{\"BarcodeFormatIds\":[\"BF_QR_CODE\"],\"Description\":\"\",\"Name\":\"Settings\"},\"Version\":\"3.0\"}"; }else{ this.runtimeSettings = "{\"ImageParameter\":{\"BarcodeFormatIds\":[\"BF_ALL\"],\"Description\":\"\",\"Name\":\"Settings\"},\"Version\":\"3.0\"}"; } this.isActive = true; //set initial values this.torchOn = false; }
-
Add an
onFrameRead
function to receive the barcode reading result.onFrameRead(frameResult:FrameResult) { if (frameResult.results.length>0) { this.isActive = false; this.torchOn = false; this.router.navigate(['/home'],{ state: { barcodeResults:frameResult.results } }); } }
If there are barcodes found, stop scanning and return to the home page.
Add a Floating Action Button to the Scanner Page
In order to let the user turn on/off the torch and close the scanner page, we can add a floating action button.
-
In
scanner.page.html
, add the following template:<ion-fab vertical="bottom" horizontal="start" slot="fixed"> <ion-fab-button> <ion-icon name="ellipsis-horizontal-outline"></ion-icon> </ion-fab-button> <ion-fab-list side="top"> <ion-fab-button (click)="toggleTorch()"> <ion-icon name="flashlight-outline"></ion-icon> </ion-fab-button> <ion-fab-button (click)="close()"> <ion-icon name="close-outline"></ion-icon> </ion-fab-button> </ion-fab-list> </ion-fab>
-
Add equivalent functions:
close(){ this.isActive = false; this.torchOn = false; this.router.navigate(['/home'],{ state: { barcodeResults:[] } }); } toggleTorch(){ this.torchOn = !this.torchOn; }
All right, we have now completed the Ionic angular QR code scanner.
Source Code
Check out the source code to have a try.
https://github.com/xulihang/Ionic-Angular-Cordova-Barcode-Scanner