Redth / ZXing.Net.Maui

Barcode Scanning for MAUI?
MIT License
452 stars 148 forks source link

Release Device Camera #65

Open ManuLin opened 1 year ago

ManuLin commented 1 year ago

I'm using the barcode scanner in an app in conjuction with NFC. Depending on the user's preferences, the app can be used to scan either bar codes or NFC tags, respectively. The issue I am now facing is that as soon as I add the bar code scanner to the UI, the NFC scanner won't work - this is a limitation on several Android devices. Removing, hiding or disabling the bar code scanner view does not resolve the issue. I'm curious if there is a way to force the view to release the camera resources in order to enable NFC scanning?

JSMTPOS commented 1 year ago

Solved in our case by updating the Disconnect() function in ZXing.Net.MAUI project CameraManager.android.cs

public void Disconnect() { if (cameraProvider != null) { cameraProvider.UnbindAll(); } }

and when closing your scanner view barcodeReader.IsDetecting=false; barcodeReader.BarcodesDetected -= barcodeReader_BarcodesDetected; barcodeReader.Handler.DisconnectHandler(); barcodeReader = null;

ThomasCarltonInPerson commented 1 year ago

I tried recompiling ZXing.Net.Maui package in order to update the function Disconnect() but it was a nightmare. The scanner doesn't detect any QR/Bar code. So I gave up this solution and came up with this :

Which is calling the same function cameraProvider.UnbindAll() using reflection.

Be aware that this code is version dependant. In case you update ZXing.Net.Maui package, you have to make sure it still works.

#if ANDROID
        // Get the camera manager
        Type type = cameraBarcodeReaderView.Handler.GetType();        
        FieldInfo fieldInfo = type.GetField("cameraManager", BindingFlags.NonPublic | BindingFlags.Instance);
        object value = fieldInfo.GetValue(cameraBarcodeReaderView.Handler);

        // Get the ProcessCameraProvider
        type = value.GetType();
        fieldInfo = type.GetField("cameraProvider", BindingFlags.NonPublic | BindingFlags.Instance);
        ProcessCameraProvider cameraProvider = (ProcessCameraProvider)fieldInfo.GetValue(value);
        if (cameraProvider != null )
        {
            cameraProvider.UnbindAll();
        }        
#endif

That's an immediate workaround that you can use. Hoping the package team will come with a better solution.