Problem with TMSFNCWXCamera on android

I have the following code that runs OK under win but can't compile on 64bit android. Even when I paste the TMSFNCWXCamera module itself on an otherwise working project with only tlabel labels, the project doesn't even show up on the connected phone :(

PS in project settings Camera is enabled

unit TabbedTemplate;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.TabControl,
FMX.StdCtrls, FMX.Gestures, FMX.Controls.Presentation, FMX.TMSFNCTypes,
FMX.TMSFNCUtils, FMX.TMSFNCGraphics, FMX.TMSFNCGraphicsTypes,
FMX.TMSFNCCustomControl, FMX.TMSFNCWebBrowser, FMX.TMSFNCCustomWEBControl,
FMX.TMSFNCWXCamera, FMX.TMSFNCCustomWEBComponent, FMX.TMSFNCWXBarcodeDecoder,
FMX.TMSFNCWXQRDecoder, FMX.Edit, FMX.TMSFNCEdit, System.Math.Vectors,
FMX.Controls3D, FMX.Layers3D, FMX.Objects, FMX.Layouts, Data.DB,
RemoteDB.Client.Dataset;

type
TTabbedForm = class(TForm)
HeaderToolBar: TToolBar;
lblWelcome: TLabel;
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
TabItem3: TTabItem;
TabItem4: TTabItem;
GestureManager1: TGestureManager;
TMSFNCWXCamera1: TTMSFNCWXCamera;
btn_Scan: TButton;
TMSFNCWXQRDecoder1: TTMSFNCWXQRDecoder;
Button2: TButton; // Tlačítko "Stop Scan"
TMSFNCEdit1: TTMSFNCEdit; // Ponecháno dle původního kódu, i když se zdá nepoužité v logice
btn_Odeslat: TButton; // Hlavní tlačítko Odeslat/Start Scan
txt_zakazka: TTMSFNCEdit;
Layout3D1: TLayout3D;
Layout3D2: TLayout3D;
LayoutSemafor: TLayout;
CircleSemafor: TCircle;
lblSemaforText: TLabel;
lblConnectionStatus: TLabel;
LayoutTechnicianInfo: TLayout;
lblTechnicianInfo: TLabel;
lblDepartment: TLabel;
lblLastActivity: TLabel; // Textové pole pro ID zakázky
procedure FormCreate(Sender: TObject);
procedure FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo;
var Handled: Boolean);
procedure btn_ScanClick(Sender: TObject); // Klik na původní tlačítko Scan
procedure btn_OdeslatClick(Sender: TObject); // Klik na tlačítko Odeslat
procedure TMSFNCWXQRDecoder1Decoded(Sender: TObject; AFound: Boolean;
const AResult: string);
procedure Button2Click(Sender: TObject); // Klik na tlačítko Stop (Button2)
procedure txt_zakazkaChange(Sender: TObject); // Událost OnChange pro txt_zakazka
private
{ Private declarations }
FScanning: Boolean; // Příznak, zda probíhá skenování
procedure StartScanningProcess; // Pomocná metoda pro spuštění skenování
procedure StopScanning(AUserCancelled: Boolean = False); // Pomocná metoda pro zastavení
public
{ Public declarations }
end;

var
TabbedForm: TTabbedForm;

implementation

{$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID}
{$R *.Windows.fmx MSWINDOWS}
{$R *.LgXhdpiPh.fmx ANDROID}

procedure TTabbedForm.FormCreate(Sender: TObject);
begin
FScanning := False;
TMSFNCWXQRDecoder1.Camera := TMSFNCWXCamera1;
TabControl1.ActiveTab := TabItem1;

TMSFNCWXCamera1.Visible := False; // Kamera je na začátku skrytá
Button2.Visible := False; // Tlačítko "Stop" je na začátku skryté
btn_Scan.Visible := True; // Původní tlačítko "Scan" je viditelné
btn_Odeslat.Visible := True; // Tlačítko "Odeslat" je viditelné

end;

procedure TTabbedForm.txt_zakazkaChange(Sender: TObject);
begin
// Pokud textové pole NENÍ prázdné po změně, vyvoláme akci odeslání.
if Trim(txt_zakazka.Text) <> '' then
begin
// Zkontrolujeme, zda neprobíhá skenování, aby se předešlo nechtěnému spuštění
// logiky odeslání během nastavování textu ze skeneru (mělo by být FScanning=False).
if not FScanning then
begin
btn_OdeslatClick(Self); // Vyvolá část pro odeslání v btn_OdeslatClick
end;
end;
end;

