Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Kein TOpenDialog für Android? (https://www.delphipraxis.net/216869-kein-topendialog-fuer-android.html)

Rued 14. Mär 2025 17:32

Kein TOpenDialog für Android?
 
Hallo!
Ich hatte aufgrund dieser Ausführungen in der Dokumentation zu DelphiFMX die Hoffnung, dass ich in meine Android-App Open- und SaveDialoge einbauen kann, aber da liege ich wohl falsch.

Jedenfalls wird folgender Code klaglos kompiliert, aber execute exekutiert nichts. Ohne jede Fehlermeldung passiert exakt nichts.
Delphi-Quellcode:
var
SD1:TOpenDialog;
begin
SD1:=TSaveDialog.Create(application);
SD1.InitialDir := TippPfad;
SD1.DefaultExt :='tip';
if SD1.Execute then Memo1.Lines.SavetoFile(SD1.FileName);
SD1.Free;

Harry Stahl 14. Mär 2025 17:36

AW: Kein TOpenDialog für Android?
 
Nein, da musst Du Dir selber etwas bauen, wobei die Möglichkeiten, Dateien zu öffnen oder zu speichern auf den mobilen Systemen sowieso relativ begrenzt sind (Standard-Verzeichnisse, wie Documents oder Download, etc).

Rued 14. Mär 2025 17:44

AW: Kein TOpenDialog für Android?
 
Zitat:

Zitat von Harry Stahl (Beitrag 1547129)
Nein, da musst Du Dir selber etwas bauen, wobei die Möglichkeiten, Dateien zu öffnen oder zu speichern auf den mobilen Systemen sowieso relativ begrenzt sind (Standard-Verzeichnisse, wie Documents oder Download, etc).

Okay - danke Harry!

Gruß
Rüd

Rollo62 14. Mär 2025 18:48

AW: Kein TOpenDialog für Android?
 
Oder Du musst mal nach SAF - StorageAccessFrameWork - ScopedStorage googlen.

jaenicke 14. Mär 2025 19:48

AW: Kein TOpenDialog für Android?
 
Das ist ein Beispiel mit einem Button und einem TImage, das ein ausgewähltes Bild anzeigt:
Delphi-Quellcode:
uses
  Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers, Androidapi.JNI.Net,
  Androidapi.JNI.App, Androidapi.JNI.JavaTypes, Androidapi.JNIBridge, System.Messaging;

procedure OpenAndroidFileDialog;
var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setType(StringToJString('*/*')); // image/* für Bilder
  Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);
  TAndroidHelper.Activity.startActivityForResult(Intent, 0);
end;

procedure TForm286.FormCreate(Sender: TObject);
begin
  TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage);
end;

function OpenFileViaContentResolver(Uri: Jnet_Uri): JInputStream;
begin
  Result := nil;
  if Uri <> nil then
  begin
    Result := TAndroidHelper.Context.getContentResolver.openInputStream(Uri);
    if Result = nil then
      ShowMessage('Konnte die Datei nicht öffnen.');
  end;
end;

function JInputStreamToMemoryStream(InputStream: JInputStream): TMemoryStream;
var
  Buffer: TJavaArray<Byte>;
  BytesRead: Integer;
begin
  Result := TMemoryStream.Create;

  Buffer := TJavaArray<Byte>.Create(1024);
  repeat
    BytesRead := InputStream.read(Buffer, 0, Buffer.Length);
    if BytesRead > 0 then
      Result.Write(Buffer.Data^, BytesRead);
  until BytesRead <= 0;

  Result.Position := 0;
end;

procedure TForm286.ShowImageFromUri(Uri: Jnet_Uri);
var
  InputStream: JInputStream;
  Bitmap: TBitmap;
  BitmapStream: TMemoryStream;
begin
  InputStream := OpenFileViaContentResolver(Uri);

  if InputStream <> nil then
  begin
    BitmapStream := JInputStreamToMemoryStream(InputStream);

    try
      Bitmap := TBitmap.Create;
      try
        Bitmap.LoadFromStream(BitmapStream);
        Image1.Bitmap.Assign(Bitmap);
      finally
        Bitmap.Free;
      end;
    finally
      BitmapStream.Free;
    end;
  end
  else
    ShowMessage('Fehler: Bild konnte nicht geöffnet werden.');
end;

procedure TForm286.HandleActivityMessage(const Sender: TObject; const M: TMessage);
var
  IntentData: JIntent;
begin
  if M is TMessageResultNotification then
  begin
    if TMessageResultNotification(M).ResultCode = TJActivity.JavaClass.RESULT_OK then
    begin
      IntentData := JIntent(TMessageResultNotification(M).Value);
      if Assigned(IntentData) then
        ShowImageFromUri(IntentData.getData);
    end;
  end;
end;

procedure TForm286.Button1Click(Sender: TObject);
begin
  OpenAndroidFileDialog;
end;

Rued 14. Mär 2025 20:12

AW: Kein TOpenDialog für Android?
 
Danke Sebastian, das schaue ich mir morgen mal an.

TurboMagic 16. Mär 2025 08:24

AW: Kein TOpenDialog für Android?
 
Hallo,

ja ScopedStorage ist inzwischen das richtige Stichwort,
wobei ich damals als ich damit mal was gemacht hatte die Möglichkeit vermisst habe,
eigene Dateitypen zu benutzen. Wenn man also z. B. ein eigenes Binäres Format oder auch
ein Textformat mit eigener Endung für irgendwas benutzt tut man sich evtl. schwer, kommt
aber nicht drumherum, wenn die betreffenden Dateien z. B. im Downloads Ordner liegen :-(

Olli73 16. Mär 2025 10:57

AW: Kein TOpenDialog für Android?
 
Zitat:

Zitat von TurboMagic (Beitrag 1547144)
wobei ich damals als ich damit mal was gemacht hatte die Möglichkeit vermisst habe,
eigene Dateitypen zu benutzen. Wenn man also z. B. ein eigenes Binäres Format oder auch
ein Textformat mit eigener Endung für irgendwas benutzt tut man sich evtl. schwer, kommt
aber nicht drumherum, wenn die betreffenden Dateien z. B. im Downloads Ordner liegen :-(

Hast du deinen Dateityp im Manifest registriert?

Rued 17. Mär 2025 10:57

AW: Kein TOpenDialog für Android?
 
Vor Sebastians Beitrag hatte ich mir folgende Lösung überlegt und umgesetzt:

In der App können an zwei Stellen Dateien unterschiedlichen Typs gespeichert und geöffnet werden. Für den Speichervorgang kann der Anwender einen Dateinamen über Edit-Feld vergeben. Beim Speichervorgang in einen spezifischen Unter-Ordner im PathDelim über einen Button wird eine spezifische Dateiendung an den Dateinamen angehängt. Beim App-Start werden alle Dateien aus dem spezifischen Ordner mit der spezifischen Dateiendung in eine Combobox eingelesen - Endung wird dabei wieder entfernt -, über deren Change-Routine die Datei geöffnet werden kann. Das Combobox-Einlesen wird nach einem Speichervorgang aktualisiert.

Für meine Zwecke reicht das. Spricht etwas dagegen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz