从图库文件路径中选择图像返回NULL

时间:2019-08-27 23:31:51

标签: android android-intent android-image

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

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,尽管从Gallery应用程序中选择图像也可以正常工作。我的代码有什么问题?

3 个答案:

答案 0 :(得分:4)

ACTION_GET_CONTENT不需要从Uri返回MediaStore或另外有Uri列的DATA

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

  

我想从图库中选取一张图片并获取其路径

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

另请参阅:

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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