FileProvider - IllegalArgumentException: Konfigurierter Stamm konnte nicht gefunden werden

233

Ich versuche, ein Bild mit der Kamera aufzunehmen, erhalte jedoch die folgende Fehlermeldung:

FATAL EXCEPTION: main
Process: com.example.marek.myapplication, PID: 6747
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.marek.myapplication/files/Pictures/JPEG_20170228_175633_470124220.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
    at com.example.marek.myapplication.MainActivity.dispatchTakePictureIntent(MainActivity.java:56)
    at com.example.marek.myapplication.MainActivity.access$100(MainActivity.java:22)
    at com.example.marek.myapplication.MainActivity$1.onClick(MainActivity.java:35)

AndroidManifest.xml:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.marek.myapplication.fileprovider"
        android:enabled="true"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Java:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Toast.makeText(getApplicationContext(), "Error while saving picture.", Toast.LENGTH_LONG).show();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                    "com.example.marek.myapplication.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

Ich habe den ganzen Tag nach diesem Fehler gesucht und versucht zu verstehen FileProvider, aber ich habe keine Ahnung, was diese Fehlermeldung mir zu sagen versucht. Wenn Sie weitere Informationen / Code wünschen, schreiben Sie mir in den Kommentar.

Pivoman
quelle
2
Können Sie auch den Methodencode createImageFile einfügen?
Ankit Batra
Es tut mir so leid, aber ich habe dieses Projekt abgesagt und arbeite nicht mehr daran . Ich werde die beliebteste Antwort akzeptieren, um diese Frage zu "schließen". Vielen Dank an alle für die Teilnahme und ich hoffe, es hilft anderen.
Pivoman
Bin auf das gleiche Problem gestoßen. Diese Lösung wurde gefunden, um ein grundlegendes FileProvider-Setup mit einem minimalen Github-Beispielprojekt durchzuführen : stackoverflow.com/a/48103567/2162226 . Es enthält Schritte, für die Dateien (ohne Änderungen) in ein lokales eigenständiges Projekt kopiert werden können
Gene Bo
Dieses Problem wurde jetzt in Delphi 10.4 behoben
Dave Nottage

Antworten:

208

Ihre Datei wird unter gespeichert getExternalFilesDir(). Das passt <external-files-path>nicht dazu <files-path>. Außerdem enthält Ihr Dateipfad keinen Inhalt images/, sodass das pathAttribut in Ihrem XML ungültig ist.

Ersetzen res/xml/file_paths.xmldurch:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="/" />
</paths>

UPDATE 2020 13. März

Anbieterpfad für einen bestimmten Pfad wie folgt:

  • <files-path/> -> Context.getFilesDir()
  • <cache-path/> -> Context.getCacheDir()
  • <external-path/> -> Environment.getExternalStorageDirectory()
  • <external-files-path/> -> Context.getExternalFilesDir(String)
  • <external-cache-path/> -> Context.getExternalCacheDir()
  • <external-media-path/> -> Context.getExternalMediaDirs()

Ref: https://developer.android.com/reference/androidx/core/content/FileProvider

CommonsWare
quelle
5
ok, ich habe external-files-path hinzugefügt, aber ich habe immer noch den gleichen Fehler: / Es gibt vielleicht mehr Fehler. Ich benutze Emulator Android-Gerät, muss ich diesen Ordner erstellen oder so?
Pivoman
22
Das Attribut "Pfad" sollte definiert werden. "Hier fehlt der Pfad in der Konfiguration.
Blackjack
1
Ich hatte ein Problem mit mehreren Pfaden auf Android 5. Links nur einen Pfad anstelle von 2.
ODAXY
3
Ich habe einen Absturzbericht erhalten (von 50 bis 100 Geräten, glaube ich), der mit diesem identisch ist. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>Das habe path="."ich in meiner eigenen Forschung gefunden, um auf der obersten Ebene zu bleiben. Wenn Sie FileProvider genauer durchgehen, werden Sie feststellen, dass der aus XML gelesene Pfad kanonisiert wird. Ich ContextCompat#getExternalFilesDirsgehe davon aus, dass null @line 616 (v26.0.1) zurückgegeben wurde, sodass keine PathStrategy registriert wurde. Dies trat auf dem Huawei-Gerät auf.
AndroidGy
10
Anstatt <external-files-path zu verwenden, habe ich <external-path ausprobiert und es hat funktioniert.
Sicherer
165

