使用 FileProvider 加载照片导致 java.lang.IllegalArgumentException:无法找到包含的已配置根
Posted
技术标签:
【中文标题】使用 FileProvider 加载照片导致 java.lang.IllegalArgumentException:无法找到包含的已配置根【英文标题】:Loading photo using FileProvider causing java.lang.IllegalArgumentException: Failed to find configured root that contains 【发布时间】:2019-11-02 21:51:50 【问题描述】:我想使用FileProvider
从相机获取照片。我完成了本教程中的所有操作,但 authority
参数导致错误。
教程:https://developer.android.com/reference/androidx/core/content/FileProvider
AndroidManifest
内部的提供者:
<provider
android:name="androidx.core.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>
<external-path name="external_files" path="."/>
</paths>
更新:
这是创建文件功能:
private fun createImageFile(): File
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
null /* directory */
)
return image
这是provider_paths.xml
(我不想要外部路径,因为我不希望用户接受存储权限来使用相机):
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name = "name"
path = "path" />
</paths>
这是打开相机功能:
private fun openCamera()
val tempFile = createImageFile()
photoUri = Uri.fromFile(tempFile)
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
if (intent.resolveActivity(a.packageManager) != null)
a.startActivityForResult(intent, REQUEST_CAMERA_NODE_MISUSE)
错误:Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/my.package.name/cache/IMG_20190620_102915_7513574861671405500.jpg
【问题讨论】:
这里也添加清单文件 【参考方案1】:确保将文件提供程序放在清单中以及 application
标记内
<application
...>
....
<provider
android:authorities = "your_string"
android:name = "androidx.core.content.FileProvider"
android:exported = "false"
android:grantUriPermissions = "true">
<meta-data
android:resource = "@xml/file_path"
android:name = "android.support.FILE_PROVIDER_PATHS" />
</provider>
</application>
而我的file_path.xml
就是这样
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name = "my_images"
path = "Android/data/com.your.package/files/Pictures" />
</paths>
并且来自java代码
val authorities = "your_string"
val imageUri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
FileProvider.getUriForFile(context!!, authorities, imageFile)
else
Uri.fromFile(imageFile)
callCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(
callCameraIntent,
CAMERA_REQUEST_CODE
)
更新
清单中的文件提供者权限和代码中的权限应该匹配。
你的问题是你的 authorities
在 manifest 和 java 代码中是不同的
`android:authorities = "$applicationId.fileprovider"`
在你的java代码中替换这个
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".provider", tempFile)
到这里
photoUri = FileProvider.getUriForFile(a, a.applicationContext.packageName + ".fileprovider", tempFile)
第二次更新
在这个函数中,你传递给不应该是这样的目录:
private fun createImageFile(): File
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
null /* directory */
)
return image
试试这个
private fun createImageFile(): File
val timeStamp = SimpleDateFormat(
"yyyyMMdd_HHmmss",
Locale.getDefault()
).format(Date())
val imageFileName = "IMG_" + timeStamp + "_"
val image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) //null /* directory */
)
return image
【讨论】:
试过了,没用。同样的例外。我的 file_path.xml 也来自教程。 我发现你的错误看看我更新的分析器 这个我以前见过,换过那个,但是更新后就不行了 发布您的完整代码、清单、provider_paths 和 java 代码,然后也许我可以检测到您的错误 在此函数中,您将传递到不应该是这种情况的目录:请参阅我的答案以上是关于使用 FileProvider 加载照片导致 java.lang.IllegalArgumentException:无法找到包含的已配置根的主要内容,如果未能解决你的问题,请参考以下文章
Intent 常用场景 FileProvider 拍照 裁剪
关于 Android 7.0 适配中 FileProvider 部分的总结
Android开发笔记(一百七十六)借助FileProvider发送彩信