I've followed the steps to add the QR code cordova plugin to my Ionic4/Angular/Capacitor app, but can't get it to work (in a web/pwa context, or on device on android).
After adding the cordova plugin and associated angular package/import and running 'npx capacitor sync', I can see the plugin in the list:
√ Copying capacitor.config.json in 1.91ms
Found 7 Cordova plugins for android
CordovaPluginDevice (2.0.2)
CordovaPluginFile (6.0.1)
CordovaPluginFileTransfer (1.7.1)
CordovaPluginIonic (5.2.10)
CordovaPluginQrscanner (2.6.0)
CordovaPluginWhitelist (1.3.3)
CordovaSqliteStorage (2.6.0)
√ copy in 1.48s
And my code is a copy and paste from the docs, I'm importing the QR scanner:
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
Injecting it into my angular component:
constructor(private qrScanner: QRScanner)
And I've got got a button that calls this function:
` qrScan() {
// Optionally request the permission early
this.qrScanner.prepare()
.then((status: QRScannerStatus) => {
if (status.authorized) {
// camera permission was granted
// start scanning
const scanSub = this.qrScanner.scan().subscribe((text: string) => {
console.log('Scanned something', text);
this.qrScanResult = text;
this.qrScanner.hide(); // hide camera preview
scanSub.unsubscribe(); // stop scanning
});
} else if (status.denied) {
// camera permission was permanently denied
// you must use QRScanner.openSettings() method to guide the user to the settings page
// then they can grant the permission from there
console.log('denied');
} else {
// permission was denied, but not permanently. You can ask for permission again at a later time.
}
})
.catch((e: any) => console.log('Error is', e));
}`
But after an ionic build and an npx sync, this doesn't work. Clicking the button does nothing.
In a browser with 'npx cap serve' the error is that it can't find Cordova. Do cordova plugins that support 'browser' work in a capacitor context?
With 'npx cap open android' in android studio running debug on the phone, the button also does nothing, but I'm too much of a n00b to know where error output would appear, but happy to follow instructions to give more detail.
I tried this plugin on my capacitor app but it seems that the scanner is behind the app. You had to develop a transparent view to see the scanner preview as you can see in the doc : https://github.com/bitpay/cordova-plugin-qrscanner#show
Configures the native webview to have a transparent background, then sets the background of the
and DOM elements to transparent, allowing the webview to re-render with the transparent background.
So, I installed this plugin https://github.com/phonegap/phonegap-plugin-barcodescanner.
This one is easier to use and works perfectly with capacitor 😀
window.cordova.plugins.barcodeScanner.scan(
result => console.log(result),
err => console.error(err),
{
showTorchButton: true,
prompt: "Scan your code",
formats: "QR_CODE",
resultDisplayDuration: 0
}
);
@piitaya Thanks so much for that, would never have realised that the barcode scanner had QR capability (thanks for the code sample, big help). I've tried that out and it's working on IOS and Android, so just need to figure out a fallback that works in a PWA and I'm away.
Just a note if anyone else stumbles across this, you'll need to remove the QR plugin for the barcode plugin to work.
closing with the tag known incompatible plugins
I've tried with Cordova and on Android it's not showing the camera neither.
Tested 2 different devices, one of them directly fails to find the camera and shows an error on logcat. On the other it doesn't show it, but it gets started and scan codes, but you can't see the preview.
I had the same behaviour with Capacitor on Android.
Where it's not compatible is on iOS as it try to add the camera view on the parent of the webview, but Capacitor's webview doesn't have a parent, it's on top already, so it would require some code changes on the plugin.
@jcesarmobile If this plug in is no longer compatible or working, can it be de-listed from the docs? (https://ionicframework.com/docs/native/qr-scanner#platforms). Would save people the time of going down a dead end (and raising bugs like this one).
And perhaps re-name the barcode scanner plug-in to barcode/qr scanner in the docs also.
Well, with Cordova it probably works. On Android despite it didn’t show the preview it was working, so maybe I did something wrong and missed some step to make the preview work.
Capacitor doesn’t have 100% support of Cordova plugins, so when a Cordova plugin doesn’t work it’s good to report it here so we can try to fix it. In this case it was not possible to fix it.
To add on to @piitaya's answer, these are the exact steps you need to take to get the Phonegap Barcode scanner working:
npm install phonegap-plugin-barcodescanner (you don't need the phonegap CLI for this)declare let window: any; or you'll get errors:import { Component, OnInit } from '@angular/core';
declare let window: any; // Don't forget this part!
@Component({
selector: 'app-qr',
templateUrl: './qr.component.html',
styleUrls: ['./qr.component.scss'],
})
export class QrComponent implements OnInit {
ngOnInit() {
window.cordova.plugins.barcodeScanner.scan(
result => console.log(result),
err => console.error(err),
{
showTorchButton: true,
prompt: "Scan your code",
formats: "QR_CODE",
resultDisplayDuration: 0
}
);
}
}
npx cap sync and Capacitor will take care of the rest. Example for Android:Found 1 Cordova plugin for android
phonegap-plugin-barcodescanner (8.1.0)
If you set the background as transparent, the camera will be shown.
E.g.:
import { Component, OnInit } from '@angular/core';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
@Component({
selector: 'app-checkin',
templateUrl: './checkin.page.html',
styleUrls: ['./checkin.page.scss'],
})
export class CheckinPage implements OnInit {
domElement: any;
constructor(
private qrScanner: QRScanner
) {}
ngOnInit() {
this.domElement = window.document.querySelector('ion-app') as HTMLElement;
this.prepare();
}
ionViewWillLeave() {
this.hideCamera();
}
prepare() {
this.qrScanner.prepare()
.then((status: QRScannerStatus) => {
console.log(status.authorized);
})
.catch((err) => {
console.log(err);
});
}
// Run this function.
showCamera() {
this.qrScanner.show();
this.domElement.classList.add('has-camera');
const scanSub = this.qrScanner.scan()
.subscribe((text: string) => {
scanSub.unsubscribe();
this.onScan(text);
});
}
hideCamera() {
this.qrScanner.hide();
this.domElement.classList.remove('has-camera');
}
onScan(text: string) {
this.hideCamera();
console.log('Scanned:', text);
}
}
Add this to src/global.css
ion-app.has-camera,
ion-app.has-camera ion-content {
--background: transparent;
background: transparent !important;
}
It's working fine so far.
Most helpful comment
If you set the background as transparent, the camera will be shown.
E.g.:
Add this to src/global.css
It's working fine so far.