Jump to content
View in the app

A better way to browse. Learn more.

FGX Native

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

  • Author

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

у FMX есть TFMXNativeActivityListener

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

  • Administrators

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

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

  TfgActivityNewIntentMessage = class(TMessage<TJIntent>);

 

  • Author

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

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

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
Отформатировал код

  • Author

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

  • Administrators

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

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

  • Author

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

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

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

Edited by Stas

  • Author

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

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

Edited by Stas

  • Author

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

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

  • 8 months later...
  • Author

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

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

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

Спасибо

OpenDialog.7z

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

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

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

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

Спасибо

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

Добрый день!

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

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

Добрый день!

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

Добрый день!

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

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

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.