Delphi Rio fails to read external storage with READ_EXTERNAL_STORAGE permissions set

前端 未结 1 1376
名媛妹妹
名媛妹妹 2020-12-07 02:01

I have a project that I once created in Delphi Seattle and I would now like to move to Delphi Rio. I read the directory structure on an external SD-Card using findfirst/find

相关标签:
1条回答
  • 2020-12-07 02:20

    Android OS introduced Runtime Permissions model since API 23.

    That means in addition to specifying permission in Manifest, you also need to ask user for granting you permission for so called dangerous permissions at runtime. User has a choice to give you permission when asked, but it can also revoke that permission at any time.

    Whenever your application deals with code that needs runtime permission it must verify that user granted you that permission and be prepared to deal with situation where user didn't gave you the permission.

    READ_EXTERNAL_STORAGE is one of them.

    Overview of different permissions (including their classification) can be found at Permissions overview

    To upload your application on Google Play Store, your application needs to support minimum API 26 (for the moment) and Delphi Rio by default targets new API levels. It also introduces support for asking permissions at runtime.

    Following is basic example that asks for READ_EXTERNAL_STORAGE permission and reads files from shared downloads folder.

    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;
    
    0 讨论(0)
提交回复
热议问题