Jump to content
Sign in to follow this  
Stas

[TfgOpenDialog] Диалог выбора файлов или каталогов

Recommended Posts

Так, диалог я вызвал, но как получить результат, мне непонятно,

у FMX есть TFMXNativeActivityListener

Что там у FGX пока неизвестно.

Share this post


Link to post
Share on other sites

В FGX Native в андроид реализации идет широковещательная рассылка двух сообщений (FGX.Platform.Android). На них (в соответствии с тем, что вам нужно) надо подписаться через System.Messaging:

  TfgActivityResultMessage = class(TMessage)
  public
    RequestCode: Integer;
    ResultCode: Integer;
    Data: TJIntent;
  end;

  TfgActivityNewIntentMessage = class(TMessage<TJIntent>);

 

Share this post


Link to post
Share on other sites

Теперь следующий вопрос

Вот так вызываю

procedure TfgOpenDialog.Show(CallBack: TProc<TObject>);
var
  Intent: TJIntent;
begin
  FProc:=Proc;

  Intent:=TJIntent.Create;
  Intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
  Intent.setAction(TJIntent.ACTION_GET_CONTENT);
  Intent.setType(StringToJString(MimeType));
  TfgAndroidHelper.Activity.startActivityForResult(Intent,5);
end;

Вот так получаю

procedure TfgOpenDialog.ResultCallback(const Sender: TObject; const M: TMessage);
begin
  if TfgActivityResultMessage(M).RequestCode = 5 then
  if TfgActivityResultMessage(M).ResultCode = TJActivity.RESULT_OK then
  begin
    Jc:=TfgActivityResultMessage(M).Data.getClipData();
   TfgDialogs.ShowMessage(IntToStr(Jc.getItemCount));
end;

И вот тут вопрос, как получить один объект ?

Т.е. где 

function getItemAt(&index : Integer) : JClipData_Item; cdecl;

Спасибо

З,Ы. Выложу как вылижу

Edited by Stas
Отформатировал код

Share this post


Link to post
Share on other sites

В релизе 1.0.3.0 в хедеры AndroidAPI добавлены оболочки для типа TJClipData_Item. Теперь эти методы будут доступны.

  • Thanks 1

Share this post


Link to post
Share on other sites

Фух, спасибо, я начал строить мосты, почище Крымского, и понимаю, что Вам это сделать гораздо проще

Share this post


Link to post
Share on other sites

Через часик релиз выложу.

На будущее. Обертки для Android API я генерирую обычно по мере необходимости. Если в будущем вам будет чего-то не хватать в них, дайте мне знать. Я их сразу добавлю. В будущем будет доступна специальная тулза, которая генерирует эти хедеры.

  • Thanks 1

Share this post


Link to post
Share on other sites

Ярослав, спасибо, я уверен,  что будет не хватать, я не буду ждать компонентов, но мосты...

Кстати, от Вас, знаю,  возможны, а к Вам ?

Пример будет полезен.

Edited by Stas

Share this post


Link to post
Share on other sites
3 минуты назад, Stas сказал:

Кстати, от Вас, знаю,  возможны, а к Вам ?

Пример будет полезен.

Ничего не понял.

Share this post


Link to post
Share on other sites

Каким образом Jnet_uri передать в TjUri (к примеру)

Имеется в виду объекты FMX в FGX

Edited by Stas

Share this post


Link to post
Share on other sites
34 минуты назад, Stas сказал:

Каким образом Jnet_uri передать в TjUri (к примеру)

Имеется в виду объекты FMX в FGX

P.S. Не забываем про правила форума. Одна тема - один вопрос.

Share this post


Link to post
Share on other sites

Волобуев, вот вам меч.

type

  TfgOpenDialog = class
  private
    FProc: TProc<boolean>;
    FMultiSelect: boolean;
    FFiles: TStrings;
    FMimeType: String;
    procedure ResultCallback(const Sender: TObject; const M: TMessage);
    procedure SetMultiSelect(const Value: boolean);
    procedure SetMimeType(const Value: String);
  public
    property Files:TStrings read FFiles;
    property MultiSelect:boolean read FMultiSelect write SetMultiSelect;
    property MimeType:String read FMimeType write SetMimeType;
    constructor Create;
    destructor Destroy; override;
    procedure Execute(Proc: TProc<boolean>);
  end;


