1

I want to pick an image from the gallery and get it's path. Here is the code I use to open the gallery

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

and 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 always is null if I select the image from the default system image picker, although it is working fine if select an image from the gallery app. What is wrong with my code ?

Mo Dev
  • 475
  • 6
  • 17

3 Answers3

5

There is no requirement for ACTION_GET_CONTENT to return a Uri from the MediaStore or a Uri that otherwise has a DATA column.

Also note that you do not have access to the DATA column for MediaStore Uri values on Android 10 and above, so "working fine" is only true temporarily.

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

There is no path. The user could be choosing a piece of content from a cloud storage provider, such as Google Drive.

See also:

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
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();
        }
    }
}
Ehsan Aminifar
  • 515
  • 4
  • 15
1

MediaStore.Images.Media.DATA is deprecated from android 10. Though it will work, if you add the following to AndroidManifest.xml

android:requestLegacyExternalStorage="true"

But it is a temporary solution, if you want to read a file and do something with it you should store it to the app-specific temporary storage, that is there for every android application. Using the app-specific storage do not requires any permission from the user.

So you can use the below code, if you already have the Uri of selected file.

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)

And the function to get the file name from the Uri is

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
}

Source: Android Upload File to Server

Belal Khan
  • 2,099
  • 2
  • 22
  • 32