Delphi 11, FMX, открыть файл зная его Path

Рейтинг: 2Ответов: 0Опубликовано: 25.08.2023

Ситуация следующая: пишу небольшое приложение под андроид на Delphi. Несколько форм с данными и возможность прикрепить файлы или сделать фотографию. После заполнения содержимое нужно отправлять на сервер. Все это уже работает, могу сделать фото и отправить его. Но нужно еще иметь возможность выбрать любой файл на самом устройстве, просмотреть его в любой момент и отправить. Это могут быть фото, видео или документы. Диалог выбора файла открывается, событие выбора тоже срабатывает и я получаю 1 или несколько выбранных файлов (Uri). А дальше мне нужно в таблицу прописать имя и путь файла (чтобы в дальнейшем его открыть или переслать), и тут не могу двинуться с места. Имя файла получаю, а вот путь возвращает только вида "\image:123456" или "\document:image\img1234.jpg". Насколько я понял, андроид не любит выдавать (явки и пароли) реальные пути, где лежат файлы. Вернее есть вроде примеры, как можно получить путь через Cursor, но я не могу найти примеров на Delphi. Если у кого-то была похожая задача, поделитесь примером кода открытия и получения содержимого файла (для передачи по https в формате base64).

Функция получения имени файла

function GetFileName(Uri: Jnet_Uri): String;
var
  Cur: JCursor;
begin
  Result := '';
  Cur := TAndroidHelper.Context.getContentResolver().query(Uri, nil, nil, nil, nil, nil);
  try
    if (Cur <> nil) then
      if Cur.moveToFirst then
        Result := JStringToString(Cur.getString(cur.getColumnIndex(TJOpenableColumns.JavaClass.DISPLAY_NAME)));
  finally
    Cur.close;
  end;
end;

Выбор файла(ов):

procedure TDM.GetFileBrowser(ReqCode: Integer);
var
  Intent: JIntent;
  FName: String;
  F: JFile;
begin
  Intent := TJIntent.Create;

  Intent.setType(StringToJString('*/*'));
  Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE,true);

  TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification,
    procedure(const Sender   : TObject;
              const aMessage : TMessage)
          var msgRES : TMessageResultNotification;
              i: Integer;
        begin
              msgRES:= TMessageResultNotification(aMessage);

              if msgRES.RequestCode=ReqCode then
                 if (msgRES.ResultCode=TJActivity.JavaClass.RESULT_OK) then
                 begin

                     URIfileTrn := msgRES.Value.getData(); //URI sing file selez

                     if URIfileTrn = nil then //multiselez
                     begin
                        ClipDataF := msgRES.Value.getClipData;
                        for i := 0 to ClipDataF.getItemCount-1 do
                        begin
                          URIfileTrn := ClipDataF.getItemAt(i).getUri;
                          FName := GetFileName(URIfileTrn);
                          F := TJFile.JavaClass.init(URIfileTrn.getPath);
                          //F.getAbsolutePath;
                          if FName <> '' then
                            case ReqCode of
                              1000: SaveFile(FName, JStringToString(F.getAbsolutePath));
                              2000: SaveSFile(FName, JStringToString(F.getAbsolutePath));
                            end;
                        end;
                     end
                     else begin
                       FName := GetFileName(URIfileTrn);
                       F := TJFile.JavaClass.init(URIfileTrn.getPath);
                       if FName <> '' then
                         case ReqCode of
                            1000: SaveFile(FName, JStringToString(F.getAbsolutePath));
                            2000: SaveSFile(FName, JStringToString(F.getAbsolutePath));
                         end;
                     end;

                     URIfileTrn := nil;
                 end;
        end);

  TAndroidHelper.Activity.startActivityForResult(Intent, ReqCode);
end;

Открытие файла

procedure TDM.openFile(FileName: String); (* PdfDosyasiSec *)
var
  ExtFile: string;
  mime: JMimeTypeMap;
  ExtToMime: JString;
  Intent: JIntent;
  pathN:string;
  Uri: Jnet_Uri;
  LAuthority: JString;
begin
  if DM.qFiles.IsEmpty then
    Exit;
  if not TFile.Exists(FileName) then
  begin
      TDialogService.MessageDialog('Файл не существует (возможно был удален или перемещен). Удалить запись о файле из таблицы?', System.UITypes.TMsgDlgType.mtInformation,
        [System.UITypes.TMsgDlgBtn.mbYes, System.UITypes.TMsgDlgBtn.mbNo],
        System.UITypes.TMsgDlgBtn.mbNo, 0,

      // Use an anonymous method to make sure the acknowledgment appears as expected.
      procedure(const AResult: TModalResult)
      begin
        case AResult of
          { Detect which button was pushed and show a different message }
          mrYES: begin
                  DM.qFiles.Delete;
                  Exit;
          end;
          mrNo: Exit;
        end;
      end);
  end;
  try
    ExtFile := AnsiLowerCase(StringReplace(TPath.GetExtension(FileName), '.', '',[]));
    mime := TJMimeTypeMap.JavaClass.getSingleton();
    ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));
    LAuthority := StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider');
    Uri := TJcontent_FileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, LAuthority, TJFile.JavaClass.init(StringToJString(FileName)));
    Intent := TJIntent.Create;
    Intent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
    Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
    Intent.setDataAndType(Uri, ExtToMime);
    TAndroidHelper.Activity.startActivity(Intent);
  except
    ShowMessage('Невозможно открыть файл!');
  end
end;

Ответы

Ответов пока нет.