constructor TfgOpenDialog.Create;
begin
 FFiles:=TStringList.Create;
  TMessageManager.DefaultManager.SubscribeToMessage(TfgActivityResultMessage, ResultCallback);
end;

destructor TfgOpenDialog.Destroy;
begin
  TMessageManager.DefaultManager.Unsubscribe(TfgActivityResultMessage, ResultCallback);
  FFiles.Free;
end;

procedure TfgOpenDialog.ResultCallback(const Sender: TObject; const M: TMessage);
var
   J:TJUri;
  function getFileName(Uri:TJUri):String;
  var c:JCursor;
  begin
  result:='';
  if (uri.getScheme().equalsIgnoreCase(StringToJString('content')))
  then
  begin
    c:=TfgAndroidHelper.Context.getContentResolver.query(uri,nil,nil,nil,nil);
    try
    if (c<>nil) and c.moveToFirst then
        result:=JStringToString(c.getString(c.getColumnIndex(StringToJString('_display_name') ) ))
    finally
    if (c<>nil) then
     c.close;
    end;
  end;
  if (result ='') then
    result:=JStringToString(uri.getPath());
 end;
  procedure UriToFile(uri:TJUri);
  var    i:integer;
         bt:byte;
         b:TJavaArray<Byte>;
         jis:TJInputStream;
         FilePath: string;
         ms:TMemoryStream;
  begin
  ms := TMemoryStream.Create;
  try
  jis := TfgAndroidHelper.Context.getContentResolver.openInputStream(uri);
  b := TJavaArray<Byte>.Create(jis.available);
  jis.read(b);
  for i:=0 to B.Length-1 do
  begin
  bt:=b.Items[i];
  ms.Write(bt,1);
  end;
  jis.close;
  FilePath:=System.IOUtils.TPath.GetTempFileName+'.jpg';
  ms.SaveToFile(FilePath);
  FFiles.Add(getFileName(uri)+'='+FilePath);
  finally
   ms.Free;
  end;
  end;
 var i:integer;
begin
  if TfgActivityResultMessage(M).RequestCode = 42 then
  begin
   if TfgActivityResultMessage(M).ResultCode = TJActivity.RESULT_OK then
   begin
    if FMultiSelect then
    for I := 0 to TfgActivityResultMessage(M).Data.getClipData().getItemCount-1 do
    UriToFile(TfgActivityResultMessage(M).Data.getClipData().getItemAt(i).getUri)
    else
    UriToFile(TfgActivityResultMessage(M).Data.getData());
    FProc(True);
   end
   else
   FProc(False)


  end;
end;

procedure TfgOpenDialog.SetMimeType(const Value: String);
begin
  FMimeType := Value;
end;

procedure TfgOpenDialog.SetMultiSelect(const Value: boolean);
begin
  FMultiSelect := Value;
end;


procedure TfgOpenDialog.Execute(Proc: TProc<boolean>);
var
  Intent: TJIntent;
begin
  FProc:=Proc;
  Intent:=TJIntent.Create;
  if FMultiSelect then
  Intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
  else
  Intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
  Intent.setAction(TJIntent.ACTION_GET_CONTENT);
  Intent.setType(StringToJString(MimeType));
 TfgAndroidHelper.Activity.startActivityForResult(Intent,42);

end;

Пример использования

  fg:=TfgOpenDialog.Create;
  fg.MimeType:='image/*';
  fg.Execute(procedure(B:boolean)
  begin
   if B and (fg.Files.Count>0) then
   begin
   TfgAssetsManager.Current.AddBitmapFromFile(fg.Files.Names[0],fg.Files.ValueFromIndex[0]);
   fgImage1.ImageName:=fg.Files.Names[0];
   fgLabel1.Text:=fgImage1.ImageName;
   end;
  fg:=nil;
 end)

Спасибо, не пинайте за небрежность кода

Edited by Stas
  • Like 3

Share this post


Link to post
Share on other sites

Здравствуйте, на всякий случай выкладываю исправленную версию диалогов

Работает на 10.4 (проверял вроде)

Просьба объявляйте  переменную как интерфейс, и  не забывайте присваивать nil по ненужности.

Спасибо

OpenDialog.7z

  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...