procedure TTabbedForm.StartScanningProcess;
begin
if FScanning then Exit; // Pokud již skenujeme, nic nedělat

if TMSFNCWXQRDecoder1.Camera <> TMSFNCWXCamera1 then
begin
TMSFNCWXQRDecoder1.Camera := TMSFNCWXCamera1;
end;

// UI změny pro aktivní skenování
TMSFNCWXCamera1.Visible := True;
Button2.Visible := True; // Zobrazit tlačítko STOP
btn_Odeslat.Visible := False; // Skrýt tlačítko Odeslat
btn_Scan.Visible := False; // Skrýt i původní tlačítko Scan

try
FScanning := True; // Nastavit příznak PŘED startem
TMSFNCWXCamera1.Start;
except
on E: Exception do
begin
FScanning := False; // Resetovat
TMSFNCWXCamera1.Visible := False;
Button2.Visible := False;
btn_Odeslat.Visible := True; // Obnovit viditelnost Odeslat
btn_Scan.Visible := True; // Obnovit viditelnost Scan
ShowMessage('Chyba při spouštění kamery: ' + E.Message);
try TMSFNCWXCamera1.Stop; except end;
end;
end;
end;

procedure TTabbedForm.btn_OdeslatClick(Sender: TObject);
begin
if FScanning and (Trim(txt_zakazka.Text) = '') then
begin
Exit;
end;

if Trim(txt_zakazka.Text) = '' then
begin
// --- POLE JE PRÁZDNÉ: Spustit skenování ---
StartScanningProcess;
end
else
begin
// --- POLE NENÍ PRÁZDNÉ: Odeslat data ---
ShowMessage('Odesílám číslo zakázky: ' + txt_zakazka.Text);
// TODO: Implementujte zde volání vašeho REST API klienta s použitím SecureBridge
// Např.: MySecureBridgeClient.SendData(txt_zakazka.Text);
end;
end;

procedure TTabbedForm.btn_ScanClick(Sender: TObject);
begin
StartScanningProcess;
end;

procedure TTabbedForm.StopScanning(AUserCancelled: Boolean = False);
begin
if not FScanning then Exit;

FScanning := False;
try
TMSFNCWXCamera1.Stop;
except
on E: Exception do
ShowMessage('Chyba při zastavování kamery: ' + E.Message);
end;

TMSFNCWXCamera1.Visible := False;
Button2.Visible := False;
btn_Scan.Visible := True;
btn_Odeslat.Visible := True;

if AUserCancelled then
begin
ShowMessage('Skenování zastaveno uživatelem.');
end;
end;

procedure TTabbedForm.TMSFNCWXQRDecoder1Decoded(Sender: TObject; AFound: Boolean;
const AResult: string);
begin
// Nejprve zkontrolujeme, zda skenování vůbec má běžet.
// Pokud FScanning je False, znamená to, že skenování bylo již zastaveno
// (např. uživatelem nebo předchozím úspěšným nálezem), takže tuto událost ignorujeme.
if not FScanning then
Exit;

if AFound then
begin
// QR KÓD BYL NALEZEN!
// 1. Zastavíme skenování (protože už máme výsledek).
// Voláme StopScanning bez parametru True, protože to není zrušení uživatelem.
StopScanning;

// 2. Zpracujeme nalezený výsledek v hlavním vlákně.
TThread.Synchronize(nil,
  procedure
  begin
    txt_zakazka.Text := AResult; // Přiřazení textu spustí událost txt_zakazkaChange,
                                 // která (pokud je text neprázdný) zavolá btn_OdeslatClick
                                 // pro odeslání dat.
    ShowMessage('QR Kód načten: ' + AResult);
  end);

end
else
begin
// QR KÓD NEBYL V TOMTO CYKLU NALEZEN
// Nic neděláme. Skenování pokračuje automaticky dál,
// dokud uživatel nestiskne "Stop" nebo dokud kód není nalezen.
// Můžete sem přidat logování do konzole pro ladění, pokud chcete sledovat cykly,
// ale žádné ShowMessage, které by blokovalo běh.
// např. OutputDebugString(PChar('QR kód nenalezen v tomto cyklu, pokračuji...'));
end;
end;

