【问题标题】:Take picture and save to gallery拍照并保存到图库
【发布时间】:2020-08-23 13:22:15
【问题描述】:

我花了几个小时研究这个问题,但没有找到任何解决方案(在 StackOverflow 上或其他方面)。 我的应用程序的目标是 API 30,minSskVersion 是 29。我正在关注本教程:https://developer.android.com/training/camera/photobasics

我的 Activity 上有一个使用 Intent 打开相机的按钮:

fun takePhoto() {
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
        takePictureIntent.resolveActivity(packageManager)?.also {
              startActivityForResult(takePictureIntent, CAMERA_REQUEST)
        }
    }
}

但我也想将图片保存在设备图库中。所以我将我的takePhoto() 方法更改为:

fun takePhoto() {
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
        takePictureIntent.resolveActivity(packageManager)?.also {
            val photoFile: File? = try {
                createImageFile()
            } catch (ex: IOException) {
                ex.printStackTrace()
                null
            }

            photoFile?.also {
                try {
                    val photoURI: Uri = FileProvider.getUriForFile(
                        this,
                        "net.filiperamos.photogrid.provider",
                        it
                    )

                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                } catch (ex: IllegalArgumentException) {
                    Log.d(TAG, "Could not get file URI.")
                    ex.printStackTrace()
                }

                startActivityForResult(takePictureIntent, CAMERA_REQUEST)
            }
        }
    }
}

并添加了createImageFile() 方法:

private fun createImageFile(): File {
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
    val filename = "image_$timeStamp"
    val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)

    return File.createTempFile(filename, ".jpg", storageDir).apply {
        currentPhotoPath = absolutePath // Save path for later use
    }
}

我的Manifest有相机使用和外部写入权限:

<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我在应用程序标签中添加了一个提供程序:

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

我创建了file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path
        name="my_images"
        path="Android/data/net.ramos.photos/files/Pictures/" />
</paths>

当我在我的设备上运行此代码时,运行FileProvider.getUriForFile() 时出现异常:

java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/net.ramos.photos/files/Pictures/image_20200823_1415398042919497737944663.jpg

如果我更改我的file_paths.xml 文件,将external-files-path 替换为external-path,错误就会消失,但没有图像存储在任何地方。

我错过了什么?

【问题讨论】:

  • "我创建了 file_paths.xml:" -- 将您的 path 值替换为 Pictures/。 “没有图像存储在任何地方”——你是如何寻找它的?它不会出现在MediaStore 中,因为存储在该位置的图像不再可索引。因此,图库风格的应用不太可能获取图像。
  • 谢谢,错误现在消失了。但我希望用我的应用程序拍摄的照片可供其他应用程序使用。如何从系统的媒体提供程序访问它?
  • 在接下来的一年左右,使用android:requestLegacyExternalStorage="true" 并写入公共位置,例如顶级Pictures/ 目录,而不是您现在使用的特定于应用程序的位置.在这一点上,考虑到整个范围的存储混乱和limits on ACTION_IMAGE_CAPTURE,我不知道一年后你想要的功能的计划是什么。

标签: android kotlin camera image-gallery android-camera-intent


【解决方案1】:

在清单文件中添加以下行作为“应用程序”标签的属性,

android:requestLegacyExternalStorage="true"

这应该可以解决您面临的问题并且异常应该消失。

【讨论】:

  • 这不起作用:如果我保留external-files-path,我仍然会看到错误,如果我将其更改为external-path,我看不到错误,但我也看不到保存的图像。虽然看起来,根据@CommonsWare,我正在寻找错误位置的照片......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多