从图库文件路径中选取图像 returns NULL

Pick image from gallery file path returns NULL

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

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 如果我 select 来自默认系统图像选择器的图像,尽管如果 select 来自图库应用程序的图像它工作正常.我的代码有什么问题?

不需要 ACTION_GET_CONTENT 到 return 来自 MediaStoreUriUri 否则有 DATA列。

另请注意,对于 Android 10 及以上的 MediaStore Uri 值,您无权访问 DATA 列,因此 "working fine" 是只是暂时的。

I want to pick an image from the gallery and get it's path

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

另请参阅:

 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();
        }
    }
}

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