Programing

FileProvider-IllegalArgumentException : 구성된 루트를 찾지 못했습니다.

crosscheck 2020. 6. 1. 07:55
반응형

FileProvider-IllegalArgumentException : 구성된 루트를 찾지 못했습니다.


카메라로 사진을 찍으려고하는데 다음과 같은 오류가 발생합니다.

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>

자바:

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했지만이 오류 메시지가 무엇을 말하려고하는지 전혀 모른다. 더 많은 정보 / 코드를 원하면 의견에 저를 쓰십시오.


파일은 아래에 저장됩니다 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" />
</paths>

플레이버가 활성화 된 후에도 비슷한 문제가 발생했습니다 (dev, stage).

맛 내기 전에 내 경로 리소스는 다음과 같습니다.

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

이렇게하면 모든 사람의 문제가 해결 될 수 있습니다. 모든 태그가 추가되므로 폴더 경로에 대해 걱정할 필요가 없습니다. 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>

내부 캐시를 사용하는 경우 사용하십시오.

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

이것도 저를 혼란스럽게합니다.

xml 파일의 "path"속성에 문제가 있습니다.

이 문서에서 FileProvider 'path'는 하위 디렉토리이지만 'path'로 표시된 다른 문서 (camera / photobasics)는 전체 경로입니다.

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

이 '경로'를 전체 경로로 변경하면 작동합니다.


장치가 제공하는 저장 장치 수를 확인하십시오-보조 저장 장치에서 파일 공유는 지원되지 않습니다. support-core-utils 25.3.1 에서 FileProvider.java소스를 확인하십시오 .

            } 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 질문을 발견했습니다 .


늦었지만 해결책을 찾았습니다. 제대로 작동하면 XML 파일 경로를 다음과 같이 변경했습니다.

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

해결책을 찾으려고 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-에뮬레이터에서 카메라가 활성화되어 있는지 확인하십시오.


외부 경로가 "이동식 스토리지"(일명 "외부")에도 불구하고 보조 스토리지를 가리 키지 않습니다. "구성된 루트를 찾지 못했습니다"가 표시되면이 줄을 XML 파일에 추가 할 수 있습니다.

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

자세한 내용은 FileProvider 및 보조 외부 저장소를 참조하십시오.


나는 파티에 늦었지만 아래에서 나를 위해 일했다고 확신합니다.

<paths>
    <root-path name="root" path="." />
</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="." />
</paths>

여기에도이 질문에 대한 훌륭한 자습서가 있습니다 : https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s


내 문제는 다음과 같이 다른 유형의 파일 경로에 겹치는 이름이 있다는 것입니다.

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

이름 ( "cached_files")을 고유하게 변경 한 후 오류를 제거했습니다. 내 생각에 그 경로는 일부 HashMap 또는 중복을 허용하지 않는 것으로 저장됩니다.


나는 이것을 위해 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/" ......

그런 다음 작동합니다!


전체 경로를 제공하는 대신 path = "Pictures"을 주었고 정상적으로 작동했습니다.

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

내가 이것을 해결하기 위해 한 것-

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>

그리고 자바 클래스에서-

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

위의 어느 것도 나를 위해 효과가 없었습니다. 몇 시간 동안 디버깅 한 후 문제가 createImageFile(), 특히 absolute pathvsrelative path

나는 너희들이 사진을 찍기 위해 공식 안드로이드 가이드를 사용하고 있다고 가정합니다. 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();
        }
    }

이 오류가 발생했습니다 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)));
    }

안드로이드 공식 문서에 따르면 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>

그러나 최신 안드로이드에서 작동하게하려면 경로 끝에 "/"가 있어야합니다.

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

xml file_paths 파일의 다음 변경이 저에게 효과적이었습니다.

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

나는 같은 문제가 있었고, 아래 코드를 시도했다.

1. Xmlfile 생성 : provider_paths

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

2. 메인 페스트 파일

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

