1

I am trying to implement barcode scanning in my Xamarin form, but no success.
I am able to get the camera working, but I don't see the red line on the screen and it simply refuses to scan anything

I tried this answer. I can see thru my camera, but no red line appears. But I can put the torch on and off

XAML code:

<Button  BackgroundColor="Chocolate" Clicked="Button_Clicked"/>
<zxing:ZXingScannerView 
    x:Name="_scanView" 
    OnScanResult="Handle_OnScanResult" 
    IsScanning="true" 
    IsAnalyzing="true"
    WidthRequest="200" 
    HeightRequest="200" />

C# Code:

private void Button_Clicked(object sender, EventArgs e)
{
    _scanView.ToggleTorch();
}

private void Handle_OnScanResult(ZXing.Result result)
{
    ChassisEntry.Text = result.Text;
}


// this is in the constructor of the page
MobileBarcodeScanningOptions options = new ZXing.Mobile.MobileBarcodeScanningOptions()
{
    TryHarder = true,
    PossibleFormats = new List<ZXing.BarcodeFormat>() { ZXing.BarcodeFormat.All_1D }
};
_scanView.Options = options;

What am I missing ?

EDIT

I have this in my MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
    ZXing.Net.Mobile.Forms.Android.Platform.Init();
    LoadApplication(new App());
}

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
   Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
   ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);

   base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Addition to the answer

@Rafeal 's answer is working for me, the only problem is that there is no red line on the scan view.
I found this workaround for that problem.
However, it is a workaround because I notice that the scan already happens if the barcode is anywhere in the view.
Though this might not appear a problem, in my case I have paper forms with up to 20 barcodes on it, and when the user wants to aim at a particular barcode he might get the wrong one.

So if anybody knows a better solution I would like to hear it.
I will make a separate question on SO about this problem.

This is the workaround I am using now

  <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                <zxing:ZXingScannerView
                    x:Name="_scanView"
                    OnScanResult="Handle_OnScanResult"
                    IsScanning="true"
                    WidthRequest="200"
                    HeightRequest="200"/>


                <zxing:ZXingDefaultOverlay
                    x:Name="scannerOverlay"                                                       
                    BottomText="Place the red line over the barcode you'd like to scan.">

                </zxing:ZXingDefaultOverlay>
            </Grid>
GuidoG
  • 11,359
  • 6
  • 44
  • 79

2 Answers2

1

In my working project I used this xaml declaration:

<zxing:ZXingScannerView x:Name="qrCodeScannerView" 
                        OnScanResult="Handle_OnScanResult" 
                        IsScanning="true"
                        WidthRequest="1024" 
                        HeightRequest="400" />

Note, that I did not set isAnalyzing property in the xaml declaration as you did. As the page appears, the zxing control starts working and analyzing immediately.

Then in xaml.cs file

        public void Handle_OnScanResult(Result scanResult)
        {
                qrCodeScannerView.IsScanning = false;
                // processing scanResult.Text here
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            qrCodeScannerView.IsScanning = true;
        }

        protected override void OnDisappearing()
        {
            base.OnDisappearing();
            qrCodeScannerView.IsScanning = false;
        }

That looks strange, but setting isScanning property also in xaml.cs file solved this task for me.

Rafael
  • 1,281
  • 2
  • 10
  • 35
  • While this scans, I do not see the red line to move over the barcode. How can I do that ? – GuidoG Feb 14 '22 at 15:00
  • I do not see the red line too while it scans. I just align the camera against the qr-code. And it catches it and analyzes immediately. – Rafael Feb 14 '22 at 15:03
  • OK But I really need to see that red line, my customer will not be satisfied without it. Any ideas ? – GuidoG Feb 14 '22 at 15:05
  • I am sorry, but I have no idea how to add a red line over the zxing control. In my project I've added a label above the control with the text: `Point the camera at the QR code. Once the QR code is recognized, you will be automatically redirected to the next step.`. And my customer was happy with it. – Rafael Feb 14 '22 at 15:07
  • I am not scanning QR codes, but 1D codes. Sometimes there is a page with many barcodes on it, without the red line (like every scanner I know has) it will be difficult to point to the correct barcode – GuidoG Feb 14 '22 at 15:46
  • 1
    I have accepted your answer, because it fixed the problem in my question. I would however still like a solution for the red line problem. – GuidoG Feb 14 '22 at 16:09
  • @GuidoG I think it would be good to ask a separate question about the red line on zxing control. – Rafael Feb 14 '22 at 16:32
1

Try removing the ZXingScannerView from your XAML completely. On a clicked event of a button add this code:

private async void ButtonScan(object sender, EventArgs e)
{
    PermissionStatus granted = await Permissions.CheckStatusAsync<Permissions.Camera>();
    if (granted != PermissionStatus.Granted)
    {
        _ = await Permissions.RequestAsync<Permissions.Camera>();
    }
    if (granted == PermissionStatus.Granted)
    {
        try
        {
            MobileBarcodeScanner scanner = new MobileBarcodeScanner();
            ZXing.Result result = await scanner.Scan();
            if (result != null && result.Text != "")
            {
                //You access your scanned text with result.Text
                scanner.Cancel(); // <--- This closes the scanner
            }
        }
        catch (Exception)
        {
            await DisplayAlert("Problem", "Something went wrong.", "ΟΚ");
        }
    }
    else
    {
        await DisplayAlert("Problem", "No permissions to use camera.", "ΟΚ");
    }
} 

EDIT

OP mentioned i should add this line of code to my answer in order to make it work.

In the MainActivity.cs you have to initialize the scanner like this:

ZXing.Mobile.MobileBarcodeScanner.Initialize(Application);
stersym
  • 308
  • 1
  • 6
  • 15
  • Let me know if you need an example for continuous scanning as well. – stersym Feb 14 '22 at 14:51
  • I get `Object reference not set to an instance of an object` on this line `ZXing.Result result = await scanner.Scan();` – GuidoG Feb 14 '22 at 15:20
  • So the scanner is null? On my MainActivity.cs i initialize like this `ZXing.Mobile.MobileBarcodeScanner.Initialize(Application);`. Can you try it? My example is for the red line you need. – stersym Feb 15 '22 at 07:27
  • I will try it, but you should put this very relevant information in your answer ! – GuidoG Feb 15 '22 at 07:46
  • With this extra line in the MainActivity this also works, but you should put that extra line of code in your answer ! – GuidoG Feb 15 '22 at 10:22
  • Do you have any idea how I could add some buttons to this scan screen ? – GuidoG Feb 15 '22 at 10:25
  • I don't believe it's possible to add buttons with this way of scanning, but don't take my word for it. I haven't gone this deep with scanning. I also added the line you suggested to my answer. Thanks. – stersym Feb 15 '22 at 10:46