ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️
https://capacitorjs.com
MIT License
11.76k stars 993 forks source link

QR Code scanner cordova plugin not working on android with capacitor #1213

Closed coffeymatt closed 5 years ago

coffeymatt commented 5 years ago

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.

piitaya commented 5 years ago

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
  }
);
coffeymatt commented 5 years ago

@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.

jcesarmobile commented 5 years ago

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.

coffeymatt commented 5 years ago

@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.

jcesarmobile commented 5 years ago

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.

dennisameling commented 4 years ago

To add on to @piitaya's answer, these are the exact steps you need to take to get the Phonegap Barcode scanner working:

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
      }
    );
  }

}
felipemarcos commented 4 years ago

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.

riderx commented 3 years ago

@FelipeMarcos thanks for the code, i tried but it look parent component are not updated, do you know how to do it in angular 11 ?

ionitron-bot[bot] commented 1 year ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.