• 0
hryasch

android Выбор файла через диалог

Вопрос

Добрый вечер. У меня такая проблема - мне нужно, чтобы Android приложение по нажатию на кнопку (к примеру) выдавало диалог, где будет видна файловая система (или спрашивала другое доступное приложение, типо X-PLORE), чтобы я мог выбрать файл ( фотографию к примеру) и нажав "окей" чтобы путь запомнился в какую-нибудь переменную.
 

68747470733a2f2f7261772e6769746875622e636f6d2f695061756c50726f2f6146696c6543686f6f7365722f6d61737465722f73637265656e73686f742d312e706e67.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1 ответ на этот вопрос

  • 0

 

На мобильных платформах обычно не принято указывать пути, хотя есть конечно исключения.
На Android нет стандартного диалога, на iOS есть, но Apple не рекомендует использовать его. 

Important: An iOS app should never use an Open or Save panel to prompt the 
user for the location of a file within the app’s sandbox. iOS apps should 
always save files to known locations inside their sandbox, and apps should 
use a custom interface when presenting those documents to the user. iOS apps 
can, however, use a UIDocumentPickerViewController to prompt the user to 
import, export, open, or move files to or from some areas outside the app’s 
sandbox. For more information, see the Document Picker Programming Guide.

https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/UsingtheOpenandSavePanels/UsingtheOpenandSavePanels.html
 

unit frmSelect;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Edit, FMX.Layouts, FMX.ListBox, FMX.Controls.Presentation;

type
  TCallback = procedure (ASelected: String) of object;

  TfmSelect = class(TForm)
    Panel1: TPanel;
    btnRefresh: TButton;
    lstItems: TListBox;
    edtCurrentFolder: TEdit;
    pnlDirectoryNotExist: TPanel;
    lblDirectoryNotExist: TLabel;
    btnSelect: TButton;
    procedure btnRefreshClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure lstItemsClick(Sender: TObject);
    procedure btnSelectClick(Sender: TObject);
  private
    { Private declarations }
  public
    const
      CONST_STRING_PARENT = '..';
      CONST_X = '/'; { I know is function for this }

    var
      Callback: TCallback;

    { Public declarations }
    function CD(AFolder: String): Boolean;
  end;

var
  fmSelect: TfmSelect;

implementation

{$R *.fmx}

uses
  System.IOUtils;

procedure TfmSelect.btnSelectClick(Sender: TObject);
var
  LResult: String;
begin
  if Assigned(Callback) then
    begin
      if lstItems.ItemIndex = -1 then
        LResult := EmptyStr
      else
        LResult := lstItems.Items[lstItems.ItemIndex];

      Callback(LResult);
    end;

  Close;
end;

function TfmSelect.CD(AFolder: String): Boolean;
var
  LParent: String;
  LDirs,
  LFiles: TStringDynArray;
  s: String;
