AVCaptureMetadataOutputObjectsDelegate,DidOutputMetadataObjects并不总是被称为

时间:2018-12-11 18:42:16

标签: xamarin xamarin.ios

我试图扫描我的应用程序中的QR码。它有时起作用,有时不起作用。感觉是当另一个线程上正在加载某些东西时,它不起作用。例如,当附近的商店仍在加载时,如果我按下扫描按钮。如果我等待,通常会奏效。

视频捕获正常,因为我会看到预览。

这是我的代码:

    private bool resultFound;

    public ScannerView()
    {
        InitializeComponent();

        On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(false);

        view = new UIView();
        ScannerArea.Children.Add(view);
    }

    void HandleAVRequestAccessStatus(bool accessGranted)
    {
        if (!accessGranted)
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                await NavigationHelper.Current.CloseModalAsync();
            });
        }

        metadataOutput = new AVCaptureMetadataOutput();

        var metadataDelegate = new MetadataOutputDelegate();
        metadataOutput.SetDelegate(metadataDelegate, DispatchQueue.MainQueue);

        session = new AVCaptureSession();

        camera = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video).First();

        input = AVCaptureDeviceInput.FromDevice(camera);
        session.AddInput(input);

        session.AddOutput(metadataOutput);

        metadataOutput.MetadataObjectTypes = AVMetadataObjectType.QRCode | AVMetadataObjectType.EAN8Code | AVMetadataObjectType.EAN13Code;

        metadataDelegate.MetadataFound += MetadataDelegate_MetadataFound;

        camera.LockForConfiguration(out var error);
        camera.VideoZoomFactor = 2;
        camera.UnlockForConfiguration();

        layer = new AVCaptureVideoPreviewLayer(session);
        layer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;

        layer.MasksToBounds = true;

        layer.Frame = UIApplication.SharedApplication.KeyWindow.RootViewController.View.Bounds;

        view.Layer.AddSublayer(layer);

        session.StartRunning();
    }


    protected override void OnAppearing()
    {
        base.OnAppearing();

        var status = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video);

        if (status != AVAuthorizationStatus.Authorized)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                AVCaptureDevice.RequestAccessForMediaType(AVMediaType.Video, HandleAVRequestAccessStatus);
            });

            return;
        }

        HandleAVRequestAccessStatus(true);
    }


    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        session.StopRunning();
        session.RemoveInput(input);

        session = null;
    }

    void Handle_Clicked(object sender, System.EventArgs e)
    {
        NavigationHelper.Current.CloseModalAsync();
    }

    void MetadataDelegate_MetadataFound(object sender, AVMetadataMachineReadableCodeObject e)
    {
        if (resultFound)
        {
            return;
        }

        resultFound = true;

        var text = e.StringValue;

        Device.BeginInvokeOnMainThread(async () =>
        {
            Vibration.Vibrate(100);
            await NavigationHelper.Current.CloseModalAsync();
            TinyPubSub.Publish(NavigationParameter.ToString(), text);
        });
    }

}

public class MetadataOutputDelegate : AVCaptureMetadataOutputObjectsDelegate
{
    public override void DidOutputMetadataObjects(AVCaptureMetadataOutput captureOutput, AVMetadataObject[] metadataObjects, AVCaptureConnection connection)
    {
        foreach (var m in metadataObjects)
        {
            if (m is AVMetadataMachineReadableCodeObject)
            {
                MetadataFound(this, m as AVMetadataMachineReadableCodeObject);
            }
        }
    }

    public event EventHandler<AVMetadataMachineReadableCodeObject> MetadataFound = delegate { };
}

0 个答案:

没有答案