Delphi Rio не может прочитать внешнее хранилище с установленными разрешениями READ_EXTERNAL_STORAGE - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть проект, который я когда-то создал в Delphi Seattle, и теперь я хотел бы переехать в Delphi Rio.Я прочитал структуру каталогов на внешней SD-карте, используя переменную findfirst / findnext

  i := findfirst(datadir + '*', faanyfile, ts);

, содержащую допустимый каталог.В Сиэтле код работает нормально (возвращаемое значение i = 0), и первая запись каталога возвращается в переменной ts.Теперь, компилируя тот же код в Rio, я получаю значение ошибки возврата i = 13 (доступ запрещен).

В моем проекте установлено разрешение READ_EXTERNAL_STORAGE.

Если я жестко закодирую targetSdkVersion вфайл манифеста (который автоматически устанавливается на 26 в Rio) до 19 (который является minSdkVersion), код работает снова, даже в Rio.Очевидно, что какой-то способ обработки доступа к SD-карте изменился с уровня SDK 19 на 26?

Кто-нибудь намекает на кого-то?

1 Ответ

0 голосов
/ 02 декабря 2018

Представлена ​​ОС Android Разрешения времени выполнения * Модель 1002 * начиная с API 23.

Это означает, что в дополнение к указанию разрешения в Manifest вам также необходимо запросить у пользователя разрешение на так называемые опасные разрешенияво время выполнения.Пользователь может дать вам разрешение на запрос, но он также может отозвать это разрешение в любое время.

Всякий раз, когда ваше приложение имеет дело с кодом, для которого требуется разрешение во время выполнения, оно должно убедиться, что пользователь предоставил вам это разрешение, и быть готовым справиться с ситуацией, когда пользователь не дал вам разрешения.

READ_EXTERNAL_STORAGE является одним из них.

Обзор различных разрешений (включая их классификацию) можно найти по адресу Обзор разрешений

Чтобы загрузить свое приложение в Google Play Store, ваше приложениедолжен поддерживать минимум 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;
...