繁体   English   中英

Android _data' 在 getContentResolver 上不存在

[英]Android _data' does not exist on getContentResolver

getColumnIndexOrThrow 的原因可能会引发异常

java.lang.IllegalArgumentException:列“_data”不存在。 可用列:[]

但是,如果您重命名文件并重试,它会起作用吗?

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

原始文件的意图是

内容://com.sec.android.app.myfiles.FileProvider/device_storage/Download/myfile.pdf

然而重命名的文件作为

内容://0@media/external/file/588

MediaStore.Files.FileColumns.DATA已弃用,并且column '_data'不再存在。

正如Android 开发人员所说

此常量在 API 级别 29 中已弃用。

应用程序可能没有直接访问此路径的文件系统权限。 应用程序不应尝试直接打开此路径,而应使用 ContentResolver#openFileDescriptor(Uri, String) 来获得访问权限。

如何使用openFileDescriptor

我尝试在跨应用程序中引入 2 个不同的广泛使用文件的示例

图像文件

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

如何处理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();

有很多例子说明如何处理FileInputStreamFileOutputStream

结论

尝试获取absolute Path是没有意义的,尽管除非引发安全和隐私问题,否则没有必要。确实, Relative path足以处理文件,并且在kernel ModeUser Mode之间存在Abstract Representation implementations ,可以 Map Relative Path Absolute Path和用户不需要知道。

openFileDescriptor速度非常快,兼容所有 android 版本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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