bitpay / cordova-plugin-qrscanner

A fast, energy efficient, highly-configurable QR code scanner for Cordova apps and the browser.
MIT License
568 stars 772 forks source link

How to make this plugin work with Ionic/angularjs? #18

Closed MilesYM closed 7 years ago

MilesYM commented 7 years ago

I’m using Ionic/angular for my cordova app and the default barcodescanner plugin is shit. (Waaayyyyyyyyyy too slow). Looking to integrate this scanner but can’t find the right way to do it.

Can anyone gimme a clue please ?

Thanks!

bitjson commented 7 years ago

You should be able to immediately start using the plugin after installing. See the installation instructions in the readme, and the usage here: https://github.com/bitpay/cordova-plugin-qrscanner#usage.

If you have trouble, consider trying the tests to get a feel for the usage: https://github.com/bitpay/cordova-plugin-qrscanner#contributing--testing

MilesYM commented 7 years ago

Thank you very much for your prompt answer, this is impressive!

To give you a bit more details. I’ve followed the usage tutorial.

But then, when calling for the QRScanner object, nothing happen. (It cannot find the QRScanner Object)

Looking at the console, I noticed i have the following error: ReferenceError: Can't find variable: module this comes from the last line of the code.

I’ve been trying to wrap it up in a document.addEventListener("deviceready", onDeviceReady, false); at the beggining of the file and wrapped your code into onDevice Ready. But no luck.

How should I do?

Thank you!

MilesYM commented 7 years ago

Looking at the code, I have no idea where the module is coming from. Can’t see it declared. Any clue?

Thanks!

EDIT:

The module is coming from swift-support.js , still investigating why this is not loading properly with Ionic/AngularJS

bitjson commented 7 years ago

No problem, happy to help if I can.

By the time the deviceready event propagates, this plugin should have instantiated an object on the window element called QRScanner. You can confirm this plugin is working properly by opening the javascript console and running something like QRScanner.scan(). Can you confirm that command works?

Also, what device(s) are you testing on?

Once you've confirmed that object exists, debugging might be a bit easier (and mostly an Angular question).

MilesYM commented 7 years ago

Thank you so much BitJson!

Ok so I made little bit of progress here.

For those using Ionic here is what I was doing wrong:

I was trying to load the QRScanner.js file myself as a service on AngularJS (in index.html). That wasn’t the right way to do it. Just don’t do anything, it will load by itself.

Now that being said, I can access the QRScanner object but ....

When doing the following: QRScanner.prepare(onDone)

It never trigger the authorization. Here is what I’m getting in the console: [Log] auth? (list.js, line 146) [Log] null (list.js, line 147) [Log] Error in Success callbackId: QRScanner1853486761 : TypeError: null is not an object (evaluating 'status.authorized') (cordova.js, line 299)

Here is my code:

function onDone(status){
      console.log('auth?’);
      console.log(status);
            if (status.authorized) {
        console.log('auth’);
        // W00t, you have camera access and the scanner is initialized.
             } else {
                // 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().
                console.log('nope’);
            }
        }
$ionicPlatform.ready(function()
{
    console.log('RDY');

        $timeout(function() {
            QRScanner.prepare(onDone); // prompt for access
        }, 5000);
});`

So basically, the status object returned to the onDone method is null. So it seems that when doing QRScanner.prepare(onDone) the plugin itself doesn’t get an object. It returns null.

Trying QRScanner.scan() on the console log would lead to Error: No callback provided to scan method. Also, when triggering the QRScanner.show() and QRScanner.scan(displayContents); methods, nothing happen.

I’m using an iPad Mini 1 with iOS 9.2.1

EDIT: I’m using Crosswalk

Thanks!

bitjson commented 7 years ago

Ah – there's actually an issue with the example usage – both the prepare and scan methods actually take two parameters, the first accepts errors. I'll make a pull request to improve that example, something like:

// For the best user experience, make sure the user is ready to give your app
// camera access before you issue the prompt.

QRScanner.prepare(onDone); // prompt for access

function onDone(err, status){
  if (err) {
   // here we can handle errors and clean up any loose ends.
   console.error(err);
  }
  if (status.authorized) {
    // W00t, you have camera access and the scanner is initialized.
  } 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()`.
  } else {
    // we didn't get permission, but we didn't get denied. (On Android, a denial
    // isn't permanent unless the user checks the "Don't ask again" box.)
  }
}

// ...
// Later in your app, when you're ready to show the video preview:

// Make the webview transparent so the video preview is visible behind it.
// (Not required for scanning to work on iOS.)
QRScanner.show();
// Be sure to make any opaque HTML elements transparent here to avoid 
// covering the video. 

// Start a scan. Scanning will continue until something is detected or
// `QRScanner.cancelScan()` is called.
QRScanner.scan(displayContents);

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

Thanks for bringing it to my attention!

If after making that change you're still having trouble seeing the video preview, try inspecting the DOM and individually modifying each HTML element's background to something like rgba(0,0,0,0.1). It's likely the video preview is being covered up by a background.

bitjson commented 7 years ago

Updating that usage example here: https://github.com/bitpay/cordova-plugin-qrscanner/pull/19

MilesYM commented 7 years ago

Thanks for your example.

Unfortunately, it’s still not working. I’ve integrated your new piece of code. But nothing is showing up. If the camera access has been granted (from the settings option), then I get [Log] {authorized: true, denied: false, restricted: false, prepared: true, scanning: false, …} (list.js, line 247) but if I reinstall the app and try again, it doesn’t trigger anything (the app/plugin does not ask to grant permission to access the camera) and the log says it’s been denied.

Even when accepted, I do not have access to the QR Code Scanner if I trigger the scan method.

Not sure what to do from here ..

Any help would be much appreciated!

Thanks!

bitjson commented 7 years ago

Hey @MilesYM – could you provide sample code? Is your app on github somewhere?

Is QRScanner.openSettings() working if you run it from the javascript console?

Have you confirmed the preview is not being covered over by an HTML element? Particularly with Ionic apps, you'll need to make some changes to Ionic's base styling to allow the video preview to be visible.

Particularly on iOS, once you've allowed or denied access to the camera for an app, even re-installing the app won't necessarily allow you to display the permission dialog again. Try opening your app in XCode and changing the Bundle Identifier to test the permissions again.

NicRoy commented 7 years ago

Hi @MilesYM,

I started using this great plugin 2 days ago, testing on Ipad and Sony Xperia (Android Lollipop). I have read this thread with deep interest. (I faced at first the same NULL status as you, because of the "err" parameter and this thread helped much).

After that, as scan was working as a charm on ipad, I kept having a black video on the Sony Xperia (whereas both devices had correct authorizations to access camera).

Problem was in my code, and maybe in yours. If you look at the provided sample by @bitjson above, you'll notice that QRScanner.show() and QRScanner.scan() may be called before QRScanner.prepare() is finished (asynchronous callback). There must be some kind of authorization object populated too late if you call QRScanner.prepare() and QRScanner.show()+QRScanner.scan() in a row.

Solved by calling QRScanner.show() and QRScanner.scan() inside of the onDone callback of QRScanner.prepare().

Now everything works perfectly.

Hope this may help. Good day !

rocketman-21 commented 7 years ago

Glad it's working for you on android @NicRoy How is the scanning speed on your Sony Xperia? I'm testing on a few older android phones and sometimes it can take a second or two before the scan result is returned. By contrast, the iOS version is almost instant in all my tests. I was wondering if you are having this same speed issue?

NicRoy commented 7 years ago

Hi @willhay, really unnoticeable delay (to not say 'zero') on the Sony Xperia (M4 aqua dual). Ditto on ipad 3. Ditto on Wiko rainbow lite. Speed may depend on QRcode size ? (using small one for testing, i.e. : http://cdn4.explainthatstuff.com/qr-code-barcode-example-ets.png).

rocketman-21 commented 7 years ago

@NicRoy Good to hear. I think it could be that I just never center the qr-code properly in the camera view. Seems to only scan if the qr-code is in the middle of the camera preview. I opened an issue about it. https://github.com/bitpay/cordova-plugin-qrscanner/issues/17 Would you mind trying to scan by placing the qr-code in the upper corner of the camera preview and tell me if it scans correctly? Thanks!

bitjson commented 7 years ago

Hey @MilesYM – were you able to get it working? The readme has been updated to make this more clear, so I think we're good to close this issue.

bitjson commented 7 years ago

@NicRoy – thanks for the explanation of the issue you had above. I rewrote the Get Started section of the readme a bit based on your experience (https://github.com/bitpay/cordova-plugin-qrscanner/commit/d083b9a2645684d9cc4800bfd5fd490aabb136cb), hopefully this will help avoid issues like that in the future.

I'm going to close this issue for now, but please feel free to post here if you have any further questions or feedback!

jacobgus commented 7 years ago

Hey there, I have implemented the code, no errors anywhere and looks identicle to many tutorials ive seen but when i got to export it to my iphone via both xcode and through ionic i cant get the camera to come up. Any ideas?

bitjson commented 7 years ago

Hey @jacobgus – what does QRScanner.getStatus() report if you run it in the console? Are you sure your app's background is not covering over the video preview?

jacobgus commented 7 years ago

Found the issue, hiring a guy to fix it for me worked like a charm ;P

rodrigograca31 commented 5 years ago

@jacobgus I have the same bug as you, dont see the camera ..... what have you done to solve this?

@bitjson my QRScanner.getStatus() output:

authorized: true
canChangeCamera: true
canEnableLight: true
canOpenSettings: true
currentCamera: 0
denied: false
lightEnabled: false
prepared: true
previewing: true
restricted: false
scanning: false
showing: true
rodrigograca31 commented 5 years ago

I've found my problem! The camera is behind the webview! So we have to set all backgrounds to transparent to view the camera!