簡體   English   中英

從 Uri 獲取真實路徑 - DATA 在 android Q 中已棄用

[英]Get real path from Uri - DATA is deprecated in android Q

我正在成功實現一種方法,該方法通過從ACTION_PICK意圖返回的Uri從圖庫中檢索圖像的真實路徑。 這是一個示例:

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

就像這個答案一樣。

最近將compileSdkVersion更新為29 ,顯然DATA 每個人都使用的屬性已棄用 在官方文檔中,他們建議改用FileDescriptor ,問題是我不知道具體如何。
我唯一發現的是這個問題 雖然沒有找到正確的答案。

請使用建議的方式或任何其他方式幫助我解決該棄用問題。

謝謝你。


更新:

遵循@CommonsWare回答並使用context.getContentResolver.openInputStream(Uri)將返回的 Uri(用戶選擇的圖像)復制到本地目錄。

甚至嘗試從 Google Drive 中檢索文件 - 並且成功了。 唯一的問題是花費了很長時間(5MB 文件大約需要 20 秒)。

作為獎勵,我被清除刪除外部存儲權限,使用應用程序的本地目錄不需要該權限。

我沒有更多的外部路徑!

一周前我也提出了這個問題。

我的解決方案是從 URI 創建一個InputStream ,然后通過復制輸入流的內容來創建一個OutputStream

注意:您可以使用異步調用來調用此方法,因為復制非常大的文件可能會有一些延遲,並且您不想阻塞您的 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();
}

我正在成功實現一種方法,該方法通過從 ACTION_PICK 意圖返回的 Uri 從圖庫中檢索圖像的真實路徑。

該代碼可能不適用於所有圖像。 DATA不需要指向您可以訪問的文件系統路徑。

就像這個答案一樣。

FWIW,是我對那個問題的回答。

我發現的唯一一件事就是這個問題。 雖然沒有找到正確的答案。

由於 Android 已鎖定/proc ,因此該技術不是特別好並且將不再起作用。

在官方文檔中,他們建議改用 FileDescriptor,問題是我不知道具體如何。

更一般的概念是您使用ContentResolver來處理Uri ,無論您獲得InputStream ( openInputStream() )、 OutputStream ( openOutputStream() ) 還是FileDescriptor 使用這些東西來消費內容。 如果您有一些絕對需要文件的 API,請將內容(例如,從InputStream中)復制到您控制的文件中(例如,在getCacheDir()中)。

作為獎勵,現在您的代碼也可以使用存儲訪問框架(例如ACTION_OPEN_DOCUMENT )和 Internet(例如 OkHttp),如果它們有用的話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM