Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi FMX : getContentResolver.query Crash und Jnet_Uri getPath (https://www.delphipraxis.net/205002-fmx-getcontentresolver-query-crash-und-jnet_uri-getpath.html)

stalkingwolf 22. Jul 2020 16:32

FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Ich versuche gerade ein ÖffnenDialog für Bilder in meine APP einzubauen.
Dabei bin ich auf 2 Probleme gestoßen.

1.
Wenn ich das ActivityResult zurück bekomme und mir den JCursor mit SharedActivity.getContentResolver.query holen möchte, dann stürzt das APP ab, wenn ich im Bilderdialog mehr als ein Bild ausgewählt habe.

Den Bilderdialog starte ich mit folgendem Quellcode
Code:
            FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage (TMessageResultNotification, HandleActivityMessage);

            RequestCode := 0;
            Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_PICK);
            intent.setType(StringToJString('image/*'));
            intent.setAction(TjIntent.JavaClass.ACTION_GET_CONTENT);
            Intent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE,true);

            ResolveInfo := SharedActivity.getPackageManager.resolveActivity(Intent, 0);
            if ResolveInfo <> nil then SharedActivity.startActivityForResult(Intent, RequestCode);
Funktioniert auch soweit, wenn ich nur 1 Datei auswähle. Aber es war ganz praktikabel wenn der Anwender mehr als eine Datei auswählen könnte.

Code:
var
C      : JCursor;
cols   : TJavaObjectArray<JString>;
begin

  if Assigned(Data) then begin

    cols:= TJavaObjectArray<JString>.Create(1);
    cols[0] := StringToJString('_display_name');
    c:= SharedActivity.getContentResolver.query(
        data.getData,
        cols,
        nil,   //StringtoJString(''),
        nil,
        nil    //StringtoJString('')
);
Da ist noch mehr Quellcode, aber der ist irrelevant.

2.
Wenn ich mir mit Data.getData.getPath den Pfad ausgeben lasse steht dort /document/image:1456
Den Pfad gibt es nicht. Wie bekomme ich hier den korrekten Pfad?

Ich glaube ich hab hier einen falschen Denkansatz oder? Ich bekomme gar nicht den Pfad raus? Sicherheit?
Weil die Document ID ist image:1456. D.h das System verhindert das ich ermitteln kann wo die Datei liegt?

TurboMagic 26. Jan 2021 10:13

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Hallo,

das was da zurückkommt, soweit ich mich momentan schon eingelesennhabe, ist kein richtiger
klassischer Dateipfad sondern eine FILE URI oder so.
Schau dir doch mal die Doku zu dem Intent mal an:

https://developer.android.com/refere...ON_GET_CONTENT

Grüße
TurboMagic

oakley 30. Jan 2021 13:42

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Da bin ich auch gerade dran.
Er gibt Dir eine URI und damit soll man den richtigen Dateipfad ermitteln können.
Wenn Du nil statt des JArray cols verwendest fragst Du alle spalten ab die da sind.
Um zu sehen welche das sind habe ich das einfach so gemacht und alles in ein Memo schreiben lassen:

Delphi-Quellcode:
for I := 0 to Cursor.getColumnCount - 1 do
begin
  Memo1.Lines.Add(JStringToString(Cursor.getColumnName(I)) +': ' + JStringToString(Cursor.getString(I)));
end;
Anders als man häufig liest findet sich da aber nirgendwo der korrekte Pfad drin.
Es soll eine Spalte namens _data existieren wo der richtige Pfad drin steht aber die wird bei mir auch nicht mit ausgegeben, sprich existiert an der Stelle nicht.

In Java soll der Name hier stehen MediaStore.Images.Media.DATA was in FMX glaube ich TJImages_ImageColumns.JavaClass.DATA entspricht aber da kommt auhc nichts.

Bist Du da eventuell weiter gekommen als ich?

LG

Mirko

TurboMagic 30. Jan 2021 13:53

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Hallo,

diese _Data Spalte gab's bei mir auch nicht, aber ich hab' den woanders gefunden:

Delphi-Quellcode:
function TFileBrowser.HandleIntentAction(const Data: JIntent): boolean;
begin
  log.d('Pfad: ' + JStringToString(Data.getData.getPath));
end;
Nur: ab Android 10 hilft dir der Pfad möglicherweise nicht. Wenn der nämlich auf
einen Ordner wie TPath.GetPublicDownloadsPath zeigt hat man da so ohne weiteres
keine Zugriffsberechtigung mehr.

Was aber seltsamerweise geht ist das hier:

Delphi-Quellcode:
  InputStream := MainActivity.getContentResolver.openInputStream(Data.getData);
  log.d('Zeichen 1: ' + InputStream.read.ToString);
  InputStream.close;
Damit erzeugt man einen input stream aus dem Intent und der Schnippsel oben
liest das erste Zeichen dieses Streams und schreibt es ins Log.

Ich fände es halt toll wenn's doch eine Android 10/11 kompatible Methode gäbe
alle Dateien mit einer gewissen Endung die im TPath.GetSharedDownloadsPath
liegen und man auf die Lese/Schreibzugriff hätte. AQchließlich ist das ja ein
öffentlicher Ordner...

