Redth / ZXing.Net.Maui

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

Camera is not disposing #38

Open eslamo opened 2 years ago

eslamo commented 2 years ago

There is an issue after scanning that camera is still on and element not disposing.

IOS green circle still on indicating resource is still in use after changing page or close modal or whatever.

What I tried and nothing is working: I turned off IsDetecting and set to false after reading. I also tried to remove the child element it self from stacklayout (it disappears) BUT camera green indicator still show in use.

Please add a Dispose method to manually disconnect the Camera

eslamo commented 2 years ago

I Checked the code and found Dispose method in CameraManager not calling Disconnect. It's Empty ...

And I don't know if it's already disposing while removie the control from UI or not

https://github.com/Redth/ZXing.Net.Maui/blob/71a6ea2114b9f1412dccedee36ad1721e06e5a4a/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs#L237-L239

https://github.com/Redth/ZXing.Net.Maui/blob/71a6ea2114b9f1412dccedee36ad1721e06e5a4a/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs#L137-L161

darioragusa commented 2 years ago

Hi, I had to remove the control from the page and after removing it with this:

if (Content.Contains(scanner))
    Content.Remove(scanner);

*Content is a StackLayout and scanner is the CameraBarcodeReaderView I disconnected the camera (or at least the green circle disappeared) with this: scanner.Handler.DisconnectHandler();

Hope it helps!

khambley commented 1 year ago

It certainly helped me! I was pulling my hair out trying to get that dang green dot to disappear. Thanks much! :)

haeun159951 commented 1 year ago

I tried with that code but I am having this error: virtual view cannot be null when i navigated to the next screen

Have you got this kind of error before?

Screenshot 2023-02-23 at 8 01 40 PM

cvaughn-bhs commented 7 months ago

Late to the party on this one, but this helped me figure out the next step after also getting the "VirtualView cannot be null here" error message. So, the issue is the DisconnectHandler that needs to be called is the one defined on the CameraBarcodeReaderViewHandler.

If you just call {Your Control Name}.Handler.DisconnectHandler() it will call the base ViewHandler.DisconnectHandler() method which is missing the bit where the CameraManager_FrameReady is removed from the FrameReady event handler delegate.

image

This is what I used to get around that. Hopefully this helps. Most of my testing for this was done on a Maui Community Toolkit popup.

       // Gets the CameraBarcodeReaderViewHandler.
    var cameraViewHandlerType = CameraView.Handler?.GetType();

    // Gets the CameraManager.
    var cameraManagerInfo = cameraViewHandlerType?.GetField("cameraManager", BindingFlags.NonPublic | BindingFlags.Instance);
    var cameraManagerValue = cameraManagerInfo?.GetValue(CameraView.Handler);

    // Gets the PreviewView that will be used as a parameter for calling DisconnectHandler.
    var cameraManagerType = cameraManagerValue?.GetType();
    FieldInfo? previewViewInfo = null;

    // The PreviewView is named differently on Android and iOS.
    if (OperatingSystem.IsAndroid())
    {
        previewViewInfo = cameraManagerType?.GetField("previewView", BindingFlags.NonPublic | BindingFlags.Instance);
    }
    else if (OperatingSystem.IsIOS())
    {
        previewViewInfo = cameraManagerType?.GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
    }

    var previewViewValue = previewViewInfo?.GetValue(cameraManagerValue);

    // Gets the DisconnectHandler method handle.
    var disconnectHandlerInfo = cameraViewHandlerType?.GetMethod("DisconnectHandler", BindingFlags.NonPublic | BindingFlags.Instance);

    if (previewViewValue != null)
    {
        var disconnectHandlerParams = new[] { previewViewValue };

        disconnectHandlerInfo?.Invoke(CameraView.Handler, disconnectHandlerParams);
    }
mackayn commented 2 months ago

Late to the party on this one, but this helped me figure out the next step after also getting the "VirtualView cannot be null here" error message. So, the issue is the DisconnectHandler that needs to be called is the one defined on the CameraBarcodeReaderViewHandler.

If you just call {Your Control Name}.Handler.DisconnectHandler() it will call the base ViewHandler.DisconnectHandler() method which is missing the bit where the CameraManager_FrameReady is removed from the FrameReady event handler delegate.

image

This is what I used to get around that. Hopefully this helps. Most of my testing for this was done on a Maui Community Toolkit popup.

       // Gets the CameraBarcodeReaderViewHandler.
  var cameraViewHandlerType = CameraView.Handler?.GetType();

  // Gets the CameraManager.
  var cameraManagerInfo = cameraViewHandlerType?.GetField("cameraManager", BindingFlags.NonPublic | BindingFlags.Instance);
  var cameraManagerValue = cameraManagerInfo?.GetValue(CameraView.Handler);

  // Gets the PreviewView that will be used as a parameter for calling DisconnectHandler.
  var cameraManagerType = cameraManagerValue?.GetType();
  FieldInfo? previewViewInfo = null;

  // The PreviewView is named differently on Android and iOS.
  if (OperatingSystem.IsAndroid())
  {
      previewViewInfo = cameraManagerType?.GetField("previewView", BindingFlags.NonPublic | BindingFlags.Instance);
  }
  else if (OperatingSystem.IsIOS())
  {
      previewViewInfo = cameraManagerType?.GetField("view", BindingFlags.NonPublic | BindingFlags.Instance);
  }

  var previewViewValue = previewViewInfo?.GetValue(cameraManagerValue);

  // Gets the DisconnectHandler method handle.
  var disconnectHandlerInfo = cameraViewHandlerType?.GetMethod("DisconnectHandler", BindingFlags.NonPublic | BindingFlags.Instance);

  if (previewViewValue != null)
  {
      var disconnectHandlerParams = new[] { previewViewValue };

      disconnectHandlerInfo?.Invoke(CameraView.Handler, disconnectHandlerParams);
  }

Thanks for this, works perfectly, was using a Mopup to host the barcode scanner and was getting the virtualview crash randomly even after disconnecting the handler.