procedure TTabbedForm.Button2Click(Sender: TObject);
begin
StopScanning(True); // Uživatel kliknul na "Stop"
end;

procedure TTabbedForm.FormGesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
{$IFDEF ANDROID}
case EventInfo.GestureID of
sgiLeft:
begin
if TabControl1.ActiveTab <> TabControl1.Tabs[TabControl1.TabCount-1] then
TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex+1];
Handled := True;
end;

sgiRight:
begin
  if TabControl1.ActiveTab <> TabControl1.Tabs[0] then
    TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex-1];
  Handled := True;
end;

end;
{$ENDIF}
end;

end.

Hi,

Did you add the necessary JAR files to your project? See here if not:

TTMSFNCWXCamera module under android runs after installing *.jar libraries and reads "large" QR codes but does not focus on small ones like 2x2cm

How to set autofocus?

TTMSFNCWXCamera module under android runs after installing *.jar libraries and reads "large" QR codes but does not focus on small ones like 2x2cm
How to set autofocus?

Component version:

  • TMS FNC WX Pack version actual

  • Delphi 12.3 Path 5/25

  • Android version on test device 15, One+ phone

Problem:

  • TTMSFNCWXCamera does not focus when scanning QR codes

  • SupportedConstraints contains 'focusMode' and 'focusDistance'

  • ApplyConstraints with focusMode='continuous' has no effect

What have you already tried:

  • ApplyConstraints in OnStart event

  • Different focusMode values

  • Thread with time delay

unit TabbedTemplate;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.TabControl,
FMX.StdCtrls, FMX.Gestures, FMX.Controls.Presentation, FMX.TMSFNCTypes,
FMX.TMSFNCUtils, FMX.TMSFNCGraphics, FMX.TMSFNCGraphicsTypes,
FMX.TMSFNCCustomControl, FMX.TMSFNCWebBrowser, FMX.TMSFNCCustomWEBControl,
FMX.TMSFNCWXCamera, FMX.TMSFNCCustomWEBComponent, FMX.TMSFNCWXBarcodeDecoder,
FMX.TMSFNCWXQRDecoder, FMX.Edit, FMX.TMSFNCEdit, System.Math.Vectors,
FMX.Controls3D, FMX.Layers3D, FMX.Objects, FMX.Layouts, Data.DB,
RemoteDB.Client.Dataset, FMX.DialogService
{$IFDEF ANDROID}
, Androidapi.Helpers, Androidapi.JNI.App
{$ENDIF};

type
// Definice stavů tlačítka
TButtonState = (bsStartScan, bsStopScan, bsSendData);

TTabbedForm = class(TForm)
HeaderToolBar: TToolBar;
lblWelcome: TLabel;
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
TabItem3: TTabItem;
TabItem4: TTabItem;
TMSFNCWXCamera1: TTMSFNCWXCamera;
btn_Scan: TButton;
TMSFNCWXQRDecoder1: TTMSFNCWXQRDecoder;
Button2: TButton;
btn_Odeslat: TButton;
txt_zakazka: TTMSFNCEdit;
LayoutSemafor: TLayout;
CircleSemafor: TCircle;
lblSemaforText: TLabel;
lblConnectionStatus: TLabel;
LayoutTechnicianInfo: TLayout;
lblTechnicianInfo: TLabel;
lblDepartment: TLabel;
lblLastActivity: TLabel;
GestureManager1: TGestureManager;
btnExit: TSpeedButton; // Přidáno - tlačítko pro ukončení
procedure FormCreate(Sender: TObject);
procedure FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo;
var Handled: Boolean);
procedure btn_ScanClick(Sender: TObject);
procedure btn_OdeslatClick(Sender: TObject);
procedure TMSFNCWXQRDecoder1Decoded(Sender: TObject; AFound: Boolean;
const AResult: string);
procedure Button2Click(Sender: TObject);
procedure txt_zakazkaChange(Sender: TObject);
procedure btnExitClick(Sender: TObject); // Přidáno - handler pro ukončení

