QRScanner camera preview is not removed

I’ve implemented the QRScanner in my application, and for the most part, it works just fine.
When I’m done using it, I unsubscribe to the subscription and call QRScanner.hide() to hide the camera preview.

The issue occurs when I’m using NativePageTransitions with the slowdownfactor set as 2 or higher. The slide transition applies fade to the previous view. This reveals that the camera preview is still present. As can be seen in the screenshot below, when using the front facing camera, you’ll see your face gradually appearing in the background during the duration of the transition. You can also see that the next view has the QRScanner.hide() properly applied.

I’ve tried removing the QRScanner instance after I’m doing using it. This does not solve the problem. It appears that the QRScanner initiates the camera when called and leaves it at that.

How can I ensure that the camera preview is also removed when I remove the QRScanner instance?

What does it look like before the transition starts?

Do you manually set some background to transparent or does the plugin? Maybe you can set this back to white…

I manually have to set the background to transparent, when I unsubscribe from the scanner I also remove the transparency. My background is as follows:


I removed it in the example to show that QRScanner.hide() is working.

Sorry, I don’t understand the flow of your app. Can you show the screens how they appear one after another and where there is the preview and what code gets executed at which step?

It starts off with a view in which you can scan the qr code:

Simplified code:

private initiateScanner(callback)
{
    window.document.querySelector('ion-app').classList.add('transparentBody');
    window.document.querySelector('.main-background').classList.add('transparentBody');
    this.qrScanner.useFrontCamera();
    this.scanSub = this.qrScanner.scan().subscribe((result) => {
         this.unsubscribeScanner();
        callback(result);
}

 public unsubscribeScanner()
 {
     this.qrScanner.hide();
     this.scanSub.unsubscribe();
    window.document.querySelector('ion-app').classList.remove('transparentBody');
    window.document.querySelector('.main-background').classList.remove('transparentBody');
}

The unsubscribeScanner function is called whenever the view is left, in whichever way that may be.

If you don’t have a qr code, you move on to the search page:

From there, you move to the following view:

Background of the search and checkin pages are blurred versions of the live camera input?
Where exactly would the transition and bug then happen? After picture #3?

Probably should have explained that. The background is not a blurred version of live camera input. It is a static image with a blur effect on top.

.main-background
{
    @extend .background-fill;
    height:100vh;
    width: 100vw;
    filter: blur(25px);
    background-image: url($main-background);
    z-index: 1;
}

The bug occurs in all the transitions. I’ve shown the transition between images 2 and 3 as example.

Ok, that confused me a good bit :wink:

Where exactly does the transition happen? On the back button on the “Welcome Simon” #3 page that then goes back to the search page #2? And then it displays the camera preview that was on the page #1?

The transition happens when selecting one of the search results on page #2, and also when selecting back on page #3.

And yes, it displays the camera preview that was on page #1.

For example, when page #2 transitions to #3, page #3 comes sliding in from the right, overlapping page #2.
During this transition, page #2 fades away, revealing the camera preview.

image

Is it a live picture from the camera or a old state?

Did you remote debug the problem on the device already? Follow these instructions here to debug the problem in Chrome dev tools: https://ionic.zone/debug/remote-debug-your-app#android Inspect the page to see if the plugin adds a div with the image somehow or if this is really only in native code.

It’s definitely a live image, you can see yourself moving in the camera preview.

This is what the transition looks like when I don’t call the QRScanner plugin:

As you can see, here it is fading to black, no camera preview to be seen.

So my working theory: The fading is also playing with transparency. The camera preview somehow is still there, only hidden, but not removed.

As it is native very difficult to debug…

Maybe there is a function to really disable the preview?

Probably have to read the Java code of the plugin a bit…

Exactly my theory as well.
There is a destroy function documented within the plugin, but I have been unable to access it from within my application. The following is mentioned:

The show and hide methods are the fastest way to toggle visibility of the scanner. When building the scanner into tab systems and similar layouts, this makes the application feel much more responsive. It’s possible to reduce power consumption (to extend battery life on mobile platforms) by intellegently destroying the scanner when it’s unlikely to be used for a long period of time. Before scanning is used again, you can re-prepare it, making the interface seem much more responsive when show is called.

While not the ideal solution in my case (I use the scanner often enough that ‘hide’ would suffice), it will likely solve the camera preview problem I am having.

Only problem is that I can’t access the function, and I haven’t been able to figure out how to fix it in the Java code.
I’ve also tried reinstalling the plugin, to no avail.
I’m not quite adept enough to fix this yet. Any help would be very much appreciated :slight_smile:

We are talking about https://ionicframework.com/docs/native/qr-scanner/ and https://github.com/bitpay/cordova-plugin-qrscanner, right?

destroy doesn’t seem to be implemented in the Ionic Native plugin.

Docs on it are here:
https://github.com/bitpay/cordova-plugin-qrscanner#destroy

So you could a) change the Ionic Native plugin at https://github.com/ionic-team/ionic-native/blob/master/src/@ionic-native/plugins/qr-scanner/index.ts and add the destroy or b) use the function from the Cordova plugin directly: QRScanner.destroy(...). (You will have to make the QRScanner object known to your TS: declare var QRScanner: any; after your imports should be enough.

(If b) works, it would still be nice to do a) so everybody can benefit from it…)

1 Like

Jan, you are my hero of the week. Declaring and using the Cordova plugin directly allowed me to use destroy and thus solved my problem :grinning:

It also made me aware of the difference between the native qr-scanner and the cordova-plugin-qrscanner (I had thought these were one and the same). The way these two are implemented differs significantly (Cordova requires callbacks to be included in the method calls). Knowing these differences allowed me to find the fix for the ionic-native qr-scanner plugin (I’ve now switched back to using this plugin in my application). Thank you so much for your help.

And as per your suggestion, I’ve done a).

1 Like