Dies kann das Problem aller lösen: Alle Tags werden hinzugefügt, sodass Sie sich nicht um den Ordnerpfad kümmern müssen. Ersetzen Sie res / xml / file_paths.xml durch:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
<files-path
    name="files"
    path="." />
</paths>
Mitul Varmora
quelle
3
Beste Lösung. Vielen Dank.
Pawan Pillai
1
Einfache Lösung ... aber dafür genial! Ich habe einen Anbieter verwendet und dann die Benutzer-Möglichkeit eingegeben, das Zielverzeichnis zu ändern. Es hat nichts mehr funktioniert, da der Anbieter zu diesem Zeitpunkt dynamisch sein sollte. Sie haben meinen Tag gespeichert.
Bronz
1
benutzte diese Lösung und der Code begann zu funktionieren. Unnötiger Code wurde entfernt, indem getestet wurde, welcher davon funktionierte
Kartik
1
Bro du hast meinen Tag gerettet. Vielen Dank :-)
Manjunath Kallannavar
1
Großartig hat für mich funktioniert, als neuer Lernender wurde mir klar, dass ich nicht aus externen Dateien, sondern aus dem Cache komme
Tony Merritt
82

Habe ein ähnliches Problem nach aktivierten Aromen (dev, stage).

Vor Aromen sah meine Pfadressource folgendermaßen aus:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
    name="my_images"
    path="Android/data/pl.myapp/files/Pictures" />
</paths>

Nach dem Hinzufügen von android: behörden = "$ {applicationId} .fileprovider" in Manifest appId war pl.myapp.dev oder pl.myapp.stage abhängig vom Geschmack und App stürzte ab. Ich entfernte den vollständigen Pfad und ersetzte ihn durch einen Punkt, und alles begann zu funktionieren.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>
Antygravitation
quelle
7
Hat für mich gearbeitet. Vielen Dank! Wie du auf '.' Notation?
NightFury
2
@antygravity können Sie bitte Referenz / Dokumentation dieser Lösung bereitstellen?
Geekoraul
7
Gibt es irgendwelche negativen Konsequenzen dieser Lösung?
RediOne1
Arbeitete für mich, vielen Dank.
Hiren
Dies sollte die akzeptierte Antwort sein! Die einzige Lösung, die funktioniert hat
egorikem
43

Wenn Sie den internen Cache verwenden, verwenden Sie.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>
Unschuldig
quelle
3
danke, meine situation: Ich möchte eine App installieren, die in / data / data / pkg_name / files gespeichert ist, also meine korrekte Konfiguration wie folgt: <files-path name = "files" path = "/" />
aolphn
25

2 Wochen verloren, um eine Lösung zu finden ... Wenn Sie hier ankommen, nachdem Sie alles oben versucht haben:

1 - Überprüfen Sie, ob sich Ihr Tag-Anbieter in der Tag-Anwendung befindet

<application>

    <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.companyname.Pocidadao.fileprovider" android:exported="false" android:grantUriPermissions="true">
      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>

</application>

2 - Wenn Sie viele Pfade ohne Erfolg ausprobieren, testen Sie Folgendes:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <cache-path name="cache" path="." />
  <external-path name="external" path="." />

  <root-path name="root" path="." />
  <files-path name="my_images" path="/" />
  <files-path name="my_images" path="myfile/"/>
  <files-path name="files" path="." />

  <external-path name="external_files" path="." />
  <external-path name="images" path="Pictures" />
  <external-path name="my_images" path="." />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures" />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures/" />

  <external-files-path name="images" path="Pictures"/>
  <external-files-path name="camera_image" path="Pictures/"/>
  <external-files-path name="external_files" path="." />
  <external-files-path name="my_images" path="my_images" />

  <external-cache-path name="external_cache" path="." />

</paths>

Testen Sie dies, wenn die Kamera funktioniert, entfernen Sie einige Linien und fahren Sie mit dem Testen fort ...

3 - Vergessen Sie nicht zu überprüfen, ob die Kamera in Ihrem Emulator aktiviert ist.