private
{ Private declarations }
FScanning: Boolean;
FButtonState: TButtonState;
FTimeoutTimer: TTimer;
procedure StartScanningProcess;
procedure StopScanning(AUserCancelled: Boolean = False);
procedure SetButtonState(AState: TButtonState);
procedure ProcessOrderNumber(const AOrderNumber: string);
procedure ResetToInitialState;
procedure UpdateSemafor(const AStatus: string);
procedure TimeoutTimerTimer(Sender: TObject);
public
{ Public declarations }
end;

var
TabbedForm: TTabbedForm;

implementation

{$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID}
{$R *.Windows.fmx MSWINDOWS}
{$R *.LgXhdpiPh.fmx ANDROID}

procedure TTabbedForm.FormCreate(Sender: TObject);
begin
FScanning := False;
FButtonState := bsStartScan;

TMSFNCWXQRDecoder1.Camera := TMSFNCWXCamera1;
TMSFNCWXCamera1.CameraType := wctBack;
TabControl1.ActiveTab := TabItem1;

// Nastavení txt_zakazka
txt_zakazka.TextPrompt := 'Zadej číslo zakázky nebo scanuj';
txt_zakazka.Text := '';

btn_Scan.StyleLookup := 'speedbutton';
btn_Scan.TintColor := TAlphaColors.Blue;

TMSFNCWXCamera1.Visible := False;
Button2.Visible := False;
btn_Scan.Visible := True;
btn_Scan.BringToFront;
btn_Odeslat.Visible := True;

// Skrytí původních tlačítek pomocí opacity
Button2.Opacity := 0;
Button2.HitTest := False;
btn_Odeslat.Opacity := 0;
btn_Odeslat.HitTest := False;

txt_zakazka.Opacity := 1;
txt_zakazka.HitTest := True;
txt_zakazka.Visible := True;

// Vytvoření timeout timeru
FTimeoutTimer := TTimer.Create(Self);
FTimeoutTimer.Interval := 30000; // 30 sekund
FTimeoutTimer.Enabled := False;
FTimeoutTimer.OnTimer := TimeoutTimerTimer;

// Inicializace labelů
lblTechnicianInfo.Text := 'Technik: ---';
lblDepartment.Text := 'Oddělení: ---';
lblLastActivity.Text := 'Aktivita: nepřipojeno';

// Přidání světle šedého pozadí pro LayoutTechnicianInfo pomocí TRectangle
var
BgRect: TRectangle;
begin
// Najít existující rectangle nebo vytvořit nový
BgRect := nil;
for var i := 0 to LayoutTechnicianInfo.ControlsCount - 1 do
begin
if LayoutTechnicianInfo.Controls[i] is TRectangle then
begin
BgRect := TRectangle(LayoutTechnicianInfo.Controls[i]);
Break;
end;
end;

if BgRect = nil then
begin
  BgRect := TRectangle.Create(LayoutTechnicianInfo);
  BgRect.Parent := LayoutTechnicianInfo;
end;

BgRect.Align := TAlignLayout.Contents;
BgRect.Fill.Kind := TBrushKind.Solid;
BgRect.Fill.Color := TAlphaColors.Lightgray;
BgRect.HitTest := False;
BgRect.Stroke.Kind := TBrushKind.None;
BgRect.SendToBack;

end;

// Inicializace semaforu
UpdateSemafor('nepřipojeno');

// Nastavit počáteční stav tlačítka
SetButtonState(bsStartScan);

// Vytvoření a nastavení tlačítka Exit v HeaderToolBar
if btnExit = nil then
begin
btnExit := TSpeedButton.Create(HeaderToolBar);
btnExit.Parent := HeaderToolBar;
btnExit.Align := TAlignLayout.Right;
btnExit.Width := 40;
btnExit.StyleLookup := 'stoptoolbutton'; // Nebo 'closetoolbutton'
btnExit.OnClick := btnExitClick;

// Alternativně můžete použít text místo ikony:
// btnExit.Text := 'X';
// btnExit.StyleLookup := 'toolbutton';

end;
end;

procedure TTabbedForm.SetButtonState(AState: TButtonState);
begin
FButtonState := AState;

case AState of
bsStartScan:
begin
btn_Scan.Text := 'START SCAN';
btn_Scan.TintColor := TAlphaColors.Blue;
FTimeoutTimer.Enabled := False;
end;

