Delphi Rio无法读取设置了READ_EXTERNAL_STORAGE权限的外部存储

时间:2018-12-02 11:55:16

标签: android delphi sdk findfirst delphi-10.3-rio

我有一个我曾经在西雅图德尔福(Delphi Seattle)创建的项目,现在我想搬到德尔福里约(Delphi Rio)。 我使用findfirst / findnext

读取了外部SD卡上的目录结构
  i := findfirst(datadir + '*', faanyfile, ts);

datadir变量包含一个有效目录。在西雅图,代码工作正常(返回值i = 0),并且第一个目录条目在变量ts中返回。 现在,在Rio上编译相同的代码,我得到一个返回错误值i = 13(访问被拒绝)。

在我的项目中设置了权限READ_EXTERNAL_STORAGE。

如果我将清单文件中的targetSdkVersion硬编码(在Rio中自动设置为26)到19(即minSdkVersion),则即使在Rio中,代码也可以再次工作。 因此,显然处理SD卡访问权限的某种方式已从SDK级别19更改为26?

有人暗示某人吗?

1 个答案:

答案 0 :(得分:10)

Android OS introduced Runtime Permissions模型中复制

这意味着除了在清单中指定权限外,还需要请求用户在运行时授予您所谓的危险权限的权限。用户可以在询问时选择授予您权限,但也可以随时撤消该权限。

每当您的应用程序处理需要运行时权限的代码时,它都必须验证用户是否已授予您该权限,并准备处理用户未授予您权限的情况。

READ_EXTERNAL_STORAGE是其中之一。

可以在Permissions overview上找到不同权限的概述(包括其分类)

要将您的应用程序上传到Google Play商店,您的应用程序目前需要支持最低API 26,并且默认情况下,Delphi Rio的目标是新的API级别。它还引入了对在运行时询问权限的支持。

以下是一个基本示例,要求获得READ_EXTERNAL_STORAGE权限并从共享下载文件夹中读取文件。

uses
  System.Permissions,
  Androidapi.Helpers,
  Androidapi.JNI.App,
  Androidapi.JNI.OS,
  ...

procedure TMainForm.AddFiles;
var
  LFiles: TArray<string>;
  LFile: string;
begin
  LFiles := TDirectory.GetFiles(TPath.GetSharedDownloadsPath);
  for LFile in LFiles do
    begin
      Memo1.Lines.Add(LFile);
    end;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
  PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE)],
    procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
    begin
      if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
        begin
          Memo1.Lines.Add('GRANTED');
          AddFiles;
        end
      else
        begin
          Memo1.Lines.Add('NOT GRANTED');
        end;
    end)
end;