begin
  lstItems.Clear;
  pnlDirectoryNotExist.Visible := False;
  if (AFolder <> EmptyStr) and (AFolder <> CONST_X) and (AFolder[AFolder.Length - 1] <> CONST_X) then
    AFolder := AFolder + CONST_X;
  edtCurrentFolder.Text := AFolder;

  { http://stackoverflow.com/questions/20318875/how-to-show-the-availble-files-in-android-memory-with-firemonkey }
  if not TDirectory.Exists(AFolder, True) then
    begin
      lblDirectoryNotExist.Text := 'Directory ' + AFolder + ' does not exist.';
      pnlDirectoryNotExist.Visible := True;
      Exit(False);
    end;

  { }
  LParent := TDirectory.GetParent(AFolder);

  { }
  if LParent <> AFolder then
    lstItems.Items.Add(CONST_STRING_PARENT);

  { }
  LDirs := TDirectory.GetDirectories(AFolder, '*');

  // Get all files. Non-Windows systems don't typically care about
  // extensions, so we just use a single '*' as a mask.
  LFiles := TDirectory.GetFiles(AFolder, '*');

  for s in LDirs do
    lstItems.Items.Add(s + CONST_X);

  for s in LFiles do
    lstItems.Items.Add(s);

  Result := True;
end;

procedure TfmSelect.FormCreate(Sender: TObject);
begin
  pnlDirectoryNotExist.Visible := False;
end;

procedure TfmSelect.lstItemsClick(Sender: TObject);
var
  s: String;
begin
  if lstItems.ItemIndex = -1 then
    Exit;

  if SameText(lstItems.Items[lstItems.ItemIndex], CONST_STRING_PARENT) then
    { Or we need to  use global var for Parent }
    CD(TDirectory.GetParent(edtCurrentFolder.Text))
  else
    begin
      s := lstItems.Items[lstItems.ItemIndex];

      if s = EmptyStr then
        Exit;

      if s[s.Length - 1] = CONST_X then
        CD(s);
    end;
end;

procedure TfmSelect.btnRefreshClick(Sender: TObject);
begin
  if edtCurrentFolder.Text <> EmptyStr then
    CD(edtCurrentFolder.Text)
  else
    CD(TPath.GetDocumentsPath);
end;

end.

 

Использование

if fmSelect = nil then
    begin
      Application.CreateForm(TfmSelect, fmSelect);
      fmSelect.Callback := Yahoo;
    end;
  fmSelect.Show;
  fmSelect.CD(TPath.GetDocumentsPath);


procedure TFormXX.Yahoo(ASelectedItem: String);
begin
  ShowMessage(ASelectedItem);
  //
end;
Изменено пользователем ENRGY
Равиль Зарипов (ZuBy) и Rusland понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: om.pranayama
      Здравствуйте форумчане и профессионалы разработчики.
      Компилирую проект через C++Builder 10.2  под Android
      Появилась следующая проблема при использовании компонента TBitmapListAnimation
      Если приложение свернуть, а затем развернуть - то появляются жуткие глитчи в ввиде чёрных фонов вокруг компонентов, типа TImage, TButton.
      В Windows такая проблема - не наблюдается.
      Попытки вызвать Repaint или даже Invalidate для всей формы - положительного результата не дают.
      Пожалуйста, помогите решить эту проблему.
      //--------------------------------------------------------------------------------------------------------------------------------------------
      ТЕМУ МОЖНО УДАЛЯТЬ
      Причина не в TBitmapListAnimation а в TAniIndicator, который работал совместно с TBitmapListAnimation.
      Приношу извинения за беспокойство. Проблема была в TAniIndicator. Буду разбираться почему он так себя безобразно ведёт.
      Тему можно удалять.
    • Автор: Aptyp
      В приложении:
          procedure TForm7.Button1Click(Sender: TObject);     var AIntent: JIntent;         AServiceName: string;     begin       AIntent := TJIntent.Create;       AServiceName := 'com.embarcadero.services.Service';       AIntent.setClassName( TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString( AServiceName ) );       AIntent.putExtra( TAndroidHelper.StringToJString( 'Code' ), 0 );       AIntent.putExtra( TAndroidHelper.StringToJString( 'Data' ), TAndroidHelper.StringToJString( 'DataString' ) );       TAndroidHelper.Activity.startService( AIntent );     end;
      В сервисе:
          procedure TDM.AndroidIntentServiceCreate(Sender: TObject);     begin       Toast( 'Create' );     end;          procedure TDM.AndroidIntentServiceHandleIntent(const Sender: TObject;       const AnIntent: JIntent);     begin       Toast( 'HandleIntent' );     end; Сообщение 'Create' показывается, а 'HandleIntent' нет. OnCreate срабатывает, но onHandleIntent не вызывается что бы я не делал. Может я что-то не так делаю?
    • Автор: Roman V
      Всем привет. Учусь работать с ini-файлами на Android. И сразу же возникла проблема, которую никак не могу решить. Хотел написать подобие приложение-тест с хранением данных в ini файле. В итоге все отлично работает на windows,а под Андроид при запуске висит только значок firemonkey секунд 10 и приложение вырубается так и не запустившись. В чем может быть проблема? Использую отладку по USB. 
      TIniFile *Ini = new TIniFile(System::Ioutils::TPath::GetDocumentsPath() + PathDelim + "options.ini"); Юзаю эти библиотеки 
      #include <System.IOUtils.hpp> #include <System.IniFiles.hpp>  
    • Автор: gonzales
      Доброго времени суток!
      Решаю следующую задачу, в приложении динамически формируются разные объекты, наследники от одного класса. При формировании объектов заполняется динамический массив этих элементов. Далее я хочу в отдельном потоке для каждого из элементов массива получить его состояние, то есть делаю запрос к серверу. Все это повешено на таймер, каждую секунду должен отрабатываться запрос. Все более менее работает в Windows, а на Андроиде со временем приложение валится. Вот код таймера, для читаемости я удалил куски с различными вариантами E. RootElements - это массив TEssense от которого есть наследники. Функции GetBoardCurrentValue, GetBoardMaxValue - по сути запросы к серверу. 
      Подскажите, правильно ли я оформляю работу с потоками для работы на Андроиде?
      procedure TForm1.MasterTimerTimer(Sender: TObject); begin TTask.Run( procedure var l, d, a: byte; i,j:integer; E: TEssence; p: Pointer; VirtualNode: IXMLNode; VirtualElementNode: IXMLNode; id: byte; begin l := Length(Form1.RoomElements); for j := 0 to l - 1 do begin E := Form1.RoomElements[j]; // Реле if E is TRele then begin d := (E as TRele).Device_ID; a := (E as TRele).Device_Adress; if Form1.GetBoardCurrentValue(d, a) = true then begin TThread.Synchronize(nil, procedure begin (E as TRele).ReleSwitch.IsChecked := Form1.device[d].Board[a].CurrentValue.ToBoolean; end); end; // (E as TRele).ReleOnTimer(E) end // Диммер else if E is TDimmer then begin d := (E as TDimmer).Device_ID; a := (E as TDimmer).Device_Adress; if Form1.GetBoardMaxValue(d, a) = true then begin TThread.Synchronize(nil, procedure begin if (Form1.device[d].Board[a].Type_ID = TType.Светодиод) or (Form1.device[d].Board[a].Type_ID = TType.Диммер220) then begin (E as TDimmer).DimmerValue.Text := (Form1.device[d].Board[a].MaxValue).ToString; end; end); end; // (E as TDimmer).DimmerOnTimer(E) end // Таймер else if E is TSTimer then begin id := (E as TSTimer).STimerIndex; Form1.FillHTTPRequest(0, 0, HTTP_GET_TIMER_INFO, id); if Form1.AnswerIsComming = HTTP_GET_TIMER_INFO then begin TThread.Synchronize(nil, procedure begin if Form1.HTTPAnswer.Data1 = 0 then (E as TSTimer).Interval.Text := 'OFF' else (E as TSTimer).Interval.Text := 'ON' end); end; // (E as TSTimer).STimerOnTimer(E); end; end; end); end;   
    • Автор: andahay
      Доброго времени суток. Есть android приложение, в нем есть диалоговое окно, которое предлагает перейти в google play и скачать другое приложение (pro версию), с 2 кнопками (да/нет). Как реализовать этот переход в Google play, чтобы в нем сразу было загружено нужное приложение. Использую Delphi XE7
    • Автор: zekelive
      Добрый день, друзья. Начал заниматься вопросом описанным в шапке и столкнулся со множеством непонятных для меня проблем. Как примерно должно выглядеть на Рис. ниже. Знаю, что сам список барабан выполнен в TlistBox. Есть хорошая ссылка на блог Ярослава тут. Пошерстил файлы в FMX, и не нашел ключа для своего дела. Может кто занимался этим? Я изначально брал TScrollBox, кидал на него Tlayout и в него TLabel. Но думаю, видимо не то совсем.

    • Автор: zekelive
      Добрый день. Кто знает, подскажите, можно ли средствами firemonkey менять иконку приложения в рантайм либо после закрытия и повторного открытия приложения? На win вроде бы можно, статьи на форуме находил, а для Андроида найти не удалось.
    • Автор: bossalex
      Недавно компилил приложение на Delphi  FMX Android  при обращении  к серверу https при выполнении Get запроса от компонента TIdHttp запросил библиотеку "Could not load SSL library" используется протокол sslvTLSv1_2 в windows все пашет в андроид нет , накопал что можно подключить библиотеки  libssl.so и  libcrypto.so через  deployment .assets\internal , А вот как в коде дальше их использовать никто примерчик не выложил, хоть и обсуждали на интернет просторах 100 раз, те как прикрутить  к IdSSLIOHandlerSocketOpenSSL1.SSLOptions.CertFile. Если есть у кого код выложите пожалуйста? или скинте по email bossalex@ya.ru
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method.sslvTLSv1_2;
      IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode.sslmUnassigned;
       
    • Автор: zekelive
      Добрый день, друзья. Подскажите, есть ли возможность в firemonkey открыть форму как представлено на картинке ниже? Если да, то подскажите в какую сторону копать. Спасибо.

    • Автор: Аров Марат (Coolmarat)
      Здравствуйте, коллеги.
      При написании клиента под андроид для Datasnap сервера столкнулся с проблемой, что из телефона строки с русскими буквами
      уходят в нечитаемом виде на сервер. При запуске приложения под Windows проблемы нет. Даже тестовые методы, генерируемые
      мастером создания DataSnap сервера (EchoString, ReverseString) не работают с русским текстом при запуске клиента на
      андроиде. Прилагаю тестовые проекты сервера и клиента с вызовом одной только функции ReverseString - у меня все равно
      выходят кракозябры. Помогите разобраться, как правильно передавать строки с русскими буквами.

      DSTestStrAndroidServer.zip
      DSTestStrAndroidClient.zip
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу