gpt4 book ai didi

android - kotlin:如何在 Android 中读取 Uri?

转载 作者:行者123 更新时间:2023-11-29 23:02:14 27 4
gpt4 key购买 nike

我已经坚持了将近一个星期。 Triend 几乎所有我找到的答案/教程,但还没有运气。

我有一个使用相机的应用程序。用户拍照并选择相机中的检查/确定按钮后,相机会返回存储图像的 Uri 等信息。它以以下形式出现:content://media/external/images/media/122(这是手机中的实际图片),如果我要求 Uri.path 我会得到在这种情况下:/external/images/media/123

现在,有了 Uri 对象,我可以将它分配给像 imageView.setImageURI() 这样的 imageView 并且它可以工作,所以我非常有信心图像存储在某处.

现在,我的应用接下来应该做的是拍摄所有拍摄的照片,并将它们发送到 API。

我的问题是,当我尝试使用任何方法读取 Uri 时,无论我使用 Uri 还是路径,它都会给我一个 FileNotFound Exception

所以我真的不知道该怎么办。我错过了什么?我是否必须明确地将图像保存在工作目录中?如果是这样,它是如何完成的?如果没有,我如何获得包括文件名在内的完整路径名?当我在手机中查看 DCIM 目录时,我找不到图片。

提前致谢!

编辑

拍照代码:

    btnTomarFoto.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_DENIED || ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_DENIED
) {
// El permiso no fue concedido
val permission = arrayOf(android.Manifest.permission.CAMERA,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
requestPermissions(permission, PERMISSION_CODE)
} else {
// El permiso ya estaba concedido
openCamera()
}
} else {
// El SO es menor que Marshmallow
}
}
}

打开相机的代码:

  private fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION, "From the camera")
image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE)
}

将 Uri 存储到数据库中的代码:

  private fun guardarFoto() {
var foto = FotografiaModel(actividad_id!!, image_uri.toString(), txtObservacion.text.toString())
Log.w(tag, "URI: $image_uri PATH: " + image_uri!!.path + " Encoded Path: " + image_uri!!.encodedPath)
fotografiaDBHelper.insertFoto(foto)
visitaDBHelper.actualizaEstado(actividad_id!!, "INICIADO")
}

代码还做了一些事情,但这是主要的事情。要将接收到的 Uri 显示到我使用的 Imageview 中:

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
imageView.setImageURI(image_uri)
Log.v(tag, "Image URI: $image_uri")
}
}

最佳答案

My problem is, when I try to read the Uri with any method, it gives me a FileNotFound Exception, no matter if I use the Uri or the path.

那是因为它不是一个文件。它是一个 Uri

例如,https://stackoverflow.com/questions/56839478/kotlin-how-to-read-a-uri-in-android 是一个Uri .您的代码假定路径 /questions/56839478/kotlin-how-to-read-a-uri-in-androidUri 中唯一重要的内容。根据您的说法,地球上的每台计算机(加上轨道上的计算机)都有一个位于 /questions/56839478/kotlin-how-to-read-a-uri-in-android 的文件。这不是 Uri 的工作方式。您需要使用整个 Uri 来确定如何使用它。在这种情况下,https 作为方案意味着您使用 HTTPS 作为与指定服务器 (stackoverflow.com) 对话以检索内容的协议(protocol)。

同样,insert() 中的 Uri 中的 content 方案表明您使用 ContentResolver 来工作用它。特别是,您可以使用 openInputStream() 获取由 Uri 标识的内容的 InputStream,就像您可能使用 HttpUrlConnection 或 OkHttp 在 https Uri 上获取 InputStream

特别是,由于您将数据存储委托(delegate)给其他应用程序(MediaStore),图像的存储位置由其他人决定,并且它不一定位于文件系统中的某个位置你可以访问它。在 Android Q 及更高版本上尤其如此,您只能通过文件系统 API 对设备上的任意位置进行有限访问。

Now, next thing my app should do, is take all the pictures taken, and send them to an API.

我猜测“将它们发送到 API”意味着“将它们上传到服务器”(相对于“调用设备上的库公开的 API”或“调用 Android SDK 中的方法”)。在这种情况下,您有一些与该服务器通信的代码。它可能是通用代码(例如,OkHttp、Retrofit)或特定于 API 的代码(例如,Facebook SDK)。

无论如何,您都需要查看该代码对您的图片内容的支持:

  • 如果它支持 Uri,请尝试使用您的 Uri

  • 如果它支持 InputStream(或某种类型的 Reader),请在 ContentResolver 上使用 openInputStream()

  • 如果它支持 FileDescriptorAssetFileDescriptor,请在 ContentResolver 上使用 openFileDescriptor()/p>

  • 如果只支持File,而不是使用contentResolver.insert()获取Uri发送到相机应用程序,使用 FileProvider,这样您就可以将图像保存在您控制的文件中(例如,在 getCacheDir() 中)

关于android - kotlin:如何在 Android 中读取 Uri?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56839478/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com