Delphi Rio 无法读取设置了 READ_EXTERNAL_STORAGE 权限的外部存储
Delphi Rio fails to read external storage with READ_EXTERNAL_STORAGE permissions set
我有一个曾经在 Delphi 西雅图创建的项目,现在我想搬到 Delphi 里约热内卢。
我使用 findfirst/findnext
读取外部 SD 卡上的目录结构
i := findfirst(datadir + '*', faanyfile, ts);
datadir 变量包含有效目录。在西雅图,代码运行良好(return 值 i=0)并且第一个目录条目在变量 ts 中 returned。
现在,在 Rio 上编译相同的代码,我得到一个 return 错误值 i=13(访问被拒绝)。
我的项目中设置了权限READ_EXTERNAL_STORAGE。
如果我将清单文件中的 targetSdkVersion(在 Rio 中自动设置为 26)硬编码为 19(即 minSdkVersion),代码将再次运行,即使在 Rio 中也是如此。
显然,处理 sd 卡访问的某种方式已从 sdk 级别 19 更改为 26?
有什么提示吗?
Android OS 自 API 23 年以来引入了 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;
我有一个曾经在 Delphi 西雅图创建的项目,现在我想搬到 Delphi 里约热内卢。 我使用 findfirst/findnext
读取外部 SD 卡上的目录结构 i := findfirst(datadir + '*', faanyfile, ts);
datadir 变量包含有效目录。在西雅图,代码运行良好(return 值 i=0)并且第一个目录条目在变量 ts 中 returned。 现在,在 Rio 上编译相同的代码,我得到一个 return 错误值 i=13(访问被拒绝)。
我的项目中设置了权限READ_EXTERNAL_STORAGE。
如果我将清单文件中的 targetSdkVersion(在 Rio 中自动设置为 26)硬编码为 19(即 minSdkVersion),代码将再次运行,即使在 Rio 中也是如此。 显然,处理 sd 卡访问的某种方式已从 sdk 级别 19 更改为 26?
有什么提示吗?
Android OS 自 API 23 年以来引入了 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;