Search code examples
androidxamarinzxing

xamarin barcode scanning with torch


I'm trying to use xzing barcode scanner in my xamarin android application but I need to also turn on the torch so that I scan in low light conditions.

I'm using xamarin essentials to attempt to turn on the torch but I keep getting the following error message.

     Torch for camera "0" is not available due to an existing camera user

I have a xaml page that contains my scanner

<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <forms:ZXingScannerView                                      
                IsScanning="{Binding IsScanning}" 
                IsAnalyzing="{Binding IsAnalyzing}"
                Result="{Binding Result, Mode=TwoWay}" 
                ScanResultCommand="{Binding ScanCommand}" />
            <forms:ZXingDefaultOverlay               
                x:Name="scannerOverlay"                                                       
                BottomText="Place the red line over the barcode you'd like to scan." />
            <Button Grid.Row="1" Text="Toggle Flash" Command="{Binding FlashToggleCommand}"></Button>
        </Grid>

Then I have the following code behind the command to toggle the torch

public Command FlashToggleCommand
    {
        get { return new Command(async () =>
        {
            try
            {
                   
                // Turn On
                await Flashlight.TurnOnAsync();

                //// Turn Off
                //await Flashlight.TurnOffAsync();
            }
            catch (FeatureNotSupportedException fnsEx)
            {
                // Handle not supported on device exception
            }
            catch (PermissionException pEx)
            {
                // Handle permission exception
            }
            catch (Exception ex)
            {
                // Unable to turn on/off flashlight
            }

        }); }
    }

But I keep on dropping into the exception block with the error message above

I'm assuming that the barcode scanner is utilizing the camera, does anyone know how to get the flashlight/torch to turn on whilst the zxing scanner is also running?


Solution

  • You can add button in your scan layout, achieve the button click event like following code.

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

    NOTE:zxingView is

    <zxing:ZXingScannerView x:Name="zxingView" Grid.Row="1" OnScanResult="Handle_OnScanResult" IsScanning="true" WidthRequest="200" HeightRequest="200" />
    

    And I notice you used MVVM in the forms:ZXingScannerView, as Jason said. you can use IsTorchOn property. Bind a property and use Button click command to control it.

    <Button Text="click" Command="{Binding FlashToggleCommand}"></Button>
    <zxing:ZXingScannerView x:Name="zxingView" Grid.Row="1" OnScanResult="Handle_OnScanResult" IsScanning="true" IsTorchOn="{Binding TouchON}"
                                    WidthRequest="200" HeightRequest="200" />
    

    background code.

    public PartialScreenScanning()
            {
                InitializeComponent();
                this.BindingContext = new MyViewModel();
            }
    

    Then create a MyViewModel.cs.

       public class MyViewModel: INotifyPropertyChanged
        {
            public MyViewModel()
            {
               
    
                  
            }
            bool _touchON=false;
            public Command FlashToggleCommand
            {
                get
                {
                    return new Command(async () =>
                    {
    
                        TouchON = !TouchON;
                    });
                }
            }
           
            public bool TouchON
            {
                set
                {
                    if (_touchON != value)
                    {
                        _touchON = value;
                        OnPropertyChanged("TouchON");
    
                    }
                }
                get
                {
                    return _touchON;
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    Here is runnning GIF.

    enter image description here