簡體   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