繁体   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