android - Android Q:从图库中获取图像并进行处理
问题描述
我知道这似乎是一个非常基本的问题,但它专门针对 Android Q。
我只想从图库中获取图像并将其压缩并发送到服务器。但由于 Android Q 的 Scoped Storage,它比我想象的要难。我将首先解释我对代码所做的事情:
首先,我发出选择图像的意图。
fun openGallery(fragment: Fragment){
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
intent.type = "*/*"
val mimeTypes = arrayOf("image/*")
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
fragment.startActivityForResult(intent, REQUEST_IMAGE_PICK)
}
它工作正常,我可以在 onActivityResult 方法中获取图像
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE_PICK && resultCode == Activity.RESULT_OK && null != data) {
val selectedImage = data.data
val source = ImageDecoder.createSource(activity!!.contentResolver, selectedImage)
val bitmap = ImageDecoder.decodeBitmap(source)
mBinding.circularProfileImage.setImageBitmap(bitmap)
}
}
好的,现在的问题是如何以文件格式访问此图像,以便进一步处理/压缩它。
以下是我尝试过的事情:
val mImagePath = getImagePathFromUri(activity!!, selectedImage)
这是我得到的路径:
/storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg
我通过以下方式从中创建了一个文件:
val file = File(mImagePath)
以下是我压缩和上传图像的自定义逻辑:
val mNewFile = MediaCompressor.compressCapturedImage(activity!!, file, "ProfilePictures")
uploadProfile(mNewFile)
在这个自定义逻辑中,我有一个方法来处理图像的采样和旋转,如下所示:
fun handleSamplingAndRotationBitmap(context: Context, selectedImage: File, reqWidth: Int, reqHeight: Int): Bitmap {
val mUri = Uri.fromFile(selectedImage)
// First decode with inJustDecodeBounds=true to check dimensions
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
var imageStream = context.contentResolver.openInputStream(mUri)
BitmapFactory.decodeStream(imageStream, null, options)
imageStream!!.close()
// Calculate inSampleSize
options.inSampleSize =
calculateInSampleSize(options, reqWidth, reqHeight)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
imageStream = context.contentResolver.openInputStream(mUri)
var img = BitmapFactory.decodeStream(imageStream, null, options)
img = rotateImageIfRequired(context, img!!, mUri)
return img
}
但是当我尝试使用context.contentResolver.openInputStream打开流时 ,出现以下错误:
java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg: open failed: EACCES (Permission denied)
我知道我得到了这个,因为在 Android 10 中,我们无权直接从外部存储访问文件。
所以,请帮我解决这个问题,如何在 Android 10 中将外部存储中的图像用作文件。
注意:我拥有所有必需的权限,所以这不是问题
解决方案
以下是我尝试过的事情:
没有可能的可靠getImagePathFromUri()
实现。
在这个自定义逻辑中,我有一个方法来处理图像的采样和旋转,如下所示:
您不需要 aFile
在该功能中。毕竟,您在该函数中的第一个语句Uri
会从 that 中创建一个File
。因此,将File
参数替换为Uri
您拥有的参数,然后跳过Uri.fromFile()
调用。
如何在 Android 10 中将外部存储中的图像用作文件。
你不能。而且,如上所示,您所做的事情并不需要它。
如果您发现自己陷入使用某些绝对肯定必须具有的库或 API 的情况File
:
- 就像您今天所做的那样
InputStream
,使用 对内容打开一个contentResolver.openInputStream()
- 将其中的字节复制
InputStream
到FileOutputStream
您可以读/写的文件中的某个文件(例如,getCacheDir()
在 上Context
) - 将您的副本与需要
File
推荐阅读
- php - PHP PDO SQLite中查询字符串的最大长度?
- tomcat - Tomcat procrun 安装程序不适用于 catalina_home 路径中的空格
- r - 找不到函数“(<-”
- linux - 如何删除文件Shell脚本中的文本块?
- python - 过滤 1000 个大文件 pyspark 中的 Header 2 行和 Trailer 1 行
- python - 我正在观看 Reducible 关于递归的视频并看到了这段代码,但我无法理解它是如何工作的,有人可以解释一下吗?
- java - 使用 JNI 创建 JFrame
- prometheus - Prometheus 指标不会显示 Java 类
- java - 如何为此使用包装器的日志过滤器编写单元测试
- typescript - 使用导入/导出时出现 webpack 错误