Ionic QR Code scan not opening camera for iOS and Android devices

the problem with ZBar plugin is that you can’t customize the view. So if you doesn’t need customization, i agree with you. :slight_smile:

I think that maybe create a global variable in the theme folder of the ionic team and put in the ion-content and another areas and let the variable with false by default. and then if the user needs to let the background transparent he/she can set this variable as true. And then explain this in the plugin.

Let’s see if someone can help with this issue! @shinu_neo

I got the following code:

 // more code
 <ion-content overflow-y="scroll">
     <button class="setActivePlaceButton" (click)="scanQr()">
        <ion-row>   
          <ion-col style="max-width:40px;margin-top:-8px">
          <ion-icon item-start name="qr-scanner">
            </ion-icon>
          </ion-col>
          <ion-col style="margin-top:-8px">
            Access to a place
          </ion-col> 
        </ion-row>
       </button>
         // more code

This is a side-menu, actually! I’ve got that button which triggers the function “scanQr()”, which looks like this:

   scanQr(){
    // Optionally request the permission early
    this.qrScanner.prepare()
    .then((status: QRScannerStatus) => {

    if (status.authorized) {
        // camera permission was granted
        console.log("scanning")

        // start scanning
        let scanSub = this.qrScanner.scan().subscribe((text: string) => {
        console.log('Scanned something', text);

        this.qrScanner.hide(); // hide camera preview
        scanSub.unsubscribe(); // stop scanning
        });

        // show camera preview
        window.document.querySelector('ion-app').classList.add('transparentBody')
        this.qrScanner.show();

        // wait for user to scan something, then the observable callback will be called

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


    }

It contains the fix that @laedanthehuman explained, as it tries to include the following css class:

 .transparentBody {
    background: transparent !important;
}

But it doesn’t work. I can scan QRs if I put the camera aiming towards them, but I still don’t see the camera view anywhere; I have to guess where it’s aiming.

Do I have something bad in this code?

have you tried my solution?

1 Like

Yes, and it’s not working.

Why isn’t this patched yet? It’s a major issue to me, at least.

have you implemented the transparencies in index.html which i mentioned in the post?

Yes, and it doesn’t work either, I don’t know why. Tried to add the transparencies but it keeps the same.

This is also not working for me, @Zerok were you ever able to fix your issue?

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

ion-app, ion-content and .nav-decor must all have transparent backgrounds

I put my solution in another reply

1 Like

@bensearle This work at least for iOS. Observed that on Android this element doesn’t have that background.

In the qrscanner() function you could hide the entire ionic app.

Set a pointer to your html element. The ionic app has its own custom tag ‘ion-app’. So I’m going for the getElementsByTagName method here. It is possible that there are multiple ion-app elements so this is not the best way to do this, but it is the simplest way. A better way would be to give your ion-app an id and search by id instead.

let ionApp = document.getElementsByTagName(‘ion-app’)[0];

Set its style.display to ‘none’ when launching the qrscanner (this.qrScanner.show()).

ionApp.style.display = ‘none’;

Set its style.display to ‘block’ when you scanned something (and in all catches ofcourse). I’ve manually looked up the original display style here. A better way to do this is retrieving the original style value before setting it to ‘none’. When you want to show the app you could set it to the original value.

ionApp.style.display = ‘block’;

(Tested on iOS 11 and some android version on a Galaxy Tab A 10.1)

4 Likes

Thank you @kevinbroeren! This worked with a small modification:
var ionApp = <HTMLElement>document.getElementsByTagName("ion-app")[0];

Ok, this almost worked perfectly. I can scan a qr code. I can see the camera. But I can’t see any buttons to close the camera, to cancel the action I mean. Did you not have this problem?

Yes, I have the same problem. To get around it, I added a timeout to close the camera and bring the UI back into view:

qrButtonClicked(event) {
    var context = this;
    // Optionally request the permission early
    this.qrScanner.prepare()
      .then((status: QRScannerStatus) => {

        if (status.authorized) {
          // camera permission was granted
          console.log("scanning");
          var ionApp = <HTMLElement>document.getElementsByTagName("ion-app")[0];
          // start scanning
          let scanSub = this.qrScanner.scan().subscribe((scannedAddress: string) => {
            console.log('Scanned address', scannedAddress);
            this.friendAddress = scannedAddress;
            this.qrScanner.hide(); // hide camera preview
            scanSub.unsubscribe(); // stop scanning
            ionApp.style.display = "block";
            this.friendAddressInput.setFocus();
          });

          // show camera preview
          ionApp.style.display = "none";
          context.qrScanner.show();
          setTimeout(() => {
            ionApp.style.display = "block";
            scanSub.unsubscribe(); // stop scanning
            context.friendAddressInput.setFocus();
            context.qrScanner.hide();
          }, 5000);
          // wait for user to scan something, then the observable callback will be called

        } else if (status.denied) {
          console.log("Denied permission to access camera");
        } else {
          console.log("Something else is happening with the camera");
        }
      })
      .catch((e: any) => console.log('Error is', e));
  }
4 Likes

ionApp.style.display = “block”; where to import ionApp?? ionApp.style.display=“block”!!! ionApp=> is givin error

var ionApp = <HTMLElement>document.getElementsByTagName("ion-app")[0];

By taking references from all the above points, I successfully integrated in my app, hope this will clear more about it.
Answer ref: https://github.com/bitpay/cordova-plugin-qrscanner/issues/156#issuecomment-387002328

Try with * {display: none};

Thank you @kevinbroeren, your solution works for me.

After updates I get this error back (black screen on iOS QR Code Scan) and, I finded the problem using the safari inspector. Follow the problem:

Inside ion-nav exists the nav-decor and, is this the problem! The css for nav-decor is:

.ios .ion-page.show-page ~ .nav-decor {
   left: 0;
   top: 0;
   position: absolute;
   z-index: 0;
   display: block;
   width: 100%;
   height: 100%;
   background: #000;
   pointer-events: none;
}

Following the old solution (class in body to make transparent background in inside elements), add this class in the list and the scanner show beautifully.