Diego Venâncio
quelle
1
Danke, das hat bei mir funktioniert. Müssen andere Pfade entfernt werden?
CodeSlave
22

Ich bin mir sicher, dass ich zu spät zur Party komme, aber unten hat es für mich funktioniert.

<paths>
    <root-path name="root" path="." />
</paths>
spartanfrei
quelle
Dies war der letzte Schritt, damit auch mein Code funktioniert! Vielen Dank.
Dog Dogma
15

Das verwirrt mich auch ein bisschen.

Das Problem liegt im Attribut "Pfad" in Ihrer XML-Datei.

In diesem Dokument ist FileProvider 'Pfad' ein Unterverzeichnis, aber in einem anderen Dokument (Kamera / Fotobasik) wird 'Pfad' als vollständiger Pfad angezeigt.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Ich ändere einfach diesen 'Pfad' in den vollständigen Pfad und es funktioniert einfach.

Supakij
quelle
15

Ich würde zu spät kommen, aber ich habe eine Lösung dafür gefunden. Ich habe gut funktioniert und nur die XML-Pfaddatei geändert in:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>
subbu
quelle
1
Für mich provider_paths.xmlgibt dies eine Inspektionswarnung "Element root-path ist hier nicht erlaubt".
Luis A. Florit
15

Beachten Sie, dass der externe Pfad nicht auf Ihren sekundären Speicher verweist, auch bekannt als "Wechselspeicher" (trotz des Namens "extern"). Wenn "Konfiguriertes Stammverzeichnis konnte nicht gefunden werden" angezeigt wird, können Sie diese Zeile zu Ihrer XML-Datei hinzufügen.

<root-path name="root" path="." />

Weitere Details finden Sie hier FileProvider und sekundärer externer Speicher

Peter Shashkin
quelle
14

Überprüfen Sie, wie viele Speicher Ihr Gerät anbietet. Die Freigabe von Dateien aus dem Sekundärspeicher wird nicht unterstützt. Schauen Sie sich die FileProvider.javaQuelle an (von support-core-utils 25.3.1 ):

            } else if (TAG_EXTERNAL_FILES.equals(tag)) {
                File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null);
                if (externalFilesDirs.length > 0) {
                    target = externalFilesDirs[0];
                }
            } else if (TAG_EXTERNAL_CACHE.equals(tag)) {
                File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context);
                if (externalCacheDirs.length > 0) {
                    target = externalCacheDirs[0];
                }
            }

Sie nehmen also nur den ersten Speicherplatz ein.

Sie können auch sehen, dass dies getExternalCacheDirs()verwendet wird, um eine Liste der Speicher über die ContextCompatSchnittstelle abzurufen . Informationen zu den Grenzwerten finden Sie in der Dokumentation (z. B. werden USB-Flashes nicht erkannt). Am besten erstellen Sie selbst eine Debug-Ausgabe der Liste der Speicher dieser API, damit Sie überprüfen können, ob der Pfad zum Speicher mit dem übergebenen Pfad übereinstimmt getUriForFile().

Im Issue-Tracker von Google ist bereits ein Ticket zugewiesen (Stand 06-2017), mit dem Sie aufgefordert werden, mehr als einen Speicher zu unterstützen. Irgendwann fand ich auch SO eine Frage dazu.

lef
quelle
1
Diese ausführliche Antwort sollte mehr positive Stimmen erhalten. Vielen Dank, dass Sie herausgefunden haben, welchen externen Speicher FileProvider tatsächlich erkennt.
LarsH
10

Ich habe 5 Stunden dafür verbracht ..

Ich habe alle oben genannten Methoden ausprobiert, aber es hängt davon ab, welchen Speicher Ihre App derzeit verwendet.

https://developer.android.com/reference/android/support/v4/content/FileProvider#GetUri

Überprüfen Sie die Dokumentation, bevor Sie die Codes ausprobieren.

In meinem Fall wird da files-pathUnterverzeichnis sein Context.getFilesDir(). Das Funky ist, dass es sich Context.getFilesDir()gegenseitig ein Unterverzeichnis notiert.

was ich suche ist

data/user/0/com.psh.mTest/app_imageDir/20181202101432629.png

Context.getFilesDir()

kehrt zurück /data/user/0/com.psh.mTest/files