bsStopScan:
begin
  btn_Scan.Text := 'STOP SCAN';
  btn_Scan.TintColor := TAlphaColors.Red;
  FTimeoutTimer.Enabled := False;
end;

bsSendData:
begin
  btn_Scan.Text := 'ODESLAT / PŘIHLÁSIT';
  btn_Scan.TintColor := TAlphaColors.Green;
  FTimeoutTimer.Enabled := True; // Spustit 30s timer
end;

end;
end;

procedure TTabbedForm.UpdateSemafor(const AStatus: string);
begin
lblSemaforText.Text := AStatus;

if AStatus = 'nepřipojeno' then
begin
CircleSemafor.Fill.Color := TAlphaColors.Gray;
end
else if AStatus = 'skenování' then
begin
CircleSemafor.Fill.Color := TAlphaColors.Gray; // Šedá při skenování
end
else if AStatus = 'připraveno k odeslání' then
begin
CircleSemafor.Fill.Color := TAlphaColors.Brown; // Hnědá když je text vyplněn
end
else if AStatus = 'odesláno' then
begin
CircleSemafor.Fill.Color := TAlphaColors.Orange; // Oranžová po odeslání
end
else if AStatus = 'připojeno' then
begin
CircleSemafor.Fill.Color := TAlphaColors.Green; // Zelená po spojení se serverem
end;

lblConnectionStatus.Text := 'Status: ' + AStatus;
lblLastActivity.Text := 'Aktivita: ' + AStatus + ' (' +
FormatDateTime('hh:nn:ss', Now) + ')';
end;

procedure TTabbedForm.btn_ScanClick(Sender: TObject);
begin
case FButtonState of
bsStartScan:
begin
// Spustit skenování
StartScanningProcess;
end;

bsStopScan:
begin
  // Zastavit skenování
  StopScanning(True);
  ResetToInitialState;
end;

bsSendData:
begin
  // Odeslat data
  ProcessOrderNumber(txt_zakazka.Text);
end;

end;
end;

procedure TTabbedForm.StartScanningProcess;
begin
if FScanning then Exit;

if TMSFNCWXQRDecoder1.Camera <> TMSFNCWXCamera1 then
begin
TMSFNCWXQRDecoder1.Camera := TMSFNCWXCamera1;
end;

// UI změny pro aktivní skenování
TMSFNCWXCamera1.Visible := True;
SetButtonState(bsStopScan);
UpdateSemafor('skenování');

try
FScanning := True;
TMSFNCWXCamera1.Start;
except
on E: Exception do
begin
FScanning := False;
TMSFNCWXCamera1.Visible := False;
SetButtonState(bsStartScan);
UpdateSemafor('nepřipojeno');
ShowMessage('Chyba při spouštění kamery: ' + E.Message);
try TMSFNCWXCamera1.Stop; except end;
end;
end;
end;

procedure TTabbedForm.StopScanning(AUserCancelled: Boolean = False);
begin
if not FScanning then Exit;

FScanning := False;
try
TMSFNCWXCamera1.Stop;
except
on E: Exception do
ShowMessage('Chyba při zastavování kamery: ' + E.Message);
end;

TMSFNCWXCamera1.Visible := False;

if AUserCancelled then
begin
ShowMessage('Skenování zastaveno uživatelem.');
end;
end;

procedure TTabbedForm.TMSFNCWXQRDecoder1Decoded(Sender: TObject; AFound: Boolean;
const AResult: string);
begin
if not FScanning then
Exit;

if AFound then
begin
// QR kód nalezen
StopScanning;

TThread.Synchronize(nil,
  procedure
  begin
    txt_zakazka.Text := AResult;
    SetButtonState(bsSendData);
    UpdateSemafor('připraveno k odeslání');  // Změna - hnědá
    ShowMessage('QR Kód načten: ' + AResult);
  end);

end;
end;

procedure TTabbedForm.ProcessOrderNumber(const AOrderNumber: string);
begin
// Testovací režim - nejprve změnit stav na "odesláno"
UpdateSemafor('odesláno'); // Oranžová - data byla odeslána
ShowMessage('Odesílám číslo zakázky: ' + AOrderNumber);

