QR Scanner: Seems to be working in the background, but doesn't display a preview when calling show()

The QR Scanner seems to be working in the background but doesn’t display a preview when calling show().
The code for the QR Scanner is a copy/paste from the example in the docs.

When moving the phone around over a QR code I will eventually get the following message in the console ( ‘qrcodetext’ is correct).

error opening ws message: {"category":"console","type":"log","data":["Scanned something","qrcodetext"]} 

ionic info output:

$ ionic info

global packages:

    @ionic/cli-utils : 1.5.0
    Cordova CLI      : 7.0.1 
    Ionic CLI        : 3.5.0

local packages:

    @ionic/app-scripts              : 2.0.2
    @ionic/cli-plugin-cordova       : 1.4.1
    @ionic/cli-plugin-ionic-angular : 1.3.2
    Cordova Platforms               : android 6.2.3 ios 4.4.0
    Ionic Framework                 : ionic-angular 3.5.3

System:

    Node       : v6.11.1
    OS         : OS X El Capitan
    Xcode      : Xcode 8.1 Build version 8B62 
    ios-deploy : not installed
    ios-sim    : not installed
    npm        : 3.10.10 

Can you build a simple repro repo on a ionic start blank blank project and put it on Github?

I actually just got this figured out after tinkering with things in Chrome’s Webview Debugger.

In top level index.html:

<!-- Ionic's root component and where the app will load -->
<ion-app style="background: none transparent;"></ion-app>

In camera display page html file:

<ion-content style="background: none transparent;">

What does that do exactly? What are the default values?

Both changes override the styling from the default Ionic style sheet. Without the changes, the camera preview runs underneath the app and isn’t visible.

The default is a white background, from main.css:5481:

ion-app.md {
    font-family: "Roboto", "Helvetica Neue", sans-serif;
    font-size: 1.4rem;
    background-color: #fff;
}

and from main.css:8617:

.content-md {
    color: #000;
    background-color: #fff;
}
2 Likes

There is a div, with class=“nav-decor”, which has a black background, this needs to be changed to transparent.

My solution was to have a “cameraView” class, which would set the ion-app, ion-content and .nav-decor to have a transparent background.

I used this CSS

ion-app.cameraView, ion-app.cameraView ion-content, ion-app.cameraView .nav-decor {
  background: transparent none !important; 
}

And then these functions to show the camera after qrScanner.show() and hide it after I’m finished scanning

showCamera() {    
  (window.document.querySelector('ion-app') as HTMLElement).classList.add('cameraView');
}
hideCamera() {    
  (window.document.querySelector('ion-app') as HTMLElement).classList.remove('cameraView');
}
4 Likes

you saved my god damn booty! this nav-decor appeared for me when i used ion-tabs. Before i used them, the qr-scanner just worked like @markmccarthy described.

I think “bensearle”'s answer should add to official doc (https://ionicframework.com/docs/native/qr-scanner/).
Great help.

The is one simple and way better solution: Use BarcodeScanner Plugin. Does the same stuff, easier and better.

But you cannot place it inside the page =x

Where should i add the css in main.css or in page.css ?

It is up to you.
In my case, I will create a scanner page to handle all scan process.
So, css will put inside scanner.scss.

I am trying to make it work in ionic v4.

SCSS put in global.scss can change to below:

ion-app.cameraView ion-content{
  --background: transparent none !important;
}

But the transparent background only active after first success scan.
Do u know what I need to do to give it work?

Make sure you are add the cameraView css class at the same time you call this.qrScanner.show();

And only remove it when you call this.qrScanner.hide();

More information on how I implemented it can be found here: https://softwarb.blog/ionic-qr-scanner/

did u manage to solve it. I am trying to acheive in ionc 4 but facing same problem

working on my ionic 4 project:

add to global.scss

ion-app.cameraView ion-content{
  --background: transparent none !important;
}

When start scan:

(window.document.querySelector('ion-app') as HTMLElement).classList.add('cameraView');
window.document.body.style.backgroundColor = 'transparent';

When stop scan:

(window.document.querySelector('ion-app') as HTMLElement).classList.remove('cameraView');
window.document.body.style.backgroundColor = '#FFF';

thanks for your solution which works correctly in ionic 4.

However
window.document.body.style.backgroundColor = '#FFF'
seems like not doing their job.

After qr code scanner is activated and destroyed, dragging of ion-refresher will show gray/transparent background color instead of white. Anyone can help with this?

I want to implement this in my ionic 5 project. it is asking for camera access but after that whitte blanck screen is coming. kindly help me

I’m using react with Ionic 5 and this is working (I have to put the show() call):

const qrScanner: QRScanner = new QRScanner();

  const preview = (show: boolean): void => {
    if (show) {
      (window.document.querySelector("ion-app") as HTMLElement).classList.add("cameraView");
      window.document.body.style.backgroundColor = "transparent";
    } else {
      (window.document.querySelector("ion-app") as HTMLElement).classList.remove("cameraView");
      window.document.body.style.backgroundColor = '#FFF';
    }
  }

  qrScanner.prepare()
    .then((status: QRScannerStatus) => {
      if (status.authorized) {
        preview(true);
        // camera permission was granted
        qrScanner.show();
        // start scanning
        let scanSub = qrScanner.scan().subscribe((text: string) => {
          preview(false);
          console.log("Scanned something", text);

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

And the style is:

ion-app.cameraView,
ion-app.cameraView ion-content,
ion-app.cameraView .nav-decor {
  background: transparent none !important;
  --background: transparent none !important;
}