juliansteenbakker / mobile_scanner

A universal scanner for Flutter based on MLKit. Uses CameraX on Android and AVFoundation on iOS.
BSD 3-Clause "New" or "Revised" License
889 stars 513 forks source link

If the MobileScannerController is created with autoStart=false, onDetect() will never be called #556

Closed coderaper closed 1 year ago

coderaper commented 1 year ago

First of all, I would like to take this opportunity to thank you for the time and effort you have put into creating this nice package. Since this is a fairly new library, there are still some rough edges. Here is the problem I encounter when trying to use it.

There is no information in the documentation about the meaning of the start() and stop() functions of the MobileScannerController. I assume that they only start and stop the image stream of the camera, but not the operation of the barcode reader.

How to reproduce: create MobileScannerController, but disable autoStart:

  static bool _autoStart = false;

  bool isStarted = _autoStart;

  controller = MobileScannerController(
    torchEnabled: false,
    // formats: [BarcodeFormat.qrCode]
    // facing: CameraFacing.front,
    // detectionSpeed: DetectionSpeed.normal
    // detectionTimeoutMs: 1000,
    // returnImage: false,
    autoStart: _autoStart,
  );

Call analyzeImage(), with image containing barcode. The call returns true but onDetect() is not called.

Call start() to start the MobileScanner and again call analyzeImage() with image containing barcode. The call returns true but onDetect() is still not called.

Call stop() to stop again the MobileScanner again and call analyzeImage() with an image containing a barcode. The call will return true, but onDetect() will still not be called.

Call start() to start the MobileScanner and point the camera at a known to be recognized barcode. Again, onDetect() is also not called.

This means that if the MobileScannerController is instantiated with autoStart=false, than onDetect() will never be called.

Expected behaviour: If analyzeImage() returns true, than onDetect() will be called with the corresponding BarcodeCapture result. If stop() stops also the recognizer, than calls to analyzeImage() should throw a 'Not started' exception.

Rqmco commented 1 year ago

Hello, this issue is fixed in the latest version, to fix it switch to the latest version by changing to mobile_scanner: ^3.1.1 in pubspec.yaml

coderaper commented 1 year ago

In my current project I was already using version 3.3.1, but when I have ran into this problem I went back to the original example to see if I could reproduce the problem there. Unfortunately I forgot to do a git pull, so I was actually using a version from March 1st and not the 3.3.1.

I have now re-tested this with 3.3.1 and I have found that this issue is largely fixed. Now the onDetect() is not called only if the camera start has never been issued before.

How to reproduce:

Create MobileScannerController, but disable autoStart.

Call analyzeImage() with image containing barcode. The call returns true but onDetect() is not called.

Call start() to start the camera. The camera should not be pointing at a barcode at this time. Surprisingly, the onDetect() is called with the barcode from the previous call to analyzeImage(). (If multiple analyzeImage() calls were made before the start() call, then onDetect() would only return the result for the last image.)

Call stop() to stop the camera again and call analyzeImage() with an image containing a barcode. This time the call will returns true and onDetect() is called as expected.

The conclusion is that if the MobileScannerController is instantiated with autoStart=false, then onDetect() will not work until the camera is started. Once the camera is started onDetect() will work as expected, regardless of the current camera state.

Expected behaviour: If analyzeImage() returns true, than onDetect() will be called even if the camera has never been started.