Jump to content

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


Stas

Recommended Posts

  • Administrators

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

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

  TfgActivityNewIntentMessage = class(TMessage<TJIntent>);

 

Link to comment
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
Отформатировал код
Link to comment
Share on other sites

  • Administrators

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

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

  • Thanks 1
Link to comment
Share on other sites

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

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

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

Edited by Stas
Link to comment
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 4
Link to comment
Share on other sites

  • 8 months later...

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

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

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

Спасибо

OpenDialog.7z

  • Like 2
Link to comment
Share on other sites

  • 1 year later...
В 15.09.2020 в 18:37, Stas сказал:

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

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

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

Спасибо

OpenDialog.7z 4 \u043a\u0411 · 19 загрузок

Добрый день!

Подскажите, пожалуйста, есть ли актуальная версия модуля для 10.4?
Представленная здесь не стыкуется с текущей версией библиотеки (((

Link to comment
Share on other sites

22 часа назад, Roman сказал:

Добрый день!

Подскажите, пожалуйста, есть ли актуальная версия модуля для 10.4?
Представленная здесь не стыкуется с текущей версией библиотеки (((

Добрый день!

Сам отвечу на свой запрос: все отлично работает при замене в секции uses FGX.OpenDialog.pas Android.Api.MediaStore на Android.Api.Providers.MediaStore

Спасибо @Stas за модуль и @Yaroslav Brovin за подсказку

  • Like 2
Link to comment
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.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...