Delphi Rio无法使用READ_EXTERNAL_STORAGE权限设置读取外部存储

And*_*bel 7 delphi sdk android findfirst delphi-10.3-rio

我有一个项目,我曾经在Delphi西雅图创建,现在我想转移到Delphi Rio.我使用findfirst/findnext读取外部SD卡上的目录结构

  i := findfirst(datadir + '*', faanyfile, ts);
Run Code Online (Sandbox Code Playgroud)

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

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

如果我将清单文件中的targetSdkVersion(在Rio中自动设置为26)硬编码到19(这是minSdkVersion),代码再次工作,即使在里约.所以显然处理SD卡访问的一些方法已经从sdk-level 19变为26?

有人提示吗?

Dal*_*kar 10

自从API 23起,Android OS引入了Runtime Permissions模型.

这意味着除了在Manifest中指定权限之外,还需要让用户在运行时授予您对所谓的危险权限的权限.用户可以选择在被询问时给予您许可,但也可以随时撤销该权限.

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

READ_EXTERNAL_STORAGE 是其中之一.

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

要在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;
Run Code Online (Sandbox Code Playgroud)

  • @DaveNottage,您是否忘记了外部URI问题究竟是什么?尝试在应用程序之外共享URI时,需要完成安全文件共享权利和提供程序.这个问题只是简单地访问外部存储,这只需要一个权限. (2认同)