【问题标题】:Delphi Rio fails to read external storage with READ_EXTERNAL_STORAGE permissions setDelphi Rio 无法读取设置了 READ_EXTERNAL_STORAGE 权限的外部存储
【发布时间】:2019-05-03 22:23:49
【问题描述】:

我曾经在西雅图德尔福创建了一个项目,现在我想搬到德尔福里约。 我使用 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?

有什么提示吗?

【问题讨论】:

  • 如果您在西雅图创建应用程序,并将其迁移到 Rio,您需要将 添加到 AndroidManifest.template.xml 中的 之前,并检查项目选项中权利列表中的安全文件共享选项
  • @DaveNottage Dalija 下面的回答是处理 API 23 及更高版本(Rio 针对)的权限的方法。请注意,RequestPermissions 接受权限字符串数组,以防您需要一次请求多个权限。

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


【解决方案1】:

Android OS 从 API 23 开始引入Runtime Permissions 模型。

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

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

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;

【讨论】:

  • 这个问题与权限无关,与访问外部URI有关。
  • 对我来说,看起来 Dalija 是对的。她给出的解决方案对我有用。
  • @DaveNottage,您是否忘记了外部 URI 问题实际上是什么?尝试在您的应用程序之外共享 URI 时,需要完成安全文件共享权利和提供程序。这个问题都是关于简单地访问外部存储,它只需要一个权限。
  • 同意;我的错。
  • @DaveNottage 不要为此感到难过 :)
猜你喜欢
  • 2020-06-19
  • 2017-08-26
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多