// Aktualizace labelů
lblTechnicianInfo.Text := 'Technik: Tomáš Macourek';
lblDepartment.Text := 'Oddělení: IT support';

// TODO: Zde bude implementace skutečného odeslání přes REST API
// Po úspěšném spojení se serverem:
// UpdateSemafor('připojeno'); // Zelená - spojení navázáno

// Simulace spojení se serverem po 1 sekundě
TThread.CreateAnonymousThread(
procedure
begin
Sleep(1000); // Simulace komunikace se serverem
TThread.Synchronize(nil,
procedure
begin
UpdateSemafor('připojeno'); // Zelená - spojení navázáno
end);

  Sleep(2000); // Počkat další 2 sekundy
  TThread.Synchronize(nil,
    procedure
    begin
      ResetToInitialState;
    end);
end).Start;

end;

procedure TTabbedForm.ResetToInitialState;
begin
// Vymazat text
txt_zakazka.Text := '';

// Resetovat tlačítko
SetButtonState(bsStartScan);

// Resetovat labely
lblTechnicianInfo.Text := 'Technik: ---';
lblDepartment.Text := 'Oddělení: ---';
UpdateSemafor('nepřipojeno');

// Zastavit timer
FTimeoutTimer.Enabled := False;
end;

procedure TTabbedForm.TimeoutTimerTimer(Sender: TObject);
begin
// Timeout po 30 sekundách - vrátit na začátek
FTimeoutTimer.Enabled := False;
ShowMessage('Časový limit vypršel. Vracím na začátek.');
ResetToInitialState;
end;

// Původní metody ponechané pro kompatibilitu
procedure TTabbedForm.txt_zakazkaChange(Sender: TObject);
begin
// Původní logika - pokud text není prázdný a neskenujeme, zpracovat
if Trim(txt_zakazka.Text) <> '' then
begin
if not FScanning then
begin
// Pokud je tlačítko ve stavu "Odeslat", automaticky odeslat
// Jinak nastavit tlačítko na "Odeslat"
if FButtonState = bsSendData then
begin
ProcessOrderNumber(txt_zakazka.Text);
end
else
begin
SetButtonState(bsSendData);
UpdateSemafor('připraveno k odeslání'); // Změna - hnědá
end;
end;
end;
end;

procedure TTabbedForm.btn_OdeslatClick(Sender: TObject);
begin
// Ponecháno prázdné - logika přesunuta do btn_ScanClick
end;

procedure TTabbedForm.Button2Click(Sender: TObject);
begin
// Ponecháno prázdné - původní funkce
end;

procedure TTabbedForm.btnExitClick(Sender: TObject);
begin
// Použití moderního DialogService
TDialogService.MessageDialog('Opravdu chcete ukončit aplikaci?',
TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo],
TMsgDlgBtn.mbNo, 0,
procedure(const AResult: TModalResult)
begin
if AResult = mrYes then
begin
{$IFDEF ANDROID}
// Pro Android - správné ukončení
TAndroidHelper.Activity.finish;
{$ELSE}
// Pro ostatní platformy
Application.Terminate;
{$ENDIF}
end;
end);
end;

procedure TTabbedForm.FormGesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
{$IFDEF ANDROID}
case EventInfo.GestureID of
sgiLeft:
begin
if TabControl1.ActiveTab <> TabControl1.Tabs[TabControl1.TabCount-1] then
TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex+1];
Handled := True;
end;

sgiRight:
begin
  if TabControl1.ActiveTab <> TabControl1.Tabs[0] then
    TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex-1];
  Handled := True;
end;

end;
{$ENDIF}
end;

end.

Hi,

The TMSFNCWXCamera is using the MediaDevices.getUserMedia() API. It will return a list of camera devices available and select one on its own. Auto focus is working by default if the selected camera device itself is capable of auto focusing.

The problem is, currently it's impossible to tell the API to select an auto focus capable camera device when requesting one. If the camera that is selected automatically for you (or the camera you select yourself) does not have an auto focus option then you can't force it to do the focusing as it does not support it.

Can you try cycling through the camera devices and see if any of them will auto focus for you? Keep in mind this needs an internet connection. See here:

We will need to duplicate this in TTMSFNCWXQRDecoder, but you can also read some of the tips here that can improve the reading success: