如何通过 ACTION_OPEN_DOCUMENT_TREE Intent 获取真实路径?

How to get the real path with ACTION_OPEN_DOCUMENT_TREE Intent?

我的应用程序下载并解压缩特定文件夹中的文件:

output = new FileOutputStream(realpath, true);
output.write(buffer, 0, bytesRead);

ZipFile zipFile = new ZipFile(realpath);

随着新引入的 ACTION_OPEN_DOCUMENT_TREE Intent,我想为用户提供选择该文件夹的机会。

当测试在我的 onActivityResult 中收到的值时,我得到一个像 /tree/primary:mynewfolder 的路径,它不是像 /sdcard/mynewfolder.

这样的物理真实路径
Uri treeUri = data.getData();
String sPath = treeUri.getPath();
Log.v("Path from Tree ", sPath);

我的解压方法需要真实路径:

ZipFile zipFile = new ZipFile(realpath);

如何从 Lollipop 中提供的 URI(API 21 和 22)中获取像 /sdcard/mynewfolder 这样的真实路径?

从URI中获取真实Path的过程与之前相同,但增加了一点:

Uri uri = data.getData();
Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri, 
                        DocumentsContract.getTreeDocumentId(uri));
String path = getPath(this, docUri);

getPath() 方法和中间方法的要点可以在这里找到:getPath()

无需检查 android 版本..

public static string GetRealPath(DocumentFile treeUri)
        {
            if (treeUri == null)
                return "";
            var path1 = treeUri.Uri.Path;
            if (path1.StartsWith("/tree/"))
            {
                var path2 = path1.Remove(0, "/tree/".Length);
                if (path2.StartsWith("primary:"))
                {
                    var primary = path2.Remove(0, "primary:".Length);
                    if (primary.Contains(':'))
                    {
                        
                        var storeName = "/storage/emulated/0/";
                        var last = path2.Split(':').LastOrDefault();
                        var realPath = storeName + last;
                        return realPath;
                    }
                }
                else
                {
                    if (path2.Contains(':'))
                    {
                        var path3 = path2.Split(':').FirstOrDefault();
                        var storeName = path3;
                        var last = path2.Split(':').LastOrDefault();
                        var realPath = "/" + storeName + "/" + last;
                        return realPath;
                    }
                }
            }
            return path1;
        }