Reputation: 53
I'm trying to get a directory files list in order to have a list and, later, choose one under android and delphi 11.0. After severals long search (here) and unsuccessful tries at the end i found this post.
Delphi Rio fails to read external storage with READ_EXTERNAL_STORAGE permissions set
Where Dalija gave this code:
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)
This code works great under delphi 10.4 update 2 but not under delphi 11.0
Why ??
I'm not able to run it on 11.0 (with new procedure's syntax, i.e APermissions: TArray<string>
in delphi 10.4 now is APermissions: TClassicStringDynArray
in delphi 11)
Thank's for any help
Daniele
Upvotes: 3
Views: 1773
Reputation: 2287
Embarcadero changed the function signatures with the release of Delphi 11. This will get you started with sorting that out.
{$if COMPILERVERSION > 34}
{$define NEW_ALEX}
{$else}
{$if COMPILERVERSION > 32}
{$define NEW_RIO}
{$endif}
{$endif}
private
FPermittoVibrate: Boolean;
FVibratePermission: String;
FPermitAccessFineLocation: Boolean;
FAccessFineLocation: String;
FPermitNetworkState: Boolean;
FNetworkStatePermission: String;
FPermitWifiState: Boolean;
FWifiStatePermission: String;
FPermitPhoneState: Boolean;
FPhoneStatePermission: String;
{$ifdef NEW_RIO}
procedure PermissionResult(Sender: TObject;
const APermissions: TArray<string>;
const AGrantResults: TArray<TPermissionStatus>);
procedure PermissionRequest(Sender: TObject;
const APermissions: TArray<string>;
const APostRationaleProc: TProc);
{$endif}
{$ifdef NEW_ALEX}
procedure PermissionsResult(Sender: TObject;
const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray
);
procedure DisplayRationale(Sender: TObject;
const APermissions: TClassicStringDynArray;
const APostRationaleProc: TProc);
{$endif}
{$ifdef NEW_RIO}
if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then // 6 or higher
begin
PermissionsService.RequestPermissions([
FVibratePermission
, FAccessFineLocation
, FNetworkStatePermission
, FWifiStatePermission
, FPhoneStatePermission
],
PermissionResult, PermissionRequest
);
end;
{$endif}
{$ifdef NEW_ALEX}
if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then // 6 or higher
begin
PermissionsService.RequestPermissions([
FVibratePermission
, FAccessFineLocation
, FNetworkStatePermission
, FWifiStatePermission
, FPhoneStatePermission
],
PermissionsResult, DisplayRationale
);
end;
{$endif}
{$ifdef NEW_RIO}
procedure TfrmMain.PermissionRequest(Sender: TObject;
const APermissions: TArray<string>; const APostRationaleProc: TProc);
var
I: Integer;
RationaleMsg: string;
begin
RationaleMsg := 'The app needs ';
for I := 0 to High(APermissions) do
begin
if APermissions[I] = FVibratePermission then
RationaleMsg := RationaleMsg + 'to vibrate the phone' + linefeed;
if APermissions[I] = FAccessFineLocation then
RationaleMsg := RationaleMsg + linefeed + 'to access fine location';
if APermissions[I] = FNetworkStatePermission then
RationaleMsg := RationaleMsg + linefeed + 'to access network state';
if APermissions[I] = FWifiStatePermission then
RationaleMsg := RationaleMsg + linefeed + 'to access wifi state';
if APermissions[I] = FPhoneStatePermission then
RationaleMsg := RationaleMsg + linefeed + 'to read phone state';
end;
TDialogService.ShowMessage(RationaleMsg,
procedure(const AResult: TModalResult)
begin
APostRationaleProc;
end)
end;
procedure TfrmMain.PermissionResult(Sender: TObject;
const APermissions: TArray<string>;
const AGrantResults: TArray<TPermissionStatus>);
var
Permission: String;
i: Integer;
begin
for i := 0 to High(APermissions) do
begin
Permission := APermissions[i];
if Permission = FVibratePermission then
FPermitToVibrate := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FAccessFineLocation then
FPermitAccessFineLocation := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FNetworkStatePermission then
FPermitNetworkState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FWifiStatepermission then
FPermitWifiState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FPhoneStatePermission then
FPermitPhoneState := AGrantResults[i] = TPermissionStatus.Granted
;
end;
end;
{$endif NEW_RIO}
{$ifdef NEW_ALEX}
procedure TfrmMain.PermissionsResult(Sender: TObject;
const APermissions: TClassicStringDynArray;
const AGrantResults: TClassicPermissionStatusDynArray
);
var
Permission: String;
i: Integer;
begin
for i := 0 to High(APermissions) do
begin
Permission := APermissions[i];
if Permission = FVibratePermission then
FPermitToVibrate := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FAccessFineLocation then
FPermitAccessFineLocation := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FNetworkStatePermission then
FPermitNetworkState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FWifiStatepermission then
FPermitWifiState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FPhoneStatePermission then
FPermitPhoneState := AGrantResults[i] = TPermissionStatus.Granted
end;
end;
procedure TfrmMain.DisplayRationale(Sender: TObject;
const APermissions: TClassicStringDynArray;
const APostRationaleProc: TProc);
var
I: Integer;
RationaleMsg: string;
begin
RationaleMsg := 'The app needs ';
for I := 0 to High(APermissions) do
begin
if APermissions[I] = FVibratePermission then
RationaleMsg := RationaleMsg + 'to vibrate the phone' + SLineBreak;
if APermissions[I] = FAccessFineLocation then
RationaleMsg := RationaleMsg + SLineBreak + 'to access fine location';
if APermissions[I] = FNetworkStatePermission then
RationaleMsg := RationaleMsg + SLineBreak + 'to access network state';
if APermissions[I] = FWifiStatePermission then
RationaleMsg := RationaleMsg + SLineBreak + 'to access wifi state';
if APermissions[I] = FPhoneStatePermission then
RationaleMsg := RationaleMsg + SLineBreak + 'to read phone state';
end;
TDialogService.ShowMessage(RationaleMsg,
procedure(const AResult: TModalResult)
begin
APostRationaleProc;
end)
end;
{$endif NEW_ALEX}
Upvotes: 2