In Delphi 10.4, I was able to get a listing of files in an Android device's shared storage. In Delphi 11, with necessary permission set (either programmatically or on the device), TDirectory.GetFiles()
is returning an empty list (ie. zero entries).
TDirectory.GetDirectories()
is working correctly, and using TFile.Exists()
with a filename which I know to be present returns true. But, if I try to open that file with, for instance, TFile.ReadAllText()
, access is denied. Any suggestions?
This is an example program which fails in Delphi 11:
uses
System.Types,System.Classes,system.sysUtils,system.IOUtils,system.Permissions,
{$IFDEF ANDROID}
Androidapi.Helpers,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Os,
{$ENDIF}
FMX.Types,FMX.Forms,FMX.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
fOK:boolean;
procedure PermissionsResult(Sender: TObject;
const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray);
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure Tform1.PermissionsResult(Sender: TObject;
const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray);
var
n:integer;
begin
if length(AGrantResults)>0 then
for n:=0 to length(AGrantResults)-1 do
if not (AGrantResults[n] = TPermissionStatus.Granted) then fOK:=false;
end;
procedure FileList(dir:string;list:TstringList);
var
LList: TStringDynArray;
I: Integer;
begin
list.Clear;
Llist:=Tdirectory.GetFiles(dir);
if length(LList)>0 then
for I := 0 to Length(LList) - 1 do
list.Add(LList[I]);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
DataDir:string;
list:TstringList;
p:Tarray<string>;
begin
fOK:=true;
p:=[JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE),
JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)];
PermissionsService.RequestPermissions(p,PermissionsResult,nil);
if fOK then
begin
list:=TstringList.Create;
DataDir := TPath.GetSharedDocumentsPath;
showmessage(DataDir);
fileList(DataDir,list);
showmessage(inttostr(list.Count) ' ' list.Text);
list.Free;
end else showmessage('permission refused');
end;
end.
CodePudding user response:
On an Android 11 devices listFiles() will, depending on the exact public directory, list only files created by the app itself or some media files.
Do not only use TFile.Exists() but also TFile.CanRead() before you try to .. read.
CodePudding user response:
This will list files:
var
FileList: TStringDynArray;
myfileList: Tstringlist;
s: string;
DocDir: string;
begin
DocDir := TPath.GetSharedDocumentsPath;// or whatever path
FileList := TDirectory.GetFiles(DocDir);
myfileList := TStringList.Create;
for s in FileList do begin //get all items in folder
if Pos('.png',s) > 0 then begin
try
myfileList.Add(s);
except
//
end;
end;
end;
myfileList.Free;
end;