INTERNAL 또는 EXTERNAL 어떤 종류의 저장을 원하는지에 따라 다릅니다.

외부 저장 용

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

그러나 INTERNAL STORAGE의 경우 경로에주의하십시오. getFilesDir () 메소드를 사용하므로 파일이 앱의 루트 디렉토리 ( "/")에 있습니다.

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

따라서 제공자 파일은 다음과 같아야합니다.

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

내 문제가 파일 이름이 잘못되었습니다 : file_paths.xml리소스가 provider_paths.xmlManifest에서 설정되어 있는 동안 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및 문제 해결.


적어도 file_paths.xml의 다른 경로와 동일한 경로를 제공하지 않는 것으로 나타났습니다. 따라서 다음을 포함하여 3 개 장소에 정확히 동일한 패키지 이름 또는 경로를 제공하십시오.

  • android:authorities 매니페스트의 속성
  • path file_paths.xml의 속성
  • authority FileProvider.getUriForFile ()을 호출 할 때 인수.

  • 대한 Xamarin.Android의 사용자

이는 Android 7.1, 8.0 이상을 대상으로 할 때 지원 패키지를 업데이트하지 않은 결과 일 수도 있습니다. v25.4.0.2 +로 업데이트하면 이 특정 오류가 사라질 수 있습니다 (다른 사용자가 지정한대로 file_path 파일을 올바르게 구성했음을 나타냄).


컨텍스트주기 : 내가 목표로 전환 오레오을 에서 누가 A의 Xamarin.Forms의 응용 프로그램과 함께 사진 촬영 Xam.Plugin.Media을 위의 오류 메시지와 함께 실패 시작, 그래서 패키지를 업데이트 확인을 나를 위해 트릭을했다.


path.xml파일 과 관련된 정책이나 동작 이 Support Library 26과 27 사이에서 변경 되었음을 알았 습니다. 카메라에서 사진을 캡처 할 때 다음과 같은 변경 사항이있었습니다.

  • 26으로, 나는 논쟁 <external-path>에서 주어진 전체 경로 를 사용해야했습니다 path.

  • 27에서는 인수에 <external-files-path>하위 폴더 만 사용해야했습니다 path.

path.xml파일로 Support Library 27에서 특히 나에게 도움이 된 것은

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

안녕하세요 친구 시도

이 코드에서

1) 매니페스트에서 2 파일 공급자를 선언하는 방법.

2) 파일 다운로드를위한 최초 제공자

3) 카메라 및 용어집에 사용되는 두 번째 공급자

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>

두번째 공급자

     <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 클래스 생성 (메소드 선언이없는 클래스 만 생성)

사용 된 파일 제공자 (.fileprovider)를 사용했을 때이 이름을 사용하고 이미지 (.provider)에 사용했습니다.

이 코드를 이해하는 데 문제가 있으면 rp1741995@gmail.com으로 문의하십시오. 도와 드리겠습니다.


아무것도 도움이되지 않고 오류가 발생하면

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.


문제는 경로 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의 태그를 포함해야 함을 의미 합니다. 그래서 mRootsuri의 인쇄 및 태그 코드를 작성한 다음 태그가 일치하지 않는 것을 쉽게 찾습니다 .

공급자 권한을 설정 ${applicationID}.provider하는 것은 어리석은 아이디어입니다 ! 이 권한은 너무 일반적이므로 다른 공급자가 사용할 수 있으므로 경로 구성이 엉망이됩니다!


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>

file_paths.xml 파일의 내용에이 문자열 => "/Android/data/com.example.marek.myapplication/files/Pictures/"가 포함되어 있는지 확인해야합니다.

오류 메시지에서 사진이 저장되는 경로입니다. 예상 샘플 참조

아래 files_path.xml :

<external-path name="qit_images" path="Android/data/com.example.marek.myapplication/files/Pictures/" />

참고 URL : https://stackoverflow.com/questions/42516126/fileprovider-illegalargumentexception-failed-to-find-configured-root

반응형