JimmyPun610 / BarcodeScanner.Mobile

Barcode Scanner using GoogleVision API for Xamarin Form, Maui
MIT License
340 stars 100 forks source link

Code decoding stops to work after some time #105

Open energywave opened 2 years ago

energywave commented 2 years ago

I have a Xamarin Forms project that run just on Android where on the main page I have the CameraView control nearly fullscreen. I'm using the latest 6.2.0-pre version from NuGet to read only QRCode with an init code like that:

Methods.SetSupportBarcodeFormat(BarcodeFormats.QRCode);
Camera.CameraFacing = Config.Instance.CameraFront ? CameraFacing.Front : CameraFacing.Back;
Camera.CaptureQuality = Config.Instance.CameraQuality;

As default I'm using 640x480 as camera quality and the decoding of qr codes works very well, until... it stops working at all! It works ok for 3, 4, 5 codes or maybe for 50, it's variable, sometimes it works for long time, sometimes for just some reads. After that the control is correctly showing camera preview but when you place a qr code in face of camera nothing happens. :( This is NOT recovering from the situation:

Camera.IsScanning = false;
Camera.IsScanning = true;

The principle of my app is quite simple: it stay there to find a code and when it do (OnDetected event) I process it and show a modal form telling a message (simplified), returning to the main page with CameraView. When I show the modal form I suspend decoding using IsScanning = false. So the decoding is active for the majority of time.

The worse part of the problem is that I don't have a way to understand, from my code, this is happening. So, even if there is workaround, when to do it? But, clearly, a workaround could be a half solution, I could provide a button to "recover" the scanning, even if that would be very ugly.

Please if you have thoughts or something to suggest/point me to I would be grateful.

JimmyPun610 commented 2 years ago

Hi @energywave ,

Could you provide the sample project and step to reproduce the error?

energywave commented 2 years ago

I'll prepare a sample project removing all the peculiarities of my app. I'll test in the hope it will behave the same (the hope is that the problem is reproducible so that it can be fixed easily). But the behavior is quite random. Sometimes no problem and it works flawlessly for hours, sometimes the decoding stops working after three decodings. I'll update the issue as soon as I can do it.

JimmyPun610 commented 2 years ago

Hi @energywave ,

Just want to know if there is any chance that there is an error occur on your app logic before you setting the IsScanning to true again?

energywave commented 2 years ago

Just want to know if there is any chance that there is an error occur on your app logic before you setting the IsScanning to true again?

Hm, that's a good point. I think not because I'm suspending IsScanning in two cases: a modal page i shown (for some seconds) and on return I await the navigation pop method to set IsScanning = true. The other is another page on the stack shown to disable barcode readings and, even there, I await the navigation pop method to set IsScanning = true. I'm using Microsoft AppCenter and I've never seen crashes that could lead to this problem so I tend to exclude it. But I hope tomorrow to have time to dedicate to this specific matter and create a demo project, hoping that I can simulate the problem there. I hope that, because if not then there could be some strange interaction with other components I'm using... I'll put some Debug.Write here and there to understand if IsScanning is correctly reset/set to better tell you. From what I've seen at first time that happened during a debug session I could remember that IsScanning was true but the OnDetected event never fired. But again, please wait that I'll accurately check to give you better data. In the meanwhile thank you very much, this project rocks, if this problem is solved it's so much better than zxing... :)

energywave commented 2 years ago

Sorry that I didn't had time (yet) to create a sample project. I was using Visual Studio 2022 preview (latest version), I've now switched to Visual Studio 2022 non preview to see if I improve stability, targeting Android 12. I've seen the app that closed without an error (not in the log, not in Microsoft AppCenter), thus was not originated from .net code, I suppose. The only component that use non .net code is this component so I assume the error arrives from here. I could luckily replicate it (don't know how, maybe by restoring the app that was not open) in my developing environment so I've got an error in my output view in Visual Studio as follow: [libc] Fatal signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0x73f28d4b in tid 6647 (Thread Pool Wor), pid 6526 (my app name) I don't know if that can be of any help... EDIT: The error was with 6.2.0.0-pre, I've just updated to 6.2.1.5-pre to see if that's working better.

