Search code examples
androiddelphifiremonkeymessagingphoto

Why is the TTakePhotoFromCameraAction.OnDidFinishTaking event not working on Android 10?


Using Delphi 10.4.2 FireMonkey, targeting Android 10 x64.

I'm trying to take a photo and save it for later processing.

First I've tried to use the built-in TTakePhotoFromCameraAction, but the OnDidFinishTaking event doesn't work (the camera screen is visible, I can take the photo and press "ok"), my program shows up, but my TakePhotoFinishTaking() method is not called.

procedure TMainForm.TakePhotoFinishTaking(Image: TBitmap);
begin
  DebugEnter(0, self, 'TakePhotoFinishTaking', [Image]);
  HidePopup;
  SetBilderActions(false);
  try
    PicGrid.RowCount := PicGrid.RowCount+1;
    InsertImageItem('', Image, PicGrid.RowCount-1);
  finally
    SetBilderActions(true);
  end;
  DebugLeave(0, self, 'TakePhotoFinishTaking');
end;

Next I tried to use IFMXCameraService directly:

procedure TMainForm.btKameraClick(Sender: TObject);
var
  Service: IFMXCameraService;
  Params : TParamsPhotoQuery;
begin
  DebugEnter(0, self, 'btKameraClick', [Sender]);
  if PermissionsService.IsEveryPermissionGranted([cPermissionCamera, cPermissionReadExternalStorage, cPermissionWriteExternalStorage]) then begin
    if TPlatformServices.Current.SupportsPlatformService(IFMXCameraService, Service) then begin
      Params.RequiredResolution := TSize.Create(640, 640);
      Params.Editable           := false;
      Params.NeedSaveToAlbum    := true;
      Params.OnDidFinishTaking  := TakePhotoFinishTaking;
      Params.OnDidCancelTaking  := NIL;
      Service.TakePhoto(NIL, Params);
    end else begin
      FMX.DialogService.ASync.TDialogServiceAsync.MessageDialog('Kamerafunktion wird auf diesem Gerät nicht unterstützt!', TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], TMsgDlgBtn.mbOK, 0)
    end;
  end else begin
    FMX.DialogService.ASync.TDialogServiceAsync.MessageDialog('Keine Kamera oder externer Speicher Rechte!', TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], TMsgDlgBtn.mbOK, 0)
  end;
  DebugLeave(0, self, 'btKameraClick');
end;

Same result: I see the camera screen, take a photo, press Ok, my program comes back, but no OnDidFinishTaking event.

Then I've tried to intercept the messages from the Photo app:

FFinishTakingCamPhotoId   := TMessageManager.DefaultManager.SubscribeToMessage(TMessageDidFinishTakingImageFromCamera,  HandleMessage);
FFinishTakingLibPhotoId   := TMessageManager.DefaultManager.SubscribeToMessage(TMessageDidFinishTakingImageFromLibrary, HandleMessage);
FMessageReceivedImagePath := TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedImagePath,               HandleMessage);

All of the subcribeToMessage() calls are returning an ID, but HandleMessage() is NEVER being called for these Types.

This Message (for example) is working very well!

FOrientationChangedId     := TMessageManager.DefaultManager.SubscribeToMessage(TOrientationChangedMessage,              HandleMessage);
procedure TMainForm.HandleMessage(const Sender: TObject; const Msg: TMessage);
var
  ImgPath : String;
begin
  DebugEnter(0, self, 'HandleMessage', [Sender, Msg]);

  {$IFDEF Android}
  if Msg is TMessageResultNotification then begin
    DebugMsg(0, 'TMessageResultNotification');
    OnActivityResult(TMessageResultNotification(Msg).RequestCode, TMessageResultNotification(Msg).ResultCode, TMessageResultNotification(Msg).Value);
  end;
  if Msg is TMessageDidFinishTakingImageFromCamera then begin
    DebugMsg(0, 'TMessageDidFinishTakingImageFromCamera');
    TakePhotoFinishTaking(TMessageDidFinishTakingImageFromCamera(Msg).Value);
  end;
  if Msg is TMessageReceivedImagePath then begin
    DebugMsg(0, 'TMessageReceivedImagePath');
    ImgPath := TMessageReceivedImagePath(Msg).Value;
  end;
  if Msg is TMessageDidFinishTakingImageFromLibrary then begin
    DebugMsg(0, 'TMessageDidFinishTakingImageFromLibrary');
    TakePhotoFinishTaking(TMessageDidFinishTakingImageFromLibrary(Msg).Value);
  end;
  {$ENDIF}

What am I doing wrong?


Solution

  • Ok - Problem solved. It was an old Projekt and that was missing the option android:requestLegacyExternalStorage="true" in the application node of Androidmanifest-template.xml.

    After fixing this all works fine, even the TakePhotoFromCameraAction with ObDidFinishTaking Event.

    Unfortunately there is no Error or Exception where executed...

    Thanks @Dave for pointing me in the right direction!