FileProvider-IllegalArgumentException:構成されたルートの検索に失敗しました


233

カメラで写真を撮ろうとしていますが、次のエラーが発生します。

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>

私はこのエラーについて丸一日検索して理解しようとしましたがFileProvider、このエラーメッセージが何を伝えようとしているのかわかりません。より多くの情報/コードが必要な場合は、コメントに私を書いてください。


2
createImageFileメソッドのコードを貼り付けることもできますか?
Ankit Batra 2017

申し訳ありませんが、このプロジェクトをキャンセルし、現在は作業を行っていません。この質問を「閉じる」ための最もお気に入りの答えを受け入れます。参加してくださった皆さん、ありがとうございました。
ピボマン2017

同じ問題に出くわした。最小限のgithubサンプルプロジェクト(stackoverflow.com/a/48103567/2162226)を使用して基本的なFileProviderセットアップを実行するためのこのソリューションが見つかりました 。ローカルスタンドアロンプ​​ロジェクト
Gene Bo

この問題は、今のDelphi 10.4に固定されている:quality.embarcadero.com/browse/RSP-26950
デイブNottage

回答:


211

ファイルはに保存されgetExternalFilesDir()ます。それはにマップ<external-files-path>、ではありません<files-path>。また、ファイルパスに含まimages/れていないため、pathXML の属性は無効です。

と置き換えますres/xml/file_paths.xml

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

2020年3月13日更新

以下のような特定のパスのプロバイダーパス:

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

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


5
わかりました、external-files-pathを追加しましたが、それでも同じエラーが発生します:/もっとバグがあるかもしれません。エミュレーターAndroidデバイスを使用していますが、そのフォルダーなどを作成する必要がありますか?
ピボマン2017

22
「 'path'属性を定義する必要があります」設定にパスがありません。
ブラックジャック

1
Android 5の複数のパスで問題が発生しました。2ではなく1つのパスのみを残しました
ODAXY

3
これと同じ1つのクラッシュレポート(50〜100台のデバイスのうち)を受け取りました。私はトップレベルにとどまるために私自身の研究で見つかったものです。FileProviderをさらに詳しく見てみると、XMLから読み取られたパスが正規化されていることがわかります。私の推測では、null @line 616(v26.0.1)が返されたため、PathStrategyは登録されませんでした。これはHuaweiデバイスで発生しました。<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>path="."ContextCompat#getExternalFilesDirs
androidguy

10
<external-files-pathを使用する代わりに、<external-pathを試してみましたが、うまくいきました。
2018年

166

これで全員の問題が解決する可能性があります。すべてのタグが追加されるため、フォルダーのパスを気にする必要はありません。res / xml / file_paths.xmlを次で置き換えます。

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

3
最良のソリューション。ありがとう。
Pawan Pillai

1
簡単な解決策...しかし、これは素晴らしいことです。私はプロバイダーを使用してから、ユーザーに宛先ディレクトリーを変更する可能性を入力しました...その時点でプロバイダーは動的であるはずなので、何も機能しません....あなたは私の日を節約しました!
Bronz

1
このソリューションを使用し、コードが機能し始めました。これらのうちどれが機能しているかをテストすることにより、不要なコードを削除しました
Kartik

1
ブロ、私の日を救った。
どうも

1
新しい学習者として、外部ファイルからではなくキャッシュから取得していないことに気づかされました
Tony Merritt

82

フレーバー(開発、ステージ)を有効にした後に同様の問題が発生しました。

フレーバーの前は、私のパスリソースは次のようになりました。

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

マニフェストにandroid:authorities = "$ {applicationId} .fileprovider"を追加した後、appIdはpl.myapp.devまたはpl.myapp.stageがフレーバーに依存し、アプリがクラッシュし始めました。フルパスを削除してドットに置き換えると、すべてが機能し始めました。

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

7
私のために働いた。ありがとう!「。」を思いついた方法 表記?
NightFury 2017

2
@antygravityこのソリューションのリファレンス/ドキュメントを提供できますか?
geekoraul

7
このソリューションの悪影響はありますか?
RediOne1 2018

私のために働いた、どうもありがとう。
Hiren 2018年

これは受け入れられる答えになるはずです!機能した唯一のソリューション
egorikem 19/06/05

43

内部キャッシュを使用している場合は、使用してください。

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

3
おかげで、私の状況:/ data / data / pkg_name / filesに保存されたアプリをインストールしたいので、次のように正しい構成を行います:<files-path name = "files" path = "/" />
aolphn

25

いくつかの解決策を見つけようとして2週間を失った...上記のすべてを試してからここに到着した場合:

1- タグプロバイダーがタグアプリケーション内にあるかどうかを確認する

<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-たくさんのパスを試しても成功しない場合は、次のコードでテストしてください。

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

これをテストし、カメラが機能する場合は、いくつかのラインを削除してテストを続行します...

