Zxing.net.mobile: ZXingScannerView IsScanning does not behave as expected

Created on 18 Apr 2018  路  5Comments  路  Source: Redth/ZXing.Net.Mobile

The IsScanning property on the ZXingScannerView does not behave as expected.

After experiencing issues where we could not scan more than once after toggling both IsScanning and IsAnalyzing, i took a quick look in the rendering code and discovered that the only difference between setting them to true is that IsScanning also sets the ScanningOptions, and the BarcodeFound handler, then they both call _cameraAnalyzer.ResumeAnalysis();

However when you toggle them both to false, the behaviour is a lot different:
IsAnalyzing --> this simply calls _cameraAnalyzer.PauseAnalysis();
IsScanning --> this calls _cameraAnalyzer.ShutdownCamera();

I would expect IsScanning to only delete the scanningOptions and remove the handler when toggled to false, or to redo the camera setup when toggled to true.

Most helpful comment

I have the same problem with version 3.0.0-beta5. @Redth
Do you plan to push an update for this soon?

All 5 comments

I am experiencing this issue from a slightly different perspective (and it only affects Android apps).

In the Xamarin.Forms sample, IsScanning is set true in the scanning page's OnAppearing method and set false in OnDisappearing, which seems reasonable.

If the sample app is modified such that a nested page is pushed onto the navigation stack, the scanning page's OnDisappearing will execute, causing camera capture to be suspended while the nested page is visible. When the nested page is popped from the stack, the scanning page's OnAppearing method will again execute, which should restart camera capture. However, since IsScanning is broken, camera capture never restarts, which means that it is not possible to navigate away from and return to a barcode scanning page without stalling the scanning operation.

After digging deeper into the code, it seems that the problem is a mismatch between the effects of the StartScanning() and StopScanning() methods of ZXing.Mobile.ZXingSurfaceView.

Since theses methods are triggered by toggling the setting of the ZXingScannerView.IsScanning property, I would expect them to be equal and opposite in their effects, but they are not.

StopScanning() fully stops and cleans up camera capture but StartScanning() simply restarts a previously initialized capture session, making the assumption that all the necessary setup has already been done. This assumption fails when the containing page disappears and then reappears, since all the camera setup is discarded when StopScanning() is triggered by the page's OnDisappearing() method.

I have worked around the problem by creating a custom renderer for ZXingScannerView, which in turn uses a custom implementation of ZXingSurfaceView, based on the original code, but with the following custom implementations of StartScanning() and StopScanning():

private Action<Result> _scanResultCallback;

public void StartScanning(Action<Result> scanResultCallback, MobileBarcodeScanningOptions options = null)
{
    _scanResultCallback = scanResultCallback;
    ScanningOptions = options ?? MobileBarcodeScanningOptions.Default;
    _cameraAnalyzer.BarcodeFound += OnScanResult;
    _cameraAnalyzer.SetupCamera();
    _cameraAnalyzer.ResumeAnalysis();
}

private void OnScanResult(object sender, Result result)
{
    _scanResultCallback?.Invoke(result);
}

public void StopScanning()
{
    _cameraAnalyzer.BarcodeFound -= OnScanResult;
    _cameraAnalyzer.ShutdownCamera();
}

I suspect the above problem is also the cause of Issue #712, although I have not tested this.

@aquisio can you share the full code of the custom renderer please?

This should behave better in the 3.0 series. Please open a new issue if there are other problems with it on that version, thanks.

I have the same problem with version 3.0.0-beta5. @Redth
Do you plan to push an update for this soon?

Was this page helpful?
0 / 5 - 0 ratings