programing

파일 공급자 - 잘못된 인수예외:구성된 루트를 찾지 못했습니다.

procenter 2023. 9. 27. 20:56
반응형

파일 공급자 - 잘못된 인수예외:구성된 루트를 찾지 못했습니다.

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

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)

Android Manifest.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 이 ..더 많은 정보/코드를 원하시면 댓글에 저를 적어주세요.

이 로 됩니다.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

이렇게 하면 모든 사람의 문제가 해결될 수 있습니다.모든 태그가 추가되어 폴더 경로에 대해 걱정하지 않아도 됩니다.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>

편집: 2021년 6월 1일

우리는 필요한 특정한 경로만 사용해야 합니다.스스로 대체 경로를 시도하고 필요한 경로를 사용합니다.

자세한 내용은 수락된 답변 참조: https://stackoverflow.com/a/42516202/4498813

플레이버(dev, stage)를 활성화한 후 유사한 문제가 발생했습니다.

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

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

Manifest appId에서 Android:authorities="${applicationId.fileprovider"를 추가한 후 pl.myapp.dev 또는 pl.myapp.stage는 맛에 따라 달라지며 앱이 충돌하기 시작했습니다.전체 경로를 제거하고 점으로 교체하니 모든 것이 작동하기 시작했습니다.

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

저는 파티에 늦었다고 확신하지만 아래는 저를 위해 일했습니다.

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

내부 캐시를 사용하는 경우 를 사용합니다.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" 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 - 에뮬레이터에 카메라가 활성화되어 있는지 확인하는 것을 잊지 마십시오.

외부 경로는 "이동식 스토리지"("외부"라는 이름에도 불구하고)라고 하는 보조 스토리지를 가리키고 있지 않습니다."Failed to find configured root"(구성된 루트를 찾지 못했습니다)라는 메시지가 나타나면 이 행을 XML 파일에 추가할 수 있습니다.

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

자세한 내용은 여기 FileProvider보조 외장 스토리지를 참조하십시오.

저도 좀 헷갈리더라고요.

문제는 xml 파일의 "path" 특성에 있습니다.

이 문서에서 FileProvider 'path'는 하위 디렉터리이지만 다른 문서(카메라/사진 기본)에서는 '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>

이 '경로'를 '전체 경로'로 바꾸면 작동합니다.

늦겠지만 해결책을 찾았습니다.잘 작동하여 경로 XML 파일을 다음과 같이 변경했습니다.

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

장치에서 제공하는 저장소 수를 확인합니다. 보조 저장소에서 파일을 공유할 수 없습니다.요.FileProvider.java소스(지원 코어 util 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 질문을 하게 되었습니다.

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

그럼 되는 거지!!

이 모든 것들이 저에겐 통하지 않았습니다.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="." />

이름("cacheed_files")을 고유하게 변경한 후 오류를 제거했습니다.내 생각에 그 경로들은 일부 해시맵이나 중복을 허용하지 않는 어떤 것에 저장되어 있을 것입니다.

.main/res/xml/provider_paths.xml

부터

<paths>
    <files-path path="images/" name="myimages" />
    <external-path name="download" path="download/"/>
</paths>

로.

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

저도 잘 먹혔는데요.전체 경로를 지정하는 대신 path="Pictures"를 지정했고 잘 작동했습니다.

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

이 문제를 해결하기 위해 내가 한 일은-

Android Manifest.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);

내부 또는 외부 스토리지 중에서 원하는 스토리지 종류에 따라 달라집니다.

외부 보관용

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

그러나 INTERNAL STORE의 경우 getFilesDir() 메서드를 사용하므로 경로에 주의해야 합니다. 이는 파일이 앱("/")의 루트 디렉터리에 위치함을 의미합니다.

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

따라서 공급자 파일은 다음과 같습니다.

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

저도 같은 문제가 있었는데, 작동을 위해 아래 코드를 사용해 보았습니다.

1. Xml 파일 만들기 : 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);

의 것들 중 않았고, 몇 는 그 가 의 에 것을 .createImageFile()으로 , absolute path.relative 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 /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의 태그를 포함해야 합니다.그래서 uri의 인쇄와 태그를 위해 코드를 작성하고 태그가 일치하지 않는 것을 쉽게 발견합니다.

제공자 권한을 그대로 두는 것은 어리석은 생각이라는 것이 드러났습니다!이 권한은 너무 일반적이어서 다른 공급자가 사용할 수 있으므로 경로 구성을 엉망으로 만듭니다!

했습니다.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>

Android Manifest.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"/>

내 문제가 잘못된 파일 이름:I Createfile_paths.xml리소스가 설정되어 있는 동안 res/xml에서provider_paths.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_paths로.file_paths문제 해결.

파일 경로가 /storage/emulated/0/"file"과 같은 경우

파일 공급자 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"));

안드로이드 M ~파이에서 작동합니다.

@CommonsWare의 답변은 훌륭합니다.

하지만 제 경우에는 여러 경로를 추가해야 했습니다.

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

적어도 file_paths.xml에서는 다른 경로와 동일한 경로를 제공하지 않는 것 같습니다.그러니 정확히 동일한 패키지 이름이나 경로를 다음을 포함하여 3곳에 제공해 주시기 바랍니다.

  • android:authorities매니페스트로 속성을 지정합니다.
  • pathfile_paths.xml의 특성
  • authorityFileProvider.getUriForFile()을 호출할 때 인수를 지정합니다.
  • Xamarin을 위해서.안드로이드 사용자

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


컨텍스트 제공:나는 자마린타고 누가에서 오레오를 목표로 삼았습니다. 앱과 Xam으로 사진을 찍습니다.플러그인.위의 오류 메시지로 미디어가 실패하기 시작했기 때문에 패키지를 업데이트하는 것이 효과적이었습니다.

나는 그 정책이나 행동을 주목했습니다.path.xml지원 라이브러리 26과 27 사이에서 파일이 변경되었습니다.카메라에서 사진을 캡처하기 위해 다음과 같은 변경 사항을 확인했습니다.

  • 26살 때는 제가끔.<external-path>은에 입니다.path논쟁.

  • 로 27개의 을 <external-files-path>할 수 있습니다.path논쟁.

Library 27 로 할 수 .path.xml이 였습니다.

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

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

반응형