我有一个项目,我曾经在Delphi西雅图创建,现在我想转移到Delphi Rio.
我使用findfirst / findnext读取外部SD卡上的目录结构
我使用findfirst / findnext读取外部SD卡上的目录结构
i := findfirst(datadir + '*',faanyfile,ts);
datadir变量包含一个有效的目录.在西雅图,代码工作正常(返回值i = 0),并在变量ts中返回第一个目录条目.
现在,在Rio上编译相同的代码,我得到一个返回错误值i = 13(访问被拒绝).
在我的项目中设置了READ_EXTERNAL_STORAGE权限.
如果我将清单文件中的targetSdkVersion(在Rio中自动设置为26)硬编码到19(这是minSdkVersion),代码再次工作,即使在里约.
所以显然处理SD卡访问的一些方法已经从sdk-level 19变为26?
有人提示吗?
解决方法
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;