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/
되어 있지 않으므로 path
XML 의 속성이 유효하지 않습니다.
다음으로 교체하십시오 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 path
vsrelative 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.xml
Manifest에서 설정되어 있는 동안 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_paths
에 file_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의 태그를 포함해야 함을 의미 합니다. 그래서 mRoots
uri의 인쇄 및 태그 코드를 작성한 다음 태그가 일치하지 않는 것을 쉽게 찾습니다 .
공급자 권한을 설정 ${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/" />
'Programing' 카테고리의 다른 글
해시에 새 항목을 추가하는 방법 (0) | 2020.06.01 |
---|---|
“! ==”와“==!”의 차이점 (0) | 2020.06.01 |
파이썬에서 RGB 이미지를 그레이 스케일로 어떻게 변환 할 수 있습니까? (0) | 2020.06.01 |
jquery 라이브 호버 (0) | 2020.06.01 |
S3-액세스 제어 허용 오리진 헤더 (0) | 2020.06.01 |