问题描述
我正在通过应用程序从存储中获取图片。通常,来自 onActivityResult 中的数据的 uri 不为 null,并且图片以“content://”开头。但是有些应用程序为我提供了以“file://”开头的同一张图片的uri。 Glide 也不适用于 "file://" uri。所以我想从 FileProvider 获取 uri。当我将此 uri 提供给 FileProvider 时,我收到此错误;
2021-01-10 19:01:55.453 30049-30049/com.example.photoselector E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.photoselector,PID: 30049
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null,request=1,result=-1,data=Intent { dat=file:///storage/0EE6-4002/Mete/IMG_20210108_120951.jpg typ=image/jpeg flg=0x3 }}
to activity {com.example.photoselector/com.example.photoselector.MainActivity}: java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/0EE6-4002/Mete/IMG_20210108_120951.jpg
同一张图片uri带有“content://”没有问题,当带有来自另一个应用程序的“file://”时,我得到一个错误。
我通过此代码创建意图:
private fun initData() {
button_storage.setonClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(
Intent.createChooser(
intent,"Select App"
),SELECT_PICTURE
)
}
}
从以下地址获取 Uri:
override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
super.onActivityResult(requestCode,resultCode,data)
when (resultCode) {
Activity.RESULT_OK -> {
isExistCheck.isChecked = false
setimageWiaUri(data?.data ?: tempFileUri)//tempFileUri for camera option
when (requestCode) {
CAMERA_PICTURE -> {
Toast.makeText(this,"CAMERA",Toast.LENGTH_SHORT).show()
}
SELECT_PICTURE -> {
Toast.makeText(this,"STORAGE",Toast.LENGTH_SHORT).show()
}
}
}
Activity.RESULT_CANCELED -> {
Toast.makeText(this,"CANCELED",Toast.LENGTH_SHORT).show()
}
}
}
这是我的代码:
private fun setimageWiaUri(uri: Uri) {
isExistCheck.isChecked = isFileExist(uri)
var imguri = uri
if (isFileExist(uri)) {
if (uri.toString().split(":")[0] == "file") {
imguri = FileProvider.getUriForFile(
this,"com.example.photoselector.fileprovider",File(uri.toString())
)
}
Glide.with(this)
.load(imguri)
.into(image)
} else {
Toast.makeText(this,"File does not exist...",Toast.LENGTH_SHORT).show()
}
}
我的 provider_paths :
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-cache-path
name="external_cache_files"
path="."/>
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
<external-media-path
name="external_media"
path="." />
<external-path
name="externals"
path="." />
<cache-path
name="cache_files"
path="." />
</paths>
我该如何解决这个问题,或者如何将“file://”uri 转换为“content://”uri?
解决方法
但是有些应用程序给了我以“file://”开头的uri。 Glide 也不适用于 "file://" uri
ACTION_GET_CONTENT
实现的工作是返回一个有用的 Uri
。您可以通过在 CATEGORY_OPENABLE
中添加 Intent
来消除一些麻烦的应用程序,表明您希望能够打开由 Uri
标识的内容。
Glide 可以使用 file://
Uri
,前提是您的应用有权访问该文件。
如何将“file://”uri 转换为“content://”uri?
那不是你的问题。 content://
不是表示“Uri
会起作用”的魔法字符串,而 file://
不是表示“Uri
不起作用”的魔法字符串。>
您没有解释您在使用 Glide 时遇到的具体问题。我的猜测是您没有对该文件的读取权限。如果是这样,FileProvider
不会神奇地授予您读取权限,而 HeyThisClassIsMagic
类不会授予您读取权限。您的应用要么具有读取权限,要么没有。
确保您的应用拥有 READ_EXTERNAL_STORAGE
权限并在运行时请求它。此外,请确保您的应用在清单的 android:requestLegacyExternalStorage="true"
元素中有 <application>
。这些步骤将增加您阅读由 Uri
标识的内容的可能性。
如果这没有帮助,那么我建议您提出一个单独的问题,说明您如何将返回的 file://
Uri
与 Glide 结合使用,以及您遇到的具体错误。