【问题标题】:How to invoke native camera in Delphi Android application?如何在 Delphi Android 应用程序中调用本机相机?
【发布时间】:2019-05-18 15:39:20
【问题描述】:

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

我在关注德尔福官方guide

在表单设计器上,选择按钮(用于拍照)。 在 Object Inspector 中,选择 Action 属性的下拉列表。 选择新标准动作 |媒体库 | TtakePhotoFromCameraAction:

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

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

procedure TForm1.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);
begin
  Image1.Bitmap.Assign(Image);
end;

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

我已验证该项目 |选项 |使用权限 - 相机设置设置为 true。我也在申请启动应用所需的权限。在 Debug 和 Release 中运行没有区别。

但是有一个问题。单击按钮时,我收到以下错误消息:

java.lang.NullPointerException:尝试在 null 上调用虚拟方法 '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.

如何让原生相机TTakePhotoFromCameraAction工作?

【问题讨论】:

标签: android delphi camera firemonkey delphi-10.3-rio


【解决方案1】:

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

【讨论】:

  • 我也有同样的问题。我已经检查了安全文件共享选项,但我收到了 Kromster 提到的错误消息。我想还需要别的东西。
  • 您的 AndroidManifest.template.xml 很可能没有 标记,因为您的应用是使用较早版本的 Delphi 创建的。您可以手动添加它,就在 标签之上
  • 没有内容 - 当您部署应用程序时,IDE 会将其填充到 AndroidManifest.xml 中。如果创建应用程序时标签不存在,请检查它是否存在于文件 C:\Users(yourusername)\AppData\Roaming\Embarcadero\BDS\20.0\AndroidManifest.xml 中,这是 Delphi 用于创建 AndroidManifest 的文件。模板.xml。如果标签不存在,则可能意味着您之前在机器上安装了 beta 版本
  • 我不知道为什么,但是有了新的编译,标签就在那里并且应用程序运行良好(它可以毫无问题地拍照)。非常感谢
  • 感谢它的工作!这是缺少的 标记。我之前在 10.2 中构建。升级到 10.3 后,清单文件中似乎缺少它。在项目目录中还有一个清单文件,所以我建议也编辑它。
【解决方案2】:

对于将项目从旧版本移植到 10.3 的任何人,请确保您的 AndroidManifest.xml 在 标记上方包含 标记。

我在其他方面发现了很多 cmets,这里建议可以在此处找到此文件:

C:\Users\(yourusername)\AppData\Roaming\Embarcadero\BDS\20.0\AndroidManifest.xml

但如果这不起作用,那么您的源目录中可能已经有一个AndroidManifest.template.xml 文件。如果是这种情况,那么编译器将使用此模板文件并忽略 AppData 文件夹中的文件!

【讨论】:

    【解决方案3】:

    我遇到了一些问题,Android 9 可以运行,但某些运行 Android 10 的设备不能运行。我需要执行上面列出的答案中的步骤,但在我添加之前我的仍然无法正常工作:

    android:requestLegacyExternalStorage="true"

    到我的 AndroidManifest.template.xml 的应用程序部分

    【讨论】:

      猜你喜欢
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      相关资源
      最近更新 更多