Delphi 11, FMX, открыть файл зная его Path
Ситуация следующая: пишу небольшое приложение под андроид на 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;