3-エミュレータでカメラがアクティブになっているかどうかを確認することを忘れないでください。


1
ありがとう、これでうまくいきました。他のパスを削除する必要がありますか?
CodeSlave

22

私はパーティーに遅れると確信していますが、以下はうまくいきました。

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

これは私のコードを動作させるための最後のステップでした!ありがとう。
犬のドグマ

15

これも私を少し混乱させます。

問題は、xmlファイルの「パス」属性にあります。

このドキュメントからFileProvider 'path'はサブディレクトリですが、別のドキュメント(camera / photobasics)では、 'path'はフルパスです。

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

私はこの「パス」をフルパスに変更するだけで機能します。


15

私は遅れるでしょうが、私はそれに対する解決策を見つけました。私のためにうまく働いて、私はパスXMLファイルを次のように変更しました:

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

1
私にとってこれはprovider_paths.xml「要素のルートパスはここでは許可されていません」という検査警告を出します。
Luis A. Florit

15

「外部パス」は、「リムーバブルストレージ」とも呼ばれるセカンダリストレージを指していないことに注意してください(「外部」という名前にもかかわらず)。「設定されたルートの検索に失敗しました」と表示される場合は、この行をXMLファイルに追加できます。

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

詳細はこちらFileProviderとセカンダリ外部ストレージ


14

デバイスが提供するストレージの数を確認します-セカンダリストレージからのファイルの共有はサポートされていません。FileProvider.javaソースを見てください(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];
                }
            }

つまり、最初のストレージのみを取得します。

また、インターフェースをgetExternalCacheDirs()介してストレージのリストを取得するために使用されていることがわかりContextCompatます。制限については、ドキュメントを参照してください(たとえば、USBフラッシュを認識しないように指示されています)。最善の方法は、このAPIからストレージのリストのデバッグ出力を自分で作成して、ストレージへのパスがに渡されたパスと一致することを確認できるようにすることですgetUriForFile()

Googleの課題追跡に(06-2017に関して)割り当てられチケットがすでにあり、複数のストレージのサポートを要求しています。結局、私もこれについてSOの質問を見つけました。


1
この詳細な答えは、より多くの投票を獲得するはずです。FileProviderが実際に認識する外部ストレージを検索していただき、ありがとうございます。
LarsH 2017年

10

私はこれに5時間費やしました。

私は上記の方法をすべて試しましたが、それはアプリが現在使用している店舗に依存します。

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

コードを試す前にドキュメントを確認してください。

私の場合、files-pathサブディレクトリはになりますContext.getFilesDir()。ファンキーなのは、Context.getFilesDir()別のサブディレクトリを示していることです。

私が探しているのは

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

Context.getFilesDir()

戻り値 /data/user/0/com.psh.mTest/files

したがって、タグは

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

その後、動作します!!


1
ドキュメントをご参照いただきありがとうございます。それが正解につながりました。私の場合、ファイルは一緒に保存getExternalStorageDirectory()され、パスの<external-path>代わりにタグを付けることになっていた<files-path>
alierdogan7

files-pathに関するこの特定の回答をありがとうございます。それは大いに役立ちました。:)
arungiri_10

はい、動作します!!! 重要な点は、パスの先頭に「..」を指定することです。たとえば、次のパス= "../ myDirectory /"
Robert Apikyan

9

これはどれも私にとってはうまくいきませんでした。機能する唯一のアプローチは、xmlで明示的なパスを宣言しないことです。だからこれをして幸せになる:

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

ここにもこの質問に関する優れたチュートリアルがありますhttps : //www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s


7

私の問題は、次のように、異なるタイプのファイルパスに重複する名前があったことです。

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

名前( "cached_files")を一意に変更した後、エラーを解消しました。私の推測では、これらのパスは一部のHashMapまたは重複を許可しないものに格納されています。


3

これを解決するために私がしたこと-

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(FileProviderがアプリの外部ファイルディレクトリ内にあるすべてのファイルを共有できるようにする)

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

そしてJavaクラスで-

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

3

これも私にとってはうまくいきました。フルパスを指定する代わりに、path = "Pictures"を指定すると、うまくいきました。

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

2

INTERNALまたはEXTERNALのいずれの種類のストレージを使用するかによって異なります

外部ストレージ用

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

ただし、内部ストレージの場合はパスに注意してください。getFilesDir()メソッドを使用しているため、ファイルはアプリのルートディレクトリ( "/")に配置されます。

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

したがって、プロバイダーファイルは次のようにする必要があります。

<paths>
    <files-path name="my_images" path="/" />
</paths>

すべての例は、ユーザーが外部ストレージを使用していることを前提としています。内部ストレージのサポートが必要でしたが、この答えを見つけるのに何時間もかかりました。ありがとうございました。
Zeeshan

2

上記の私は問題はであることが判明デバッグの数時間後、私のために働いたのどれもcreateImageFile()具体的には、absolute pathrelative path

