FileProvider - IllegalArgumentException: impossible de trouver la racine configurée

235

J'essaie de prendre une photo avec l'appareil photo, mais j'obtiens l'erreur suivante:

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>

Je cherchais toute la journée sur cette erreur et essayais de comprendre FileProvider, mais je n'ai aucune idée de ce que ce message d'erreur essaie de me dire. Si vous voulez plus d'informations / code, écrivez-moi dans le commentaire.

Pivoman
la source
2
Pouvez-vous également coller du code de méthode createImageFile?
Ankit Batra du
Je suis vraiment désolé, mais j'ai annulé ce projet et je n'y travaille plus . J'accepterai la réponse la plus préférée pour «fermer» cette question. Merci à tous pour votre participation et j'espère que cela aide les autres.
Pivoman
Ran dans le même problème. J'ai trouvé cette solution pour obtenir une configuration de base de FileProvider en utilisant un exemple de projet github minimal: stackoverflow.com/a/48103567/2162226 . Il fournit des étapes pour les fichiers à copier (sans apporter de modifications) dans un projet autonome local
Gene Bo
Ce problème est désormais résolu dans Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Dave Nottage

Réponses:

212

Votre fichier est stocké sous getExternalFilesDir(). Cela correspond à <external-files-path>, non <files-path>. De plus, votre chemin de fichier ne contient pas images/dedans, donc l' pathattribut dans votre XML n'est pas valide.

Remplacez res/xml/file_paths.xmlpar:

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

MISE À JOUR 2020 13 MARS

Chemin du fournisseur pour un chemin spécifique comme suit:

  • <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()

Réf: https://developer.android.com/reference/androidx/core/content/FileProvider

CommonsWare
la source
5
ok, j'ai ajouté external-files-path, mais j'ai toujours la même erreur: / Il y a peut-être plus de bugs. J'utilise un appareil Android émulateur, dois-je créer ce dossier ou quelque chose?
Pivoman
22
"L'attribut 'path' doit être défini" il nous manque ici le chemin dans la configuration.
blackjack
1
J'avais un problème avec plusieurs chemins sur Android 5. Je n'ai laissé qu'un seul chemin, au lieu de 2.
ODAXY
3
J'ai reçu un rapport de crash (sur 50-100 appareils, je pense) qui est identique à celui-ci. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>C'est path="."ce que j'ai trouvé dans mes propres recherches pour rester au plus haut niveau. Si vous parcourez FileProvider de plus près, vous verrez que le chemin lu à partir de XML est canonisé. Ma meilleure supposition est que ContextCompat#getExternalFilesDirsretourné null @line 616 (v26.0.1), donc un PathStrategy n'a pas été enregistré. Cela s'est produit sur l'appareil Huawei.
androidguy
10
Au lieu d'utiliser <chemin-de-fichiers-externes, j'ai essayé <chemin-externe et cela a fonctionné.
Safeer
167

Cela peut résoudre le problème de tout le monde: toutes les balises sont ajoutées afin que vous n'ayez pas à vous soucier du chemin des dossiers. Remplacez res / xml / file_paths.xml par:

<?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
la source
3
Meilleure solution. Merci.
Pawan Pillai
1
Solution simple ... mais pour ce brillant! J'ai utilisé un fournisseur, puis j'ai saisi la possibilité pour l'utilisateur de changer le répertoire de destination ... rien ne fonctionnait plus car à ce stade, le fournisseur devrait être dynamique .... vous m'avez sauvé la journée!
Bronz
1
utilisé cette solution et le code a commencé à fonctionner. Suppression du code inutile en testant celui qui fonctionnait
Kartik
1
Bro tu m'as sauvé la journée. Merci beaucoup :-)
manjunath kallannavar
1
Très bien travaillé pour moi, en tant que nouvel apprenant, cela m'a fait réaliser que je n'obtenais pas de fichiers externes mais du cache
Tony Merritt
82

Vous avez un problème similaire après avoir activé les saveurs (dev, stage).

Avant les saveurs, ma ressource de chemin ressemblait à ceci:

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

