是否有一种直接的方法从文件Uri获取父目录的Uri?

时间:2018-02-21 20:54:54

标签: android-file storage-access-framework android-storage

假设Uri可以是以下任何一种:

  • 来自Storage Access Framework的DocumentFile的Uri(即DocumentFile.getUri())。
  • 来自常规文件的Uri(即Uri.fromFile(File))

它指的是两种情况下目录下的文件。

有没有一种简单的方法来获取其父目录的Uri而不尝试两者中的每一个来查看哪一个有效?

[编辑]: 以下是SAF的示例:

的URI:

content://com.android.externalstorage.documents/tree/0000-0000%3Atest/document/0000-0000%3Atest%2Ffoo%2FMovies%2FRR%20parking%20lot%20a%202018_02_22_075101.mp4

的getPath():

  

/ tree / 0000-0000:test / document / 0000-0000:test / foo / Movies / RR停车场   a 2018_02_22_075101.mp4

getPathSegments():

0 = "tree"
1 = "0000-0000:test" 
2 = "document"
3 = "0000-0000:test/foo/Movies/RR parking lot a 2018_02_22_075101.mp4"

父文件夹应为test / foo / Movies。

以下是常规文件的示例:

的URI:

  

文件:///storage/emulated/0/foo/Movies/RR%20parking%20lot%20a%202018_02_22_081351.mp4

的getPath():

  

/ storage / emulated / 0 / foo / Movies / RR停车场2018_02_22_081351.mp4

getPathSegments():

0 = "storage"
1 = "emulated"
2 = "0"
3 = "foo"
4 = "Movies"
5 = "RR parking lot a 2018_02_22_081351.mp4"

1 个答案:

答案 0 :(得分:2)

晚了 3 年,我遇到了类似的问题。我已经使用 Android 26 API DocumentsContract.findDocumentPath 解决了这个问题。对我来说没问题,因为我在项目的早期 Android 版本上使用 File API。

本质上,我使用 findDocumentPath 找到文档的路径并从中删除最后一段(即找到父目录的路径)。然后,为了改革 SAF Uri,我在 Uri 中找到最后一个 / 或 : 字符,并将下一部分替换为父目录的路径。

public static String GetParentDirectory( ContentResolver resolver, String rawUri )
{
    if( !rawUri.contains( "://" ) )
    {
        // This is a raw filepath, not a SAF path
        return new File( rawUri ).getParent();
    }
    
    // Calculate the URI's path using findDocumentPath, omit the last path segment from it and then replace the rawUri's path component entirely
    DocumentsContract.Path rawUriPath = DocumentsContract.findDocumentPath( resolver, Uri.parse( rawUri ) );
    if( rawUriPath != null )
    {
        List<String> pathSegments = rawUriPath.getPath();
        if( pathSegments != null && pathSegments.size() > 0 )
        {
            String rawUriParentPath;
            if( pathSegments.size() > 1 )
                rawUriParentPath = Uri.encode( pathSegments.get( pathSegments.size() - 2 ) );
            else
            {
                String fullPath = pathSegments.get( 0 );
                int separatorIndex = Math.max( fullPath.lastIndexOf( '/' ), fullPath.lastIndexOf( ':' ) + 1 );
                rawUriParentPath = separatorIndex > 0 ? Uri.encode( fullPath.substring( 0, separatorIndex ) ) : null;
            }

            if( rawUriParentPath != null && rawUriParentPath.length() > 0 )
            {
                int rawUriLastPathSegmentIndex = rawUri.lastIndexOf( '/' ) + 1;
                if( rawUriLastPathSegmentIndex > 0 )
                {
                    String rawUriParent = rawUri.substring( 0, rawUriLastPathSegmentIndex ) + rawUriParentPath;
                    if( !rawUriParent.equals( rawUri ) )
                        return rawUriParent;
                }
            }
        }
    }

    return null;
}