简体   繁体   中英

Android _data' does not exist on getContentResolver

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.

How To use openFileDescriptor ?

i try to bring examples of 2 different widely use files in across application

Image Files

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

Non-Image Files

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

Conclusion

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM