Cordova Javascript QR Scanner Plugin not working on Android (cordova-plugin-qrscanner)

3.9k views Asked by At

I followed the documentation here.

The code under function 'qrPrep()' below runs. However, the 'qrScan01' function does not work. That's the function that should show the camera to scan the code.

Calling this from HTML as;

<button onclick="qrPrep();">QR Prepare</button>
<button onclick="qrScan01();">QR Scan</button>
<button onclick="qrShow();">QR Show</button>

This doesn't work as intended:

Here is my code:

function qrPrep() {
    //alert ('Button Clicked.');
    window.QRScanner.prepare(onDone); // show the prompt
    function onDone(err, status) {
        if (err) {
            // here we can handle errors and clean up any loose ends.
            alert('error');
            console.error(err);
        }
        if (status.authorized) {
            // W00t, you have camera access and the scanner is initialized.
            // QRscanner.show() should feel very fast.
            alert('Authorized.'); //This works.
        } else if (status.denied) {
            // The video preview will remain black, and scanning is disabled. We can
            // try to ask the user to change their mind, but we'll have to send them
            // to their device settings with `QRScanner.openSettings()`.
            alert('Denied.');
        } else {
            // we didn't get permission, but we didn't get permanently denied. (On
            // Android, a denial isn't permanent unless the user checks the "Don't
            // ask again" box.) We can ask again at the next relevant opportunity.
            alert('Not permanently denied.');
        }
    }
}

function qrScan01() {
    console.log("Button clicked.");
    QRScanner.scan(displayContents); //this does not work
    //Also tried window.QRScanner - doesn't work either.

    function displayContents(err, text) {
        console.log("Entered.");
        if (err) {
            // an error occurred, or the scan was canceled (error code `6`)
            console.log('error', err);
            alert('An error occurred.');
        } else {
            // The scan completed, display the contents of the QR code:
            console.log('text', text);
            alert(text);
        }
    }
}

function qrShow() {
    QRScanner.show(function(status) {
        console.log(status); //this only shows status like authorized: true etc.
    });
}

Here is the LOGCAT output. Looks like Camera is starting, but the app screen crashes and navigates back to /index.html:

D/CameraPreview: resume()
D/CameraInstance: Opening camera
D/CameraInstance: Configuring camera
I/CameraManager: Camera Display Orientation: 90
I/CameraManager: Initial camera parameters: preview-size=1920x1080;video-size=1920x1080;preferred-preview-size-for-video=1920x1080;
I/CameraConfiguration: Requesting focus mode value from among: [auto]
I/CameraConfiguration: Supported focus mode values: [infinity, auto, macro, continuous-video, continuous-picture]
I/CameraConfiguration: Can set focus mode to: auto
I/CameraConfiguration: Focus mode already set to auto
I/CameraConfiguration: Requesting flash mode value from among: [off]
I/CameraConfiguration: Supported flash mode values: [off, auto, on, torch, red-eye]
I/CameraConfiguration: Can set flash mode to: off
I/CameraConfiguration: Flash mode already set to off
I/PreviewScalingStrategy: Viewfinder size: 2621x1440
I/PreviewScalingStrategy: Preview in order of preference: [1920x1080, 1920x960, 1920x1440, 1280x720, 1600x1200, 1280x768, 1280x960,
I/CameraManager: Final camera parameters: video-size=1920x1080;preferred-preview-size-for-video=1920x1080;preview-size-values=1920x
I/CenterCropStrategy: Preview: 1080x1920; Scaled: 1474x2621; Want: 1440x2621
I/CameraPreview: Starting preview
D/CameraInstance: Starting preview
D/JsMessageQueue: Set native->JS mode to null
D/CordovaWebViewImpl: onPageDidNavigate(file:///android_asset/www/index.html?)
1

There are 1 answers

2
SparkFountain On

In my company, we implemented a QR scanner using the Barcode Scanner Plugin for PhoneGap. It handles several kinds of scan codes, including QR codes, and for our purposes it seemed much easier to handle than the official cordova plugin.

You can use it the following way (all code examples adapted from documentation):

package.json

{
  "name": "your-app",
  "dependencies": {
    "@ionic-native/barcode-scanner": "^5.19.1",
    "phonegap-plugin-barcodescanner": "^8.1.0",
    [...]
  },
  "cordova": {
    "plugins": {
      "phonegap-plugin-barcodescanner": {}
    }
  }
}

app.module.ts

import {BarcodeScanner} from '@ionic-native/barcode-scanner/ngx';

@NgModule({
    declarations: [AppComponent],
    entryComponents: [...],
    imports: [...],
    providers: [
        BarcodeScanner,
        QrService,  // an example service to handle QR codes; can also be omitted
        [...]
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

qr.service.ts (an example service)

import { Injectable } from '@angular/core';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BarcodeScanner, BarcodeScanResult } from '@ionic-native/barcode-scanner/ngx';

@Injectable({
    providedIn: 'root'
})
export class QrService {

    constructor(private barcodeScanner: BarcodeScanner) { }

    getQrCode$(): Observable<any> {
        return from(this.barcodeScanner.scan())
            .pipe(
                map((data: BarcodeScanResult) => {
                    const barCodeData = JSON.parse(data.text);
                    return barCodeData;
                })
            );
    }
}