Open EmilAlipiev opened 3 years ago
Torch does have issues on Android. FlashCommand property of DefaultOverlay does not work. IsTorchOn property of ScannerView does not work. First time Torch is turned on, it doesn't turn on... (Note: I also could not get property IsScanning to work properly: see workaround below)
Below is what I had to do to get the Torch button to work. (Version 2.4.1 of the library - I haven't tried 3.0 in Beta)
I recommend just setting ShowFlashButton to true. (Am curious: Is there any device who's camera is capable enough to run this library, yet does not have a torch? Are there known issues with always setting it to true?)
I do MVVM, but couldn't for the Torch because of those properties not working. (I do use MVVM for the scan Result)
XAML:
?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="YourNameSpace.ScanPage"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
>
<StackLayout>
<Button Text="Cancel"
Command="{Binding ExclusiveCommand}"
CommandParameter="Cancel"
TextColor="Black"
BackgroundColor="LightGray"
FontSize="10"
HorizontalOptions="FillAndExpand"
/>
<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<zxing:ZXingScannerView x:Name="ScannerView"
IsAnalyzing="{Binding IsAnalyzing}"
Result="{Binding Result, Mode=OneWayToSource}"
ScanResultCommand="{Binding ScanResultCommand}"
WidthRequest="200"
HeightRequest="200" />
<!-- DOES NOT WORK in View -->
<!--IsTorchOn="{Binding IsTorchOn, Mode=TwoWay}"-->
<zxing:ZXingDefaultOverlay
x:Name="ScannerOverlay"
TopText="Place the red line over the barcode."
BottomText="Hold the device steady for a second."
ShowFlashButton="True"
Opacity="0.8"
FlashButtonClicked="ScannerOverlay_FlashButtonClicked" />
<!-- DOES NOT WORK in View -->
<!--FlashCommand="{Binding FlashCommand}"-->
</Grid>
</StackLayout>
</ContentPage>
Code Behind for Torch: (and a few other things I couldn't get working with MVVM / bound properties)
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using ZXing.Mobile;
namespace YourNameSpace
{
public partial class ScanPage : ContentPage
{
public ScanPage()
{
InitializeComponent();
// https://blog.verslu.is/xamarin/xamarin-forms-xamarin/zxing-android-skipping-frames/
ScannerView.Options.DelayBetweenAnalyzingFrames = 5; // 5 milliseconds, and lower than the default - weird that it's better
ScannerView.Options.DelayBetweenContinuousScans = 2000; //2000
ScannerView.Options.InitialDelayBeforeAnalyzingFrames = 300;
ScannerView.Options.TryHarder = false;
ScannerView.Options.TryInverted = false;
ScannerView.Options.AutoRotate = false;
ScannerView.Options.UseFrontCameraIfAvailable = false;
ScannerView.Options.PossibleFormats.Clear();
ScannerView.Options.PossibleFormats.Add(ZXing.BarcodeFormat.CODE_128);
}
private bool _isFirstTorchOnRequest = true;
private void ScannerOverlay_FlashButtonClicked(Button sender, EventArgs e)
{
if (_isFirstTorchOnRequest) // else won't turn on with 1st click
{
ScannerView.IsTorchOn = true;
_isFirstTorchOnRequest = false;
}
else
{
ScannerView.IsTorchOn = !ScannerView.IsTorchOn;
}
}
protected override void OnAppearing()
{
base.OnAppearing();
ScannerView.IsScanning = true;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
ScannerView.IsScanning = false;
}
}
}
Relevant parts of ViewModel:
private bool _doScan = true;
private bool _isAnalyzing = true; // start with analysis on
public bool IsAnalyzing
{
get => _isAnalyzing;
set => SetProperty(ref _isAnalyzing, value);
}
private Result _result;
public Result Result
{
get => _result;
set => SetProperty(ref _result, value);
}
private DelegateCommand _scanResultCommand;
public DelegateCommand ScanResultCommand => _scanResultCommand ??= new DelegateCommand(ExecuteScanResultCommand);//, CanExecuteScanResultCommand);
/// <summary>
/// Unlike your typical button command, this methods is called from the hardware, on a non-UI thread
/// </summary>
private void ExecuteScanResultCommand()
{
if (!_doScan) // use this non-UI property to block re-entry, as this call comes in on a non-UI thread
{
return;
}
_doScan = false; // doing this immediately, in this thread, to really avoid re-entry
_player.PlayScannerBeep(); // play early because human response is slow
_deviceService.BeginInvokeOnMainThread(async () =>
{
IsAnalyzing = false; // while could set _doScane false earlier, must call the rest from UI thread
var barcode = Result.Text; // not exactly what I do, but same principle.
});
// NOTE: DO NOT set _doScan = true here, because this code runs in separate thread from Main UI thread, BEFORE GoBackWithBarcodeAsync completes.
}
...I haven't tried 3.0 in Beta)
Hey @thhowl can you try 3.0 beta please?
@knocte , I will try 3.0 beta next week.
I already wrote in the issue that i tried and problem persists.
I had the same issue and it appeared that I didn't have the Android FLASHLIGHT permission in the AndroidManifest.xml (silly me).
I tried your sample and code below doesn't display the flash button although my phone has has torch, HasTorch returns always false. If set it true, torch is just working fine on my code. it seems like a bug on android. I tried 3 beta as well. same problem