简体   繁体   中英

DocumentsContract's buildChildDocumentsUriUsingTree(uri, DocumentsContract.getTreeDocumentId(uri)); returns parent Uri tree

I am trying to use DocumentsContract to traverse a directory recursively using the following method.

    void traverseDirectoryEntries(Uri rootUri) {
        ContentResolver contentResolver = activityMain.getContentResolver();
        Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(
                rootUri, DocumentsContract.getTreeDocumentId(rootUri));
        List<Uri> dirNodes = new LinkedList<>();
        dirNodes.add(childrenUri);
        while (!dirNodes.isEmpty()) {
            childrenUri = dirNodes.remove(0); // get the item from top
            try (Cursor cursor = contentResolver.query(childrenUri, new String[]{
                            DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                            DocumentsContract.Document.COLUMN_DISPLAY_NAME,
                            DocumentsContract.Document.COLUMN_MIME_TYPE},
                    null, null, null)) {
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        final String docId = cursor.getString(0);
                        final String name = cursor.getString(1);
                        final String mime = cursor.getString(2);
                        if (isDirectory(mime)) {
                            final Uri newNode = DocumentsContract.buildChildDocumentsUriUsingTree(
                                    rootUri, docId);
                            traverseDirectoryEntries(newNode);
                        }
                    }
                }
            }
        }
    }

    // Util method to check if the mime type is a directory
    private static boolean isDirectory(String mimeType) {
        return DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType);
    }

Unfortunately, this does not work. It goes through the same root directory over and over despite the directory passed in being a child of the root. The line final Uri newNode = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, docId); returns a Uri with the child directory attached at the end. That works fine. The problem is the follwing line: Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, DocumentsContract.getTreeDocumentId(rootUri)); where rootUri is the newNode. I get the same childrenUri; the one I got from rootUri. Is this a bug? Did I make a mistake? Is the docId wrong? I tried getDocumentId(rootUri) , but that throws an error because the id it returns is not a tree. It is almost like getTreeDocumentId(rootUri) is returning what getRootId(rootUri) should be returning. Is there a way to fix this?

The rootUri was obtained via ACTION_OPEN_DOCUMENT_TREE . I am running this on Android Pie. I left some code out where I am building a tree structure from the data.

You are abusing this well known void traverseDirectoryEntries(Uri rootUri) function.

You think it is recursive but it is not.

Remove the recursive call and instead add 'newNode' to the list.

// traverseDirectoryEntries(newNode);

dirNodes.add(newNode); 

Then you make use of the list.

Then original code is restored.

Who changed it without telling so?

Of course you can adapt this function to make it recursiv.

Nice exercise ;-).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM