微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 TTakePhotoFromCameraAction.OnDidFinishTaking 事件在 Android 10 上不起作用?

如何解决为什么 TTakePhotoFromCameraAction.OnDidFinishTaking 事件在 Android 10 上不起作用?

使用 Delphi 10.4.2 FireMonkey,针对 Android 10 x64。

我正在尝试拍照并保存以供日后处理。

首先我尝试使用内置的 TTakePhotoFromCameraAction,但是 OnDidFinishTaking 事件不起作用(相机屏幕可见,我可以拍照并按“确定”) ,我的程序出现了,但我的 TakePhotoFinishTaking() 方法没有被调用

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,'TakePhotoFinishTaking');
end;

接下来我尝试直接使用 IFMXCameraService

procedure TMainForm.btKameraClick(Sender: TObject);
var
  Service: IFMXCameraService;
  Params : TParamsPhotoQuery;
begin
  DebugEnter(0,'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!',0)
  end;
  DebugLeave(0,'btKameraClick');
end;

相同的结果:我看到相机屏幕,拍照,按确定,我的程序回来了,但没有 OnDidFinishTaking 事件。

然后我尝试拦截来自照片应用的消息:

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

所有 subcribetoMessage() 调用都返回一个 ID,但从未为这些类型调用 HandleMessage()

此消息(例如)运行良好!

FOrientationChangedId     := TMessageManager.DefaultManager.SubscribetoMessage(TOrientationChangedMessage,HandleMessage);
procedure TMainForm.HandleMessage(const Sender: TObject; const Msg: TMessage);
var
  ImgPath : String;
begin
  DebugEnter(0,'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}

我做错了什么?

解决方法

您的应用未收到 TMessageDidFinishTakingImageFromCamera 消息的原因是,如果 OnDidFinishTaking 分配给 Params,则消息不会发送,如 {{1} 中的代码}:

FMX.MediaLibrary.Android

以下代码与您的代码基本相同,对我使用 Delphi 10.4.2 时效果很好:

procedure TImageManagerAndroid.DidReceiveBitmap(const Sender: TObject; const M: TMessage);
var
  ImagePath: string;
  Photo: TBitmap;
  RequestCode: Integer;
begin
  if M is TMessageReceivedImagePath then
  begin
    ImagePath := TMessageReceivedImagePath(M).Value;
    RequestCode := TMessageReceivedImagePath(M).RequestCode;
    Photo := TBitmap.CreateFromFile(ImagePath);
    try
      if Assigned(FParams.OnDidFinishTaking) then
        FParams.OnDidFinishTaking(Photo)
      else
      begin
        if RequestCode = TJFMXMediaLibrary.JavaClass.ACTION_TAKE_IMAGE_FROM_CAMERA then
          TMessageManager.DefaultManager.SendMessage(Self,TMessageDidFinishTakingImageFromCamera.Create(Photo));
        if RequestCode = TJFMXMediaLibrary.JavaClass.ACTION_TAKE_IMAGE_FROM_LIBRARY then
          TMessageManager.DefaultManager.SendMessage(Self,TMessageDidFinishTakingImageFromLibrary.Create(Photo));
      end;
    finally
      Photo.Free;
    end;
  end;
end;
,

好的 - 问题解决了。 这是一个旧的 Projekt,在 Androidmanifest-template.xml 的应用程序节点中缺少选项 android:requestLegacyExternalStorage="true"。

解决此问题后一切正常,即使是带有 ObDidFinishTaking 事件的 TakePhotoFromCameraAction。

不幸的是,执行时没有错误或异常...

感谢@Dave 为我指明了正确的方向!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。