claesl commented 2 years ago

I have the same problem on Android. Continuous scan with an interval of 500ms is getting a null ref exception in CameraViewRenderer line 299 _renderer.Element.IsScanning = false; and the setter in CameraView.cs line 99 as seen below in the Stacktrace

Object reference not set to an instance of an object.

at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00199] in D:\a_work\1\s\Xamarin.Forms.Core\BindableObject.cs:454 at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0004d] in D:\a_work\1\s\Xamarin.Forms.Core\BindableObject.cs:374 at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in D:\a_work\1\s\Xamarin.Forms.Core\BindableObject.cs:349 at GoogleVisionBarCodeScanner.CameraView.set_IsScanning (System.Boolean value) [0x00000] in /Users/claesl/Projects/MyApp/BarcodeScanner.XF/GoogleVisionBarCodeScanner/Shared/CameraView.cs:99 at GoogleVisionBarCodeScanner.Renderer.CameraViewRenderer+BarcodeAnalyzer.Analyze (AndroidX.Camera.Core.IImageProxy proxy) [0x002a5] in /Users/claesl/Projects/MyApp/BarcodeScanner.XF/GoogleVisionBarCodeScanner/Android/Renderer/CameraViewRenderer.cs:299

I moved IsScanning = false to CameraView.cs

public void TriggerOnDetected(List<BarcodeResult> barCodeResults)
{
    MainThread.BeginInvokeOnMainThread(() =>
    {
        IsScanning = false;
        OnDetected?.Invoke(this, new OnDetectedEventArg { BarcodeResults = barCodeResults });
        OnDetectedCommand?.Execute( new OnDetectedEventArg { BarcodeResults = barCodeResults });
    });
}

Now the problem is gone. I never had the error on iOS. Could be that the CameraViewRenderer on iOS is not settings IsScanning to false. Should it be reset here or in the Event/Command?

istanko commented 2 years ago

Hi,

In my case this is happening when proxy?.Close(); in SafeCloseImageProxy method in Android CameraViewRenderer.cs line 410 raise the ArgumentException.

private void SafeCloseImageProxy(IImageProxy proxy)
{
    try
    {
        proxy?.Close();
    }
    catch (ObjectDisposedException) { }
    catch (ArgumentException)
    {
        //Ignore argument exception, it will be thrown if BarcodeAnalyzer get disposed during       processing
        }
}

System.ArgumentException: Handle must be valid. Parameter name: instance at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method) [0x00009] in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniEnvironment.g.cs:11853 at Android.Runtime.JNIEnv.CallVoidMethod (System.IntPtr jobject, System.IntPtr jmethod) [0x00000] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNIEnv.g.cs:258 at AndroidX.Camera.Core.IImageProxyInvoker.Close () [0x0002d] in D:\a\1\s\generated\androidx.camera.camera-core\obj\Release\monoandroid9.0\generated\src\AndroidX.Camera.Core.IImageProxy.cs:467 at BarcodeScanner.Mobile.XamarinForms.Renderer.CameraViewRenderer+BarcodeAnalyzer.SafeCloseImageProxy (AndroidX.Camera.Core.IImageProxy proxy, BarcodeScanner.Mobile.XamarinForms.Renderer.CameraViewRenderer _renderer) [0x00002]

After this exception scanning stops.

I've managed to add quick and dirty workaround with calling:

try
{
    proxy?.Close();
}
catch (ObjectDisposedException) { }
catch (ArgumentException)
{
    //Ignore argument exception, it will be thrown if BarcodeAnalyzer get disposed during processing
    Device.BeginInvokeOnMainThread(() =>
    {
        _renderer.CameraCallback();
    });
}
mantasdaskev commented 2 years ago

Hi, I am having same issue with proxy closing. My use case is similar to @energywave only that my app is running on MAUI. Wanted to know if there is any progress made with this?

snill93 commented 10 months ago

News about this on MUAI?