皆さんは公式のAndroidガイドを使って写真を撮っていると思います。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;
    }

をメモしてくださいstorageDir。これは、ファイルが作成される場所です。したがって、このファイルの絶対パスを取得するには、単にを使用しますimage.getAbsolutePath()。このパスは、onActivityResult写真を撮った後にビットマップ画像が必要な場合に使用されます

以下は、絶対パスを使用file_path.xmlする.ように使用するだけです

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

写真を撮った後にビットマップが必要な場合

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();
        }
    }

2

このエラーが発生しました Failed to find configured root that contains...

次の回避策は私の問題を解決します

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

1

Androidの公式ドキュメントによると、file_paths.xmlには次のものが必要です。

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

しかし、最新のandroidで機能させるには、次のようにパスの最後に「/」が必要です。

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

1

次のxml file_pathsファイルの変更は私にとってはうまくいきました。

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>

1

私は同じ問題を抱えていたので、以下のコードを試してみました。

1. Xmlfileを作成します:provider_paths

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

2. 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.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);

1

何も解決せず、エラーが発生する場合

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

次に、次のような行を変更してみてください:

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

に:

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

そしてxmlファイルで:

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

私がアクセスするフォルダはなので、これは奇妙です/images


.getDirから.getFilesDirに切り替えると役に立ちました。ありがとう!
Dmitriy Pavlukhin

1

問題はファイル名が間違っていたfile_paths.xmlリソースがprovider_paths.xmlマニフェストで設定されているときにres / xmlの下に作成しました:

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

に変更provider_pathsfile_pathsて問題解決しました。


1

ファイルパスが/ storage / emulated / 0 / "yourfile"のような場合

FileProvider xmlを変更するだけです

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

次に、ファイルを共有する必要があるときにこの関数を呼び出します

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

android M〜Pieで動作します


うまくいきました!しかし、path = "。"を使用する理由を説明できますか?path = "DCIM"の代わりに、 "Pictures" ...?
ホアンラム

@Hoang Lam違いは、ディレクトリを指定する必要があるかどうかです。この例では、すべてにアクセスできます
レイジー

0

少なくとも、file_paths.xmlで他のユーザーと同じパスを指定していないことがわかります。したがって、次の3か所で正確に同じパッケージ名またはパスを指定してください。

  • android:authorities マニフェストの属性
  • path file_paths.xmlの属性
  • authority FileProvider.getUriForFile()を呼び出すときの引数。

0
  • 以下のためのXamarin.Androidユーザー

これは、Android 7.1、8.0以降を対象とする場合にサポートパッケージを更新しないことが原因である可能性もあります。それらをv25.4.0.2 +に更新すると、この特定のエラーがなくなる可能性があります(他の人が述べたようにfile_pathファイルを正しく構成した場合)。


コンテキストを与える:私はターゲットに切り替えオレオをからヌガーXamarin.Formsのアプリと一緒に写真を撮るXam.Plugin.Media 上記のエラーメッセージで失敗し始めたので、パッケージの更新は、[OK]私のためにトリックをしました。


0

path.xmlファイルに関するポリシーまたは動作がSupport Library 26と27の間で変更されていることに気付きました。カメラから写真をキャプチャするために、次の変更がありました。

  • 26を使用する<external-path>と、path引数で指定したフルパスを使用する必要がありました。

  • 27の場合<external-files-path>path引数にはサブフォルダーのみを使用する必要がありました。

だから、path.xmlファイルとしてサポートライブラリ27を使用して特にうまくいった

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

0

こんにちはフレンズ

このコードでは

1)マニフェストで2つのファイルプロバイダーを宣言する方法。

2)ファイルダウンロードの最初のプロバイダー

3)カメラとギャラリーに使用される2番目のプロバイダー

ステップ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>

2番目のプロバイダー

     <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

クラスMyFileProviderを作成します(Createクラスのみ、メソッド宣言なし)

ファイルプロバイダー(.fileprovider)を使用した場合、この名前を使用し、イメージ(.provider)に使用しました。

このコードを理解するための問題がある場合は、rp1741995 @ gmail.comに連絡してください。


0

問題は、パスのxmlだけではない可能性があります。

以下は私の修正です:

のルートコースを調べます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);
        }

        // ...
    }

つまりmRoots、リクエストされたURIのタグが含まれている必要があります。だから私は印刷mRootsしてuriのタグを付けるコードを書き、それからタグが一致しないことを簡単に見つけます

プロバイダーの権限を設定${applicationID}.providerするのは愚かな考えです!この権限は非常に一般的であるため、他のプロバイダーによって使用される可能性があり、パス構成を台無しにしてしまいます!


-1

xmlファイルfile_paths.xmlを

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

1
上から回答をコピーしましたが、正しく行われていません。回答の入力ミスを修正してください。
Abhinav Saxena
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.