Pfad zu Datei ändert sich

  • Antworten:10
mr1000
  • Forum-Beiträge: 86

06.08.2020, 05:35:43 via Website

Guten Morgen zusammen,

ich hier ein kleines Problem.

Ich habe mir ein File-Chooser-App programmiert der mir den Pfad des gewünschten Dokument anzeigen soll,damit ich das Dokument öffnen kann.
Der Pfad zum Dokument wird dann in ein String gespeichert und weitergegeben an die OpenPDF-Methode,nur bekomme ich die Fehlermeldung das die Datei oder das Verzeichnis nicht gefunden werden kann.

2020-08-06 05:18:39.625 9756-9756/de.testuser.testapp E/PDFView: load pdf error
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)

Ausgabe der onActivityResult-Methode: /root/storage/emulated/0/teaf.pdf

Ausgabe der OpenPDF-Methode: /storage/emulated/0/root/storage/emulated/0/teaf.pdf

  btFileChooser.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FileIntent = new Intent(Intent.ACTION_GET_CONTENT);
            FileIntent.setType("*/*");
            startActivityForResult(FileIntent, 10);
        }
    });


 @Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);


    switch (requestCode) {

        case 10:

            if (resultCode == RESULT_OK) {

                String path = data.getData().getPath();
                Toast.makeText(getActivity(), "Speicherort " + path, Toast.LENGTH_SHORT).show();

                System.out.println(path);

                OpenPDF(path);

            }

            break;

    }


}

private void OpenPDF(String path) {


    File file = new File(Environment.getExternalStorageDirectory().getPath(),path);
    pdfView.fromFile(file)
            .load();

}

Da stelle ich mir folgenden Fragen:

Wieso kann ich auf das Verzeichnis /root/ zugreifen, obwohl mein Smartphone nicht gerootet ist?

Wieso ändert sich der Pfad zum gewünschten Dokument?

Ich hoffe ihr könnt mich auf klären!

P.S:

File file = new File(Environment.getExternalStorageDirectory().getPath(),"/" + "teaf.pdf");
    pdfView.fromFile(file)
            .load();

Wenn ich es so starte, klappt es!

Gruß,

mr1000

Kommentieren
Jokel
  • Forum-Beiträge: 1.530

06.08.2020, 08:53:54 via Website

Hallo
Also ich sehe hier zwei Fehler

1.)
du willst einen String haben der den Pfad zu der Datei enthält.
Das was du mit getPath() in der ActivtyResult bekommst ist nicht der String den du willst.
getPath() gibt dir den symbolischen, abstracten Pfad als String zurück. Deshalb auch das "root/" was es im echten Dateisystem nicht gibt.
Und das hatt auch nichts mit den Root rechten zu tun.

Benutze getApsolutePath() um den richtigen String zu bekommen.

2.)
willst du mit dem String wider eine File Objekt erstellen .
Wie so holst du dafür erst mall den Pfad zum externen Speicher und hängst dort den String an.? Das ist doppelt gemoppelt. Der String hat den vollen Datei Pfad.
Du siehst ja das du zweimal den externen Pfad in File Objekt hast.
"/storage/emulated/0/root/storage/emulated/0/teaf.pdf"

String path = data.getData().getAbsolutePath();