oakley 30. Jan 2021 14:30

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Hallo,
Data.getData.getPath gibt aber auf meinem Samsung nicht den Pfad aus, den ich z.B. für den Upload auf einen FTP Server brauchen könnte.
Ich habe da sowas wie /document/image:6775 .

Der InputStream ist aber interessant weil der IndyFTP Client auch einen Stream für den Upload verwendet.

Ich habe jetzt folgendes versucht:

var
ms : TMemoryStream;
InputStream : JInputStream;
b: TJavaArray<Byte>;

InputStream := MainActivity.getContentResolver.openInputStream(Da ta.getData);
b := TJavaArray<Byte>.Create(InputStream.available);
InputStream.read(b);
ms.Write(b.Data^, b.Length);
InputStream.close;
idftp1.Connect;
idftp1.Put(ms,'test.jpg',false,-1);
idftp1.Disconnect;

Die Galerie wird geöffnet, ich tippe auf das Bild und da hängt sich die App auf.

LG

Mirko

oakley 30. Jan 2021 15:27

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Delphi-Quellcode:
var
ms : TMemoryStream;
InputStream : JInputStream;
b: TJavaArray<Byte>;

InputStream := MainActivity.getContentResolver.openInputStream(Da ta.getData);
b := TJavaArray<Byte>.Create(InputStream.available);
InputStream.read(b);
ms.Write(b.Data^, b.Length);
InputStream.close;
idftp1.Connect;
idftp1.Put(ms,'test.jpg',false,-1);
idftp1.Disconnect;
InputStream.read(b); geht noch
ms.Write(b.Data^, b.Length); geht nicht mehr, hier hängt die App sich auf

LG

Mirko

TurboMagic 30. Jan 2021 15:37

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
1. Das was da zurück kommt ist tatsächlich kein richtiger Dateiname sondern eine URI.
Das ist ja auch Absicht von denen, denn die wollen für viele Pfade ja nicht mehr,
dass du direkt Datei mäßig darauf zugreifst.

2. Warum es bei dir crash weiß ich nicht wirklich, aber was ist denn der Rückgabewert
von Read? Ich sehe auch nirgens, wo du deinen ms erzeugst...

Grüße

TurboMagic

oakley 30. Jan 2021 16:03

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Ja stimmt ich habe ms := TMemoryStream.Create; hinzugefügt und er stürzt nicht mehr ab.

Jetzt muss ich es nur noch ein wenig verbessern mit Fortschrittsbalken und mehreren Dateien und dann passt das.

Die Funktion sieht damit bis jetzt so aus:

function TMFORM.HandleIntentAction(const Data: JIntent): Boolean;
var
C: JCursor;
I: Integer;
ms : TMemoryStream;
InputStream : JInputStream;
b: TJavaArray<Byte>;
begin
Memo1.Lines.Add('URI:' + JStringToString(Data.getData.toString)); // this returns the URI in string perfectly... so I know that I am getting the file path properly
InputStream := MainActivity.getContentResolver.openInputStream(Da ta.getData);
b := TJavaArray<Byte>.Create(InputStream.available);
ms := TMemoryStream.Create;
InputStream.read(b);
Memo1.Lines.Add('Stream länge:' + inttoStr(b.Length));
ms.Write(b.Data^, b.Length);
InputStream.close;
idftp1.Connect;
ms.Position := 0;
idftp1.Put(ms,'test.jpg');
idftp1.Disconnect;
end;

TurboMagic 30. Jan 2021 16:17

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Hinweis für dich:

bevor du das nächste Mal Quellcode postest eifnach mal den "Delphi-Helm" oberhalb
des Editors anklicken und den QUellcode dann dazwischen einfügen.
Dann wird er sauber formatiert angezeigt!

oakley 30. Jan 2021 16:46

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath
 
Hey,

ja ich weiß aber ich habe den Betrag editiert und da hatte ich die Option nicht auf den Helm zu klicken.

So habe ich es jetzt für mehrere Dateien ohne Fortschrittsbalken gelöst.
Hier ist noch das Problem, dass der Bildschirm schwarz wird bis der Upload abgeschlossen ist.

Delphi-Quellcode:
function TMFORM.HandleIntentAction(const Data: JIntent): Boolean;
var
  C: JCursor;
  I, count: Integer;
  ms : TMemoryStream;
  InputStream : JInputStream;
  b: TJavaArray<Byte>;
begin
  count := Data.getClipData().getItemCount();
  for i := 0 to count-1 do
  begin
    Memo1.Lines.Add('URI:' + JStringToString(Data.getClipData().getItemAt(i).getUri.toString));
    InputStream := MainActivity.getContentResolver.openInputStream(Data.getClipData().getItemAt(i).getUri);
    b := TJavaArray<Byte>.Create(InputStream.available);
    ms := TMemoryStream.Create;
    InputStream.read(b);
    Memo1.Lines.Add('Stream länge:' + inttoStr(b.Length));
    ms.Write(b.Data^, b.Length);
    InputStream.close;
    if not idftp1.Connected then
      idftp1.Connect;
    ms.Position := 0;
    idftp1.Put(ms,'test'+InttoStr(i)+'.jpg');
    ms.Free;
    b.Free;
  end;

  idftp1.Disconnect;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:56 Uhr.
Seite 1 von 2  1 2   

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