so sollte das tag sein

....files-path name="app_imageDir" path="../app_imageDir/" ......

Dann funktioniert es !!

Seho Park
quelle
1
Vielen Dank, dass Sie sich auf die Dokumentation beziehen. Es führte mich zur richtigen Antwort. In meinem Fall wurde meine Datei mit gespeichert getExternalStorageDirectory()und ich sollte den Pfad mit <external-path>Tag anstelle von<files-path>
alierdogan7
Vielen Dank für diese spezielle Antwort auf Dateipfad. Es hat sehr geholfen. :)
arungiri_10
Ja es funktioniert!!! Der wichtigste Punkt ist, das ".." am Anfang des Pfades anzugeben, wie dieser Pfad = "../ myDirectory /"
Robert Apikyan
9

Nichts davon hat bei mir funktioniert. Der einzige Ansatz, der funktioniert, besteht darin, keinen expliziten Pfad in XML zu deklarieren. Also mach das und sei glücklich:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="." />
</paths>

Auch hier finden Sie ein hervorragendes Tutorial zu dieser Frage: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s

Paulo Linhares - Packapps
quelle
7

Mein Problem war, dass ich überlappende Namen in den Dateipfaden für verschiedene Typen hatte, wie folgt:

<cache-path
    name="cached_files"
    path="." />
<external-cache-path
    name="cached_files"
    path="." />

Nachdem ich die Namen ("cached_files") so geändert hatte, dass sie eindeutig waren, wurde der Fehler behoben. Ich vermute, dass diese Pfade in einer HashMap gespeichert sind oder etwas, das keine Duplikate zulässt.

Gefahr
quelle
3

Was ich getan habe, um das zu lösen -

AndroidManifest.xml

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

filepaths.xml (Ermöglicht dem FileProvider, alle Dateien freizugeben, die sich im externen Dateiverzeichnis der App befinden.)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="files"
        path="/" />
</paths>

und in der Java-Klasse -

Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);
Rupam Das
quelle
3

Dies funktionierte auch für mich. Anstatt den vollständigen Pfad anzugeben, gab ich path = "Pictures" und es funktionierte gut.

<?xml version="1.0" encoding="utf-8"?>
 <paths>
  <external-files-path
    name="images"
    path="Pictures">
  </external-files-path>
 </paths>
Amit Arora
quelle
2

Es hängt davon ab, welche Art von Speicher Sie möchten, INTERN oder EXTERN

für EXTERNE LAGERUNG

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="my_images" />
</paths>

Gehen Sie bei INTERNAL STORAGE jedoch vorsichtig mit dem Pfad um, da er die Methode getFilesDir () verwendet. Dies bedeutet, dass sich Ihre Datei im Stammverzeichnis der App befindet ("/").

  File storeDir = getFilesDir(); // path "/"

Ihre Provider-Datei muss also folgendermaßen aussehen:

<paths>
    <files-path name="my_images" path="/" />
</paths>
Christian Altamirano Ayala
quelle
In allen Beispielen wird davon ausgegangen, dass der Benutzer externen Speicher verwendet. Ich brauchte Hilfe beim internen Speicher und es dauerte Stunden, um diese Antwort zu finden. Danke dir.
Zeeshan
2

Keines der oben genannten Verfahren hat bei mir funktioniert. Nach ein paar Stunden Debugging stellte ich fest, dass das Problem vorliegt createImageFile(), insbesondere absolute pathvs.relative path

Ich gehe davon aus, dass ihr den offiziellen Android-Leitfaden zum Fotografieren verwendet. https://developer.android.com/training/camera/photobasics

    private static File createImageFile(Context context) throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

Beachten Sie storageDir, dass dies der Speicherort ist, an dem die Datei erstellt wird. Um den absoluten Pfad dieser Datei zu erhalten, verwende ich einfach image.getAbsolutePath()diesen Pfad, onActivityResultwenn Sie das Bitmap-Bild nach dem Aufnehmen des Fotos benötigen

unten ist das file_path.xml, einfach verwenden, .damit es den absoluten Pfad verwendet

<paths>
    <external-path
        name="my_images"
        path="." />
</paths>