private void OpenPDF(String path) {
File file = new File(path);

https://developer.android.com/reference/java/io/File

— geändert am 06.08.2020, 10:07:29

Hilfreich?
Pascal P.
Kommentieren
mr1000
  • Forum-Beiträge: 86

06.08.2020, 20:24:46 via Website

Hallo Jokel,

ich habe das mal geändert nur funktioniert data.getData().getAbsolutePath(); nicht.

Gruß,

mr1000

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

06.08.2020, 21:13:01 via Website

OK
getData gibt dir eine Uri zurück, getPath gibt dir von der Uri den abstrakten Pfad als String zurück.
Entweder du versucht jetzt mit mit getAbsolutePath den path zubekommen.

Oder du schneitest mit String Operationen das /root vom String selber ab.

Oder du benutzt die Uri und gibst die weiter und erstellst dann auch aus der Uri dir dein File Objekt.

— geändert am 06.08.2020, 22:14:02

Hilfreich?
Pascal P.
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

06.08.2020, 21:23:41 via Website

Uri uri = data.getData();
File file = new File(uri.getPath()) ;

— geändert am 07.08.2020, 09:47:08

Hilfreich?
Pascal P.
Kommentieren
mr1000
  • Forum-Beiträge: 86

07.08.2020, 00:00:41 via Website

Guten Abend,

Mit Mediastore bekommt man den ganzen Pfad eines Dokuments angezeigt, nur geht das
nicht mehr über API 19!

 public String getRealPathFromURI( Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Files.FileColumns.DATA };
        cursor = getActivity().getContentResolver().query(contentUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }

mr1000

— geändert am 07.08.2020, 00:01:16

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

07.08.2020, 10:01:18 via Website

Hallo für was brauchst du einen String?
Du hast doch die Uri. Daraus kannst du dir ein File Objekt erstellen. Und normal darauf zugreifen.

Die Symbolische Adresse als String nützt dir auch nicht viel.
Wenn dann musst du daraus wider eine Uri machen und daraus ein File Objekt.
Du wirst nie die den echten Physikalischen Pfad bekommen. Schon gleich gar nicht, wenn du eine Datei von einem entfernten Datenträger zB. Cloud holst. Da nützt dir nur die Uri.
Also arbeite mit der URI und nicht den Umweg über einen String.

Hilfreich?
Kommentieren
mr1000
  • Forum-Beiträge: 86

07.08.2020, 13:01:57 via App

Hallo Jokel,

Ich habe mir ein File-Chooser programmiert, womit ich mir eine Datei aussuchen kann.

Wenn ich mir eine Datei ausgesucht habe, in den Fall PDFs dann soll die PDF in den PDF-Viewer zusehen sein. Nur bekomme ich nicht den ganzen Pfad mit den der Datei sonder immer nur
z. B /documents/41. Mit Mediastore habe den ganzen Pfad bekommen
(/document/test.pdf). Nur unterstützt Mediastore über API 19 keine PDFs mehr.

mr1000

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

07.08.2020, 15:01:32 via Website

MediaStore nur bis Api 19 stimmt nicht so ganz.

https://developer.android.com/training/data-storage/shared/media
https://developer.android.com/reference/android/provider/MediaStore

Da hast du aber nur zugriff auf bestimmte Medien nicht auf die volle SD Karte.

Dein Pfad "storage/emulated/0/teaf.pdf" wird da nicht unterstützt werden.
Das ist das Root Verzeichnis deiner SDKarte.
Vollzugriff nur über SAF.

(/document/test.pdf). Nur unterstützt Mediastore über API 19 keine PDFs mehr.

Deine Datei is ja gar nicht in "/document" sondern im Root deiner SdKarte das wird nicht von dem MediaStore duchsucht. und kann dann auch nicht in der DB Liste angezeigt werden.

Wo ist das Problem?
In in der onActivityResult hast du den Intent "data" der enthält eine Uri die du mit getData() bekommst. Die Uri gibst du weiter an deine Methode zum anzeigen des PDF. Dort erstellst du aus der Uri dir ein File Objekt.
File file = new File(uri.getPath());
Nun hast du dein File Objekt und kannst die Datei auch öffnen.
Den path brauchst du nicht. Nützt dir auch nichts denn du hast sowieso ohne der übergehen Uri keine Rechte die Datei zu öffnen.
Außer verzeichnisse die sich auf der sdkarte unter Abdoid befinden.
Zugriff auf die volle sdkarte bekommst du nur mit SAF.

Ps. Zu deinem Vorhaben möchte ich noch bemerken. Selbst wenn du den echten Pfad hast wirst du in neueren Android Versionen trotzdem nicht darauf zugreifen können. Du hast damit nicht die Rechte mehr dazu. Nur über SAF bekommst du die Rechte über die sdkarte ob intern oder auch extern. Ab Android 10 geht es nur noch so.

— geändert am 07.08.2020, 17:21:04

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

07.08.2020, 15:21:17 via Website

Eigentlich hast du gar keinen eigenen File-Chooser erstellt sondern nutzt mittels Intend den in android vorhandenen Chooser benutzt und der gibt dir immer eine Uri zurück.

Ab andoid 10 hast du nur noch die Möglichkeit auf die sdkarte ob intern oder extern mittels SAF zuzugeifen. Was du jetzt eigentlich mit dem Intent schon machst.
https://developer.android.com/guide/topics/providers/document-provider
http://android-doc.github.io/guide/topics/providers/document-provider.html

Dir wirt nichts anderes üblich bleiben es auch zubenutzen wenn Du es auch auf neueren Systemen haben willst.

Android 10 Scoped storage.
https://developer.android.com/guide/topics/providers/document-provider

Da hast du gar keine andere Chance mehr.

PS. eine Frage noch welche Lib zum anzeigen des PDF nutzt du eigentlich?
da gibst es bestimmt sowas wie

pdfView.fromUri (uri ) oder auch pdfView.fromUrl (url )

wenn URL dann url = uri.toURL();

— geändert am 07.08.2020, 17:23:27

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

07.08.2020, 17:46:46 via Website

public String getPDFPath(Uri uri){

 final String id = DocumentsContract.getDocumentId(uri);
 final Uri contentUri = ContentUris.withAppendedId(
                Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

 String[] projection = { MediaStore.Images.Media.DATA };
 Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
 cursor.moveToFirst();
 return cursor.getString(column_index);

}

Hilfreich?
Kommentieren