使用 ActivityResultContracts.GetContent() 将图像保存到内部存储器。 - (Kotlin/Java/Android)
Save image to internal storage using ActivityResultContracts.GetContent(). - (Kotlin/Java/Android)
我是文件存储新手。我的主要目标是用相机拍照,以高质量存储它,然后在 ImageView 中显示它。我想避免请求用户许可(使用相机和外部存储),并希望尽可能简单。
为了拍照,我用的是
val capturePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { it: Boolean -> }
。
我不知道如何从这个函数中获取位图,或者我是否应该这样做。据我了解,我应该在调用 capturePicture.launch(uri)
.
时发送 uri
我的问题是这是否正确,还有我如何获取 URI,将其保存到内部存储 (.openFileOutput()
),然后从内部存储加载它。
我更喜欢 Kotlin 的答案,但 Java 也可以。
关于路径如何在内部存储中工作的解释也可能有帮助。
我按照这个 medium article 教程进行了调整,并为我的用例添加了更多功能。
缓存目录中保存的图片
要拍照:
private val takeImageResult =
registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let { uri ->
loadPhotosFromInternalStorageIntoRecyclerView()
}
}
}
调用拍照、保存并获取 uri:
private var latestTmpUri: Uri? = null
private fun takeImage() {
lifecycleScope.launchWhenStarted {
getTmpFileUri().let { uri ->
latestTmpUri = uri
takeImageResult.launch(uri)
}
}
}
private fun getTmpFileUri(): Uri {
val tmpFile = File.createTempFile("tmp_image_file", ".jpg", requireActivity().cacheDir).apply {
createNewFile()
deleteOnExit()
}
return FileProvider.getUriForFile(requireActivity().applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
加载图片(加载图片列表中的第一张图片):
private fun loadPhotosFromInternalStorage(): List<InternalStoragePhoto> {
val files = requireActivity().cacheDir.listFiles()
return files?.filter {
it.canRead() && it.isFile && it.name.endsWith(".jpg")
}?.map {
InternalStoragePhoto(it.name, it.toUri())
} ?: listOf()
}
private fun displayImage() {
Glide.with(photoImg.context)
.load(loadPhotosFromInternalStorage()[0].uri)
.into(photoImg)
}
这是图像的自定义对象:
data class InternalStoragePhoto(
val name: String,
val uri: Uri?
)
这是我的代码的简化版本,这是测试应用程序的源代码github repo
我是文件存储新手。我的主要目标是用相机拍照,以高质量存储它,然后在 ImageView 中显示它。我想避免请求用户许可(使用相机和外部存储),并希望尽可能简单。
为了拍照,我用的是
val capturePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { it: Boolean -> }
。
我不知道如何从这个函数中获取位图,或者我是否应该这样做。据我了解,我应该在调用 capturePicture.launch(uri)
.
我的问题是这是否正确,还有我如何获取 URI,将其保存到内部存储 (.openFileOutput()
),然后从内部存储加载它。
我更喜欢 Kotlin 的答案,但 Java 也可以。 关于路径如何在内部存储中工作的解释也可能有帮助。
我按照这个 medium article 教程进行了调整,并为我的用例添加了更多功能。
缓存目录中保存的图片
要拍照:
private val takeImageResult =
registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let { uri ->
loadPhotosFromInternalStorageIntoRecyclerView()
}
}
}
调用拍照、保存并获取 uri:
private var latestTmpUri: Uri? = null
private fun takeImage() {
lifecycleScope.launchWhenStarted {
getTmpFileUri().let { uri ->
latestTmpUri = uri
takeImageResult.launch(uri)
}
}
}
private fun getTmpFileUri(): Uri {
val tmpFile = File.createTempFile("tmp_image_file", ".jpg", requireActivity().cacheDir).apply {
createNewFile()
deleteOnExit()
}
return FileProvider.getUriForFile(requireActivity().applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
加载图片(加载图片列表中的第一张图片):
private fun loadPhotosFromInternalStorage(): List<InternalStoragePhoto> {
val files = requireActivity().cacheDir.listFiles()
return files?.filter {
it.canRead() && it.isFile && it.name.endsWith(".jpg")
}?.map {
InternalStoragePhoto(it.name, it.toUri())
} ?: listOf()
}
private fun displayImage() {
Glide.with(photoImg.context)
.load(loadPhotosFromInternalStorage()[0].uri)
.into(photoImg)
}
这是图像的自定义对象:
data class InternalStoragePhoto(
val name: String,
val uri: Uri?
)
这是我的代码的简化版本,这是测试应用程序的源代码github repo