AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Delphi FMX : getContentResolver.query Crash und Jnet_Uri getPath

FMX : getContentResolver.query Crash und Jnet_Uri getPath

Ein Thema von stalkingwolf · begonnen am 22. Jul 2020 · letzter Beitrag vom 1. Mär 2021
Antwort Antwort
Seite 1 von 2  1 2   
stalkingwolf

Registriert seit: 6. Mai 2011
516 Beiträge
 
#1

FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 22. Jul 2020, 16:32
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?

Geändert von stalkingwolf (22. Jul 2020 um 16:44 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.772 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 26. Jan 2021, 10:13
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
  Mit Zitat antworten Zitat
oakley

Registriert seit: 15. Aug 2005
287 Beiträge
 
#3

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 13:42
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
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.772 Beiträge
 
Delphi 12 Athens
 
#4

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 13:53
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...
  Mit Zitat antworten Zitat
oakley

Registriert seit: 15. Aug 2005
287 Beiträge
 
#5

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 14:30
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

Geändert von oakley (30. Jan 2021 um 14:46 Uhr)
  Mit Zitat antworten Zitat
oakley

Registriert seit: 15. Aug 2005
287 Beiträge
 
#6

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 15:27
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
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.772 Beiträge
 
Delphi 12 Athens
 
#7

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 15:37
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
  Mit Zitat antworten Zitat
oakley

Registriert seit: 15. Aug 2005
287 Beiträge
 
#8

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 16:03
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;

Geändert von oakley (30. Jan 2021 um 16:10 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.772 Beiträge
 
Delphi 12 Athens
 
#9

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 16:17
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!
  Mit Zitat antworten Zitat
oakley

Registriert seit: 15. Aug 2005
287 Beiträge
 
#10

AW: FMX : getContentResolver.query Crash und Jnet_Uri getPath

  Alt 30. Jan 2021, 16:46
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz