【问题标题】:Pick image from gallery file path returns NULL从图库文件路径中选择图像返回 NULL
【发布时间】:2019-08-27 23:31:51
【问题描述】:

我想从图库中挑选一张图片并获取它的路径。这是我用来打开图库的代码

Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(Intent.createChooser(intent,
                            "Select Picture"), 1111);

onActivityResult

protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    if (resultCode == RESULT_OK) {
        Uri selectedImageUri = imageReturnedIntent.getData();

        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String filePath = cursor.getString(columnIndex);
        cursor.close();

        Log.d("TAG", "onActivityResult: " + filePath);
    }
}

filePath 总是 null 如果我从默认系统图像选择器中选择图像,但如果从图库应用程序中选择图像则工作正常。我的代码有什么问题?

【问题讨论】:

    标签: android android-intent android-image


    【解决方案1】:

    ACTION_GET_CONTENT 没有要求从 MediaStoreUri 返回 Uri,否则 DATA 列。

    另请注意,在 Android 10 及更高版本上,您无权访问 DATA 列的 MediaStore Uri 值,因此“工作正常”只是暂时的。

    我想从图库中挑选一张图片并获取它的路径

    没有路径。用户可能正在从云存储提供商(例如 Google Drive)中选择一段内容。

    另见:

    【讨论】:

      【解决方案2】:
       private void loadGallery() {
          Intent choose = new Intent(Intent.ACTION_PICK,
                  MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
          startActivityForResult(choose, PICK_IMAGE_GALLERY);
      }
      
      
      
           @Override
          public void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
      
          if (requestCode == PICK_IMAGE_GALLERY) {
              if (resultCode == Activity.RESULT_OK) {
              Uri selectedImage = data.getData();
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        MediaStore.Images.Media.DATA 已从 android 10 中弃用。虽然它会起作用,但如果您将以下内容添加到 AndroidManifest.xml

        android:requestLegacyExternalStorage="true"
        

        但这是一个临时解决方案,如果您想读取文件并对其进行处理,您应该将其存储到特定于应用程序的临时存储中,该临时存储适用于每个 Android 应用程序。使用特定于应用程序的存储不需要用户的任何许可。

        因此,如果您已经拥有所选文件的 Uri,则可以使用以下代码。

        val parcelFileDescriptor =
            contentResolver.openFileDescriptor(selectedImageUri!!, "r", null) ?: return
        
        val inputStream = FileInputStream(parcelFileDescriptor.fileDescriptor)
        val file = File(cacheDir, contentResolver.getFileName(selectedImageUri!!))
        val outputStream = FileOutputStream(file)
        inputStream.copyTo(outputStream)
        

        而从Uri中获取文件名的函数是

        fun ContentResolver.getFileName(fileUri: Uri): String {
            var name = ""
            val returnCursor = this.query(fileUri, null, null, null, null)
            if (returnCursor != null) {
                val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                returnCursor.moveToFirst()
                name = returnCursor.getString(nameIndex)
                returnCursor.close()
            }
            return name
        }
        

        来源:Android Upload File to Server

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-16
          • 2020-08-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多