Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
kotlin:如何在Android中读取Uri?_Android_Kotlin - Fatal编程技术网

kotlin:如何在Android中读取Uri?

kotlin:如何在Android中读取Uri?,android,kotlin,Android,Kotlin,这件事我已经坚持了将近一个星期了。我找到了几乎所有的答案/教程,但还没有找到运气 我有一个使用相机的应用程序。在用户拍摄了一张照片,并选择相机中的check/OK按钮后,相机会返回存储图像的Uri。它以:content://media/external/images/media/122(这是手机中的实际图片),如果我询问Uri.path,我将在本例中得到:/external/images/media/123 现在,有了Uri对象,我可以将它分配给一个imageView,如imageView.se

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

我有一个使用相机的应用程序。在用户拍摄了一张照片,并选择相机中的check/OK按钮后,相机会返回存储图像的Uri。它以:
content://media/external/images/media/122
(这是手机中的实际图片),如果我询问Uri.path,我将在本例中得到:
/external/images/media/123

现在,有了Uri对象,我可以将它分配给一个imageView,如
imageView.setImageURI()
,它就可以工作了,所以我非常确信这些图像存储在某个地方

现在,我的应用程序应该做的下一件事是拍摄所有拍摄的照片,并将它们发送到API

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

所以我真的不知道该怎么办。我错过了什么?是否必须将映像显式保存在工作目录中?如果是,是如何做到的?如果没有,如何获取包括文件名在内的完整路径名?当我在电话里看DCIM导演时,我没有找到照片

提前谢谢

编辑

获取pic的代码:

    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")
  }
代码还可以做更多的事情,但这是最主要的。要在Imageview中显示收到的Uri,我使用:

  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")
    }
  }
我的问题是,当我尝试用任何方法读取Uri时,它都会给我一个FileNotFound异常,无论我使用的是Uri还是路径

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

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

类似地,来自
insert()
Uri
中的
content
方案指示您使用
ContentResolver
来处理它。特别是,您可以使用
openInputStream()
Uri
标识的内容上获取
InputStream
,就像您可以使用
HttpUrlConnection
或OkHttp在
https
Uri
上获取
InputStream
一样

特别是,由于您将数据存储委托给了其他应用程序(MediaStore),因此存储映像的位置由其他人决定,并且映像不一定位于文件系统中您可以访问的位置。在Android Q和更高版本上尤其如此,在Android Q和更高版本中,您可以通过文件系统API限制对设备上任意位置的访问

现在,我的应用程序应该做的下一件事是拍摄所有拍摄的照片,并将它们发送到API

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

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

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

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

  • 如果它支持
    FileDescriptor
    AssetFileDescriptor
    ,请在
    ContentResolver上使用
    openFileDescriptor()

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

  • 等等


你能发布你的代码吗?到目前为止,你尝试了什么,我们可以完全理解你的问题。哦,我明白了。。。我的第一个错误是认为URI是一个指向物理文件的指针,由相机自己保存,看起来不是。那么URI代表什么呢在其他方面,API希望我通过POST向它传递一个图像文件。我应该如何处理相机刚刚拍摄的图像?@luisfer:“那么URI是什么?”——“API希望我通过POST向其传递一个图像文件”——您需要与Web开发人员交谈,并确定这到底意味着什么(例如,这是JPEG字节的base64编码字节数组吗?)。然后,您需要决定如何与该API通信(例如,改装)。然后,也只有到那时,你才能开始决定如何处理用户用相机应用程序拍摄的图像。我是API的开发者。它需要一个类似于您从HTML
表单通过邮件传递的文件。我正在使用截击,我发现它非常容易使用,而且对于我正在尝试做的事情来说已经足够了。@luisfer:我没有使用截击来满足这种请求,所以我无法提供如何使用它的详细信息。最有可能的情况是,您将以某种形式使用
ContentResolver
openInputStream()