What might the cause of getColumnIndexOrThrow that would throw an exception of
java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: []
yet if you rename the file and retry again, it works?
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String[] projection = {
MediaStore.Files.FileColumns.DATA
};
try {
cursor = context.getContentResolver().query(
uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int cindex = cursor.getColumnIndexOrThrow(projection[0]);
return cursor.getString(cindex);
}
}
catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
the original file comes in the intent of
content://com.sec.android.app.myfiles.FileProvider/device_storage/Download/myfile.pdf
yet the renamed file comes in as
content://0@media/external/file/588
This MediaStore.Files.FileColumns.DATA
is deprecated and column '_data'
doesn't exist anymore.
As Android Developer stated
This constant was deprecated in API level 29.
Apps may not have filesystem permissions to directly access this path. Instead of trying to open this path directly, apps should use ContentResolver#openFileDescriptor(Uri, String) to gain access.
i try to bring examples of 2 different widely use files in across application
if(uri==null)return;
ContentResolver contentResolver = getActivity().getContentResolver();
if(contentResolver==null)return;
ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri,"rw");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
if(fileDescriptor==null)return;
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
There are a lot of examples of how to handle bitmap
if(uri==null)return;
ContentResolver contentResolver = getActivity().getContentResolver();
if(contentResolver==null)return;
ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri,"rw");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
if(fileDescriptor==null)return;
FileInputStream fileInputStream = new FileInputStream(fileDescriptor);
FileOutputStream fileOutputStream = new FileOutputStream(fileDescriptor);
parcelFileDescriptor.close();
There are a lot of examples of how to handle FileInputStream
and FileOutputStream
There is no sense trying to get absolute Path
although it isn't necessary unless raising security & privacy issues.Indeed, Relative path
is enough for working with files and there are Abstract Representation implementations
between kernel Mode
and User Mode
that can Map Relative Path
to Absolute Path
and User doesn't need to know.
openFileDescriptor
is very fast and compatible to all android versions