I'm successfully implementing a method for retrieving the real path of an image from gallery by the Uri
returned from ACTION_PICK
intent. Here's a sample:
// getRealPathFromURI(intent.getData());
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
Just like this answer.
Recently updated the compileSdkVersion
to 29
and apparently the attribute everyone's using is deprecated.
In the official docs, they recommend to use FileDescriptor instead, problem is i don't know exactly how.DATA
Only thing i found is this question. Didn't find a proper answer there though.
Please help me overcome that deprecation issue with a solution using the suggested way or any other way.
Thank you.
Followed @CommonsWare's answer and copied the returned Uri (of an image the user picked) to a local directory, using context.getContentResolver.openInputStream(Uri)
.
Even tried retrieving a file from Google Drive - and it worked. Only problem was the long time it took (about 20 sec for 5MB file).
As a bonus, i was cleared to remove external storage permissions, which one doesn't need for using app's local directories.
No more externals paths for me!
This question came up for me too a week ago.
My solution was to create an InputStream
from the URI and then, from this, create an OutputStream
by copying the contents of the input stream.
Note: You could call this method using an asynchronous call because copying extremely large files could have some delays and you won't want to block your UI
@Nullable
public static String createCopyAndReturnRealPath(
@NonNull Context context, @NonNull Uri uri) {
final ContentResolver contentResolver = context.getContentResolver();
if (contentResolver == null)
return null;
// Create file path inside app's data dir
String filePath = context.getApplicationInfo().dataDir + File.separator
+ System.currentTimeMillis();
File file = new File(filePath);
try {
InputStream inputStream = contentResolver.openInputStream(uri);
if (inputStream == null)
return null;
OutputStream outputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0)
outputStream.write(buf, 0, len);
outputStream.close();
inputStream.close();
} catch (IOException ignore) {
return null;
}
return file.getAbsolutePath();
}