Daniele
Daniele

Reputation: 53

Delphi 11, Android, directory file list

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

Answers (1)

Freddie Bell
Freddie Bell

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

Related Questions