und wenn Sie die Bitmap nach dem Fotografieren benötigen

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeFile(mCurrentPhotoPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
Grandia
quelle
2

Ich habe diesen Fehler erhalten Failed to find configured root that contains...

Die folgende Problemumgehung behebt mein Problem

res / xml / file_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="media" path="." />
</paths>

AndroidManifest.xml

<provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="[PACKAGE_NAME]"
      android:exported="false"
      android:grantUriPermissions="true">
         <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
         </meta-data>
</provider>

ActivityClass.java

void shareImage() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,"com.slappstudio.pencilsketchphotomaker", selectedFilePath));
        startActivity(Intent.createChooser(intent,getString(R.string.string_share_with)));
    }
Ali Tamoor
quelle
1

Das offizielle Android-Dokument besagt, dass file_paths.xml Folgendes haben sollte:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Aber damit es im neuesten Android funktioniert, sollte am Ende des Pfades ein "/" stehen, wie folgt:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures/" />
</paths>
Shripad Bhat
quelle
1

Die folgende Änderung in der XML-Datei file_paths hat bei mir funktioniert.

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>
Manmohan Soni
quelle
1

Ich hatte das gleiche Problem, ich habe versucht, den folgenden Code für seine Funktion.

1.Erstellen Sie eine XML-Datei: provider_paths

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="myfile/"/>
</paths>

2. Mainfest-Datei

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.ril.learnet.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
 </provider>

3.In Ihrer Java-Datei.

      File file =  new File(getActivity().getFilesDir(), "myfile");
        if (!file.exists()) {
            file.mkdirs();
        }
        String  destPath = file.getPath() + File.separator + attachmentsListBean.getFileName();

               file mfile = new File(destPath);
                Uri path;
                Intent intent = new Intent(Intent.ACTION_VIEW);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                {
                    path = FileProvider.getUriForFile(AppController.getInstance().getApplicationContext(), AppController.getInstance().getApplicationContext().getPackageName() + ".provider", mfile );
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    path = Uri.fromFile(mfile);
                }
   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setDataAndType(path, "image/*");
                    getActivity().startActivity(intent);
Suresh Kumar
quelle
1

Wenn nichts hilft und Sie den Fehler erhalten

failed to find configured root that contains /data/data/...

Versuchen Sie dann, eine Zeile wie folgt zu ändern:

File directory = thisActivity.getDir("images", Context.MODE_PRIVATE);

zu:

File directory = new File(thisActivity.getFilesDir(), "images");

und in der XML-Datei:

<files-path name="files" path="." />

Das ist komisch, da der Ordner, auf den ich zugreife, ist /images.

LivinTheNoobLife
quelle
Der Wechsel von .getDir zu .getFilesDir hat mir geholfen. Vielen Dank!
Dmitriy Pavlukhin
1

Mein Problem war der falsche Dateiname : Ich erstelle file_paths.xmlunter res / xml, während die Ressource provider_paths.xmlin Manifest auf gesetzt wurde:

<provider
        android:authorities="ir.aghigh.radio.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

Ich wechselte provider_pathszu file_pathsund Problem gelöst.

Saeed Arianmanesh
quelle
1

Wenn Ihr Dateipfad / storage / emulated / 0 / "yourfile" lautet

Sie müssen nur Ihre FileProvider-XML ändern

<paths>
    <external-path name="external" path="." />
</paths>

Rufen Sie diese Funktion dann auf, wenn Sie eine Freigabedatei benötigen

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
                    Uri fileUri = FileProvider.getUriForFile(getContext(),
                            "com.example.myapp.fileprovider",
                            file);
                    sharingIntent.setType("*/*"); // any flie type
                    sharingIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
                    startActivity(Intent.createChooser(sharingIntent, "Share file"));

es funktioniert auf Android M ~ Pie

faul
quelle
Es funktioniert! Aber können Sie erklären, warum wir path = "." Verwenden? anstelle von path = "DCIM", "Pictures" ...?
Hoang Lam
@Hoang Lam Der Unterschied besteht darin, ob Sie ein Verzeichnis angeben müssen. In meinem Beispiel können Sie auf all zugreifen
faul
0

Ich sehe, dass Sie zumindest nicht den gleichen Pfad wie andere in file_paths.xml angeben. Stellen Sie daher sicher, dass Sie an drei Stellen genau den gleichen Paketnamen oder Pfad angeben, einschließlich:

  • android:authorities Attribut im Manifest
  • path Attribut in file_paths.xml
  • authority Argument beim Aufruf von FileProvider.getUriForFile ().
