如何在Delphi Android应用程序中调用本机摄像头?

Kro*_*ica 4 delphi camera android firemonkey delphi-10.3-rio

我正在使用Delphi 10.3 Community Edition编写一个简单的Android应用程序,并尝试调用本机设备摄像头,但是却出现错误。

我正在遵循官方的Delphi 指南

在表单设计器上,选择按钮(用于拍照)。在对象检查器中,选择“动作”属性的下拉列表。选择新标准动作| 媒体库| TTakePhotoFromCameraAction:

在“事件”选项卡上,展开“操作”节点,然后双击“ OnDidFinishTaking”事件。

将以下代码添加到OnDidFinishTaking事件处理程序中:

procedure TForm1.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);
begin
  Image1.Bitmap.Assign(Image);
end;
Run Code Online (Sandbox Code Playgroud)

此代码将从移动设备照相机拍摄的图片分配给TImage组件的Bitmap属性。

我已经验证了Project | 选项| 使用权限-相机设置设为true。我也要求启动该应用程序所需的权限。在Debug或Release中运行没有区别。

但是有一个问题。当单击按钮时,出现以下错误消息:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“ android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager,java.lang.String)”。

这是我为最简单的测试应用程序编写的代码:

unit Unit1;
interface
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Permissions,
  FMX.StdCtrls, FMX.MediaLibrary, FMX.Platform, System.Messaging, FMX.Objects,
  System.Actions, FMX.ActnList, FMX.StdActns, FMX.MediaLibrary.Actions,
  FMX.Controls.Presentation;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ActionList1: TActionList;
    TakePhotoFromCameraAction1: TTakePhotoFromCameraAction;
    procedure FormCreate(Sender: TObject);
  private
    procedure PermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>);
    procedure DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc);
  end;

var
  Form1: TForm1;

implementation
uses
{$IFDEF ANDROID}
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.Os,
{$ENDIF}
  FMX.DialogService;

{$R *.fmx}

procedure TForm1.PermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>);
begin
  // 3 permission involved
  if (Length(AGrantResults) = 3)
  and (AGrantResults[0] = TPermissionStatus.Granted)
  and (AGrantResults[1] = TPermissionStatus.Granted)
  and (AGrantResults[2] = TPermissionStatus.Granted) then
  else
    ShowMessage('Required permission has not been granted') ;
end;

procedure TForm1.DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc);
begin
  TDialogService.ShowMessage('Need to access the camera',
    procedure(const AResult: TModalResult)
    begin
      APostRationaleProc;
    end);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  permCam, permRead, permWrite: string;
begin
  // Request permissions
  permCam := JStringToString(TJManifest_permission.JavaClass.CAMERA);
  permRead := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE);
  permWrite := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE);
  PermissionsService.RequestPermissions([permCam, permRead, permWrite], PermissionRequestResult, DisplayRationale);
end;

end.
Run Code Online (Sandbox Code Playgroud)

如何使本机相机TTakePhotoFromCameraAction正常工作?

Dav*_*age 5

检查“项目选项”>“权利列表”>“安全文件共享”选项是否设置为true

  • 您很有可能拥有一个不带&lt;%provider%&gt;标记的AndroidManifest.template.xml,因为您的应用程序是使用早期版本的Delphi创建的。您可以在&lt;%application-meta-data%&gt;标记上方手动添加它 (2认同)