Après avoir ajouté android: autorités = "$ {applicationId} .fileprovider" dans Manifest appId était pl.myapp.dev ou pl.myapp.stage dépend de la saveur et l'application a commencé à planter. J'ai supprimé le chemin complet et l'ai remplacé par un point et tout a commencé à fonctionner.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>
antygravité
la source
7
A travaillé pour moi. Merci! Comment vous en êtes arrivé à "." notation?
NightFury du
2
@antygravity pouvez-vous s'il vous plaît fournir une référence / documentation de cette solution?
geekoraul
7
Y a-t-il des conséquences négatives de cette solution?
RediOne1
A travaillé pour moi, merci beaucoup.
Hiren
Cela devrait être la réponse acceptée! La seule solution qui a fonctionné
egorikem
43

Si vous utilisez le cache interne, utilisez.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>
Innocent
la source
3
merci, ma situation: je veux installer une application qui a enregistré dans / data / data / pkg_name / files, donc ma configuration correcte comme suit: <files-path name = "files" path = "/" />
aolphn
25

J'ai perdu 2 semaines en essayant de trouver une solution ... Si vous arrivez ici après avoir essayé tout ce qui précède:

1 - Vérifiez si votre fournisseur de tag est dans l'application de tag

<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 - Si vous essayez beaucoup de chemins sans succès, testez avec ceci:

<?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>

Testez cela, si la caméra fonctionne, commencez à éliminer certaines lignes et continuez à tester ...

3 - N'oubliez pas de vérifier si la caméra est activée dans votre émulateur.

Diego Venâncio
la source
1
Merci, cela a fonctionné pour moi. Faut-il supprimer d'autres chemins?
CodeSlave
22

Je suis sûr que je suis en retard à la fête, mais ci-dessous a fonctionné pour moi.

<paths>
    <root-path name="root" path="." />
</paths>
spartanfree
la source
C'était la dernière étape pour que mon code fonctionne aussi! Merci.
Dog Dogma
15

Cela me déroute un peu aussi.

Le problème est sur l'attribut "path" dans votre fichier xml.

À partir de ce document FileProvider 'chemin' est un sous-répertoire, mais dans un autre document (appareil photo / photobasique) montré 'chemin' est chemin complet.

<?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>

Je change simplement ce «chemin» en chemin complet et ça marche.

Supakij
la source
15

Je serais en retard, mais j'ai trouvé une solution.Fonctionnant bien pour moi, je viens de changer le fichier XML des chemins en:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>
subbu
la source
1
Pour moi, cela provider_paths.xmldonne un avertissement d'inspection "L'élément root-path n'est pas autorisé ici".
Luis A. Florit
15

Sachez que external-path ne pointe pas vers votre stockage secondaire, alias "stockage amovible" (malgré le nom "externe"). Si vous obtenez "Impossible de trouver la racine configurée", vous pouvez ajouter cette ligne à votre fichier XML.

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

Voir plus de détails ici FileProvider et stockage externe secondaire

Peter Shashkin
la source
14

Vérifiez le nombre de stockages offerts par votre appareil - le partage de fichiers à partir du stockage secondaire n'est pas pris en charge. Regardez la FileProvider.javasource (de 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];
                }
            }

Ainsi, ils ne prennent que le premier stockage.

En outre, vous pouvez voir qu'il getExternalCacheDirs()est utilisé pour obtenir la liste des stockages via l' ContextCompatinterface. Voir la documentation pour ses limites (on lui dit de ne pas reconnaître les flashs USB par exemple). Le mieux est de faire vous-même une sortie de débogage de la liste des stockages de cette API, afin que vous puissiez vérifier que le chemin d'accès au stockage correspond au chemin passé getUriForFile().

Il y a déjà un ticket attribué (comme pour 06-2017) dans l'outil de suivi des problèmes de Google, demandant de prendre en charge plus d'un stockage. Finalement, j'ai aussi trouvé SO question à ce sujet .

lef
la source
1
Cette réponse approfondie devrait obtenir plus de votes positifs. Merci d'avoir cherché ce que FileProvider de stockage externe reconnaît réellement.
LarsH
10

J'ai passé 5 heures pour ça ..

J'ai essayé toutes les méthodes ci-dessus, mais cela dépend du stockage que votre application utilise actuellement.

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

Vérifiez la documentation avant d'essayer les codes.

Dans mon cas, puisque le files-pathsous-répertoire sera Context.getFilesDir(). Ce qui est génial, c'est qu'il se Context.getFilesDir()note un sous-répertoire.

ce que je cherche c'est

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

Context.getFilesDir()

Retour /data/user/0/com.psh.mTest/files

donc la balise doit être

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

Alors ça marche !!

Parc Seho
la source
1
Merci de vous référer à la documentation. Cela m'a conduit à la bonne réponse. Dans mon cas, mon fichier a été enregistré avec getExternalStorageDirectory()et j'étais censé fournir le chemin avec une <external-path>balise au lieu de<files-path>
alierdogan7
Merci pour cette réponse spécifique sur files-path. Cela a beaucoup aidé. :)
arungiri_10
Oui cela fonctionne!!! le point clé est de spécifier le ".." au début du chemin, comme ce chemin = "../ myDirectory /"
Robert Apikyan
9

Rien de tout cela n'a fonctionné pour moi. La seule approche qui fonctionne est de ne pas déclarer un chemin explicite en xml. Alors faites ceci et soyez heureux:

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

Ici aussi, un excellent tutoriel sur cette question: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s

Paulo Linhares - Packapps
la source
7

Mon problème était que j'avais des noms qui se chevauchaient dans les chemins de fichiers pour différents types, comme ceci:

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

Après avoir changé les noms ("cached_files") pour qu'ils soient uniques, je me suis débarrassé de l'erreur. Je suppose que ces chemins sont stockés dans un HashMap ou quelque chose qui n'autorise pas les doublons.

Péril
la source
4

Cela a également fonctionné pour moi.Au lieu de donner le chemin complet, j'ai donné path = "Pictures" et cela a bien fonctionné.

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

Ce que j'ai fait pour résoudre ce problème -

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 (Autoriser FileProvider à partager tous les fichiers qui se trouvent dans le répertoire de fichiers externes de l'application)

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

et en classe java -

Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);
Rupam Das
la source
2

Cela dépend du type de stockage que vous souhaitez faire, INTERNE ou EXTERNE

pour le STOCKAGE EXTERNE

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

mais pour le STOCKAGE INTERNE, soyez prudent avec le chemin, car il utilise la méthode getFilesDir () qui signifie que votre fichier sera situé dans le répertoire racine de l'application ("/")

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

Votre fichier fournisseur doit donc être comme ceci:

<paths>
    <files-path name="my_images" path="/" />
</paths>
Christian Altamirano Ayala
la source
Tous les exemples supposent que l'utilisateur utilise un stockage externe. J'avais besoin d'aide avec le stockage interne et il a fallu des heures pour trouver cette réponse. Je vous remercie.
zeeshan
2

rien de ce qui précède n'a fonctionné pour moi, après quelques heures de débogage, j'ai découvert que le problème était dans createImageFile(), spécifiquement absolute pathvsrelative path

Je suppose que vous utilisez le guide Android officiel pour prendre des photos. 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;
    }

Prenez note de storageDir, c'est l'emplacement où le fichier sera créé. Donc, pour obtenir le chemin absolu de ce fichier, j'utilise simplement image.getAbsolutePath(), ce chemin sera utilisé onActivityResultsi vous avez besoin de l'image Bitmap après avoir pris une photo

ci-dessous est le file_path.xml, utilisez simplement .pour qu'il utilise le chemin absolu

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

et si vous avez besoin du bitmap après avoir pris une photo

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
la source
2

Je recevais cette erreur Failed to find configured root that contains...

Le travail suivant résout mon problème

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
la source
1

Le document officiel d'Android indique que file_paths.xml devrait avoir:

<?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>

Mais pour le faire fonctionner dans le dernier android, il devrait y avoir un "/" à la fin du chemin, comme ceci:

<?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
la source
1

Le changement suivant dans le fichier xml file_paths a fonctionné pour moi.

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

J'ai eu le même problème, j'ai essayé le code ci-dessous pour son fonctionnement.

1.Créez un fichier Xml: provider_paths

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

2. Fichier Mainfest

 <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.Dans votre fichier Java.

      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
la source
1

Si rien ne vous aide et que vous obtenez l'erreur

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

puis essayez de changer une ligne comme:

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

à:

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

et dans le fichier xml:

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

ce qui est bizarre, car le dossier auquel j'accède est /images.

LivinTheNoobLife
la source
Passer de .getDir à .getFilesDir m'a aidé. Merci!
Dmitriy Pavlukhin
1

Mon problème était incorrect Nom du fichier : je file_paths.xmlcrée sous res / xml alors que la ressource était définie provider_paths.xmldans Manifest:

<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>

J'ai changé provider_pathspour file_pathset le problème a été résolu.

Saeed Arianmanesh
la source
1

Si votre chemin de fichier est comme / stockage / émulé / 0 / "votrefichier"

il vous suffit de modifier votre fichier XML FileProvider

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

puis appelez cette fonction lorsque vous avez besoin de partager un fichier

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"));

cela fonctionne sur android M ~ Pie

paresseux
la source
Ça marche! Mais pouvez-vous expliquer pourquoi nous utilisons path = "." au lieu de path = "DCIM", "Pictures" ...?
Hoang Lam
@Hoang Lam La différence est de savoir si vous devez spécifier un répertoire, dans mon exemple, vous pouvez accéder à tous
paresseux
0

Je vois qu'au moins vous ne fournissez pas le même chemin que les autres dans file_paths.xml. Veuillez donc vous assurer de fournir exactement le même nom de package ou le même chemin d'accès à 3 endroits, notamment:

  • android:authorities attribut dans le manifeste
  • path attribut dans file_paths.xml
  • authority lors de l'appel de FileProvider.getUriForFile ().
Pei
la source
0
  • Pour les utilisateurs de Xamarin.Android

Cela peut également être le résultat de la non-mise à jour de vos packages de support lors du ciblage d'Android 7.1, 8.0+. Mettez-les à jour vers v25.4.0.2 + et cette erreur particulière pourrait disparaître (en vous donnant configuré correctement votre fichier file_path comme d'autres l'ont indiqué).


Contexte: j'ai changé pour cibler Oreo depuis Nougat dans une application Xamarin.Forms et prendre une photo avec Xam.Plugin.Media a commencé à échouer avec le message d'erreur ci-dessus, donc la mise à jour des packages a fait l'affaire pour moi ok.

Ahmed Alejo
la source
0

J'ai remarqué que la politique ou le comportement concernant le path.xmlfichier a changé entre la bibliothèque de support 26 et 27. Pour capturer une image de l'appareil photo, j'ai vu les changements suivants:

  • Avec 26, je devais utiliser <external-path>et le chemin complet donné dans l' pathargument.

  • Avec 27, je devais utiliser <external-files-path>et seulement le sous-dossier dans l' pathargument.

Donc, ce qui a fonctionné spécifiquement pour moi avec la bibliothèque de support 27 car le path.xmlfichier était

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

Bonjour les amis Essayez ceci

Dans ce code

1) Comment déclarer 2 fournisseur de fichiers dans le manifeste.

2) Premier fournisseur de téléchargement de fichiers

3) deuxième fournisseur utilisé pour la caméra et le gallary

ÉTAPE 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>

Deuxième fournisseur

     <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

Create Class MyFileProvider (uniquement Create class no any method declare)

Lorsque vous avez utilisé File Provider, vous avez utilisé (.fileprovider) ce nom et vous avez utilisé pour l'image (.provider), vous l'avez utilisé.

SI n'importe quel problème pour comprendre ce code, vous pouvez contacter sur [email protected] je vais vous aider.

Rahul Patil
la source
0

Le problème n'est peut-être pas uniquement le chemin xml.

Voici ma solution:

Regarder le cours racine dans 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);
        }

        // ...
    }

Cela signifie que mRootsdoit contenir la balise de l'uri demandé. J'écris donc du code pour imprimer mRootset étiqueter uri, puis je trouve facilement que les étiquettes ne correspondent pas .

Il s'avère que définir l'autorité du fournisseur ${applicationID}.providerest une idée stupide ! Cette autorité est si courante qu'elle pourrait être utilisée par d'autres fournisseurs, ce qui gâcherait la configuration du chemin!

coup de tonnerre
la source
-1

Vous devez changer le fichier xml file_paths.xml de

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

à

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
Andrey
la source
1
Bien que vous ayez copié votre réponse ci-dessus, elle n'est pas correctement effectuée. Veuillez corriger la différence de frappe dans votre réponse.
Abhinav Saxena