Pei
quelle
0
  • Für Xamarin.Android- Benutzer

Dies kann auch darauf zurückzuführen sein, dass Ihre Support-Pakete bei der Ausrichtung auf Android 7.1, 8.0+ nicht aktualisiert wurden. Aktualisieren Sie sie auf v25.4.0.2 + und dieser spezielle Fehler kann verschwinden (vorausgesetzt, Sie haben Ihre file_path-Datei korrekt konfiguriert, wie andere angegeben haben).


Kontext angeben : Ich habe in einer Xamarin.Forms- App auf Oreo von Nougat umgestellt und mit der obigen Fehlermeldung ein Bild mit Xam.Plugin.Media aufgenommen. Die Aktualisierung der Pakete hat mir also geholfen.

Ahmed Alejo
quelle
0

Ich habe festgestellt, dass sich die Richtlinie oder das Verhalten in Bezug auf die path.xmlDatei zwischen der Support-Bibliothek 26 und 27 geändert hat. Beim Aufnehmen eines Bildes von der Kamera wurden die folgenden Änderungen festgestellt :

  • Mit 26 musste ich <external-path>den im Pfad angegebenen vollständigen Pfad verwenden path.

  • Mit 27 musste ich <external-files-path>nur den Unterordner im pathArgument verwenden.

Also, was speziell für mich mit Support Library 27 als path.xmlDatei funktioniert hat

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="camera_image" path="Pictures/"/>
</paths>
Johan Paul
quelle
0

Hallo Freunde, versuche das

In diesem Code

1) Deklarieren von 2 Dateianbietern im Manifest.

2) Erster Anbieter für den Dateidownload

3) zweiter Anbieter für Kamera und Galerie

SCHRITT 1

     <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

Provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="apks" path="." />
</paths>

Zweiter Anbieter

     <provider
        android:name=".Utils.MyFileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities"
        tools:ignore="InnerclassSeparator">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path" />
    </provider>

file_path.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="storage/emulated/0" path="."/>
</paths>

.Utils.MyFileProvider

Klasse erstellen MyFileProvider (nur Klasse erstellen, keine Methode deklarieren)

Wenn Sie den Dateianbieter verwendet haben (.fileprovider), haben Sie diesen Namen verwendet und Sie haben ihn für das Bild (.provider) verwendet.

WENN jemand ein Problem hat, diesen Code zu verstehen Sie können sich unter [email protected] an mich wenden. Ich werde Ihnen helfen.

Rahul Patil
quelle
0

Das Problem ist möglicherweise nicht nur der Pfad xml.

Folgendes ist mein Fix:

Ein Blick in den Wurzelkurs in android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile():

    public File getFileForUri(Uri uri) {
        String path = uri.getEncodedPath();

        final int splitIndex = path.indexOf('/', 1);
        final String tag = Uri.decode(path.substring(1, splitIndex));
        path = Uri.decode(path.substring(splitIndex + 1));

        final File root = mRoots.get(tag); // mRoots is parsed from path xml
        if (root == null) {
            throw new IllegalArgumentException("Unable to find configured root for " + uri);
        }

        // ...
    }

Dies bedeutet, mRootsdass das Tag der angeforderten URL enthalten sein sollte. Also schreibe ich einen Code zum Drucken mRootsund Markieren von Uri und finde dann leicht heraus, dass die Tags nicht übereinstimmen .

Es stellt sich heraus, dass ${applicationID}.provideres eine blöde Idee ist , die Autorität des Anbieters festzulegen ! Diese Berechtigung ist so häufig, dass sie möglicherweise von anderen Anbietern verwendet wird, wodurch die Pfadkonfiguration durcheinander gebracht wird!

Donnerschlag
quelle
-1

Sie müssen die XML-Datei file_paths.xml von ändern

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

zu

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
Andrey
quelle
1
Obwohl Sie Ihre Antwort von oben kopiert haben, wird sie nicht ordnungsgemäß ausgeführt. Bitte korrigieren Sie die Tippfehler in Ihrer Antwort.
Abhinav Saxena