Search code examples
androidandroid-sdcardstorage-access-framework

Android Storage Access Framework Document Create File & Dir Recursively


First of all.

Thank you for reading this question.

Currently, I am new to Android(Like it has been a month I've started learning)

And now I need to write Files and Directories "RECURSIVELY" on SD card.

My code below kind of works.....

private void recursiveFolderDownload(String src, Uri dst) throws SftpException {
    Log.e("dst",dst.toString());
    DocumentFile pickedDir = DocumentFile.fromTreeUri(context, dst);
    Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(src);
    for (ChannelSftp.LsEntry item : fileAndFolderList) {
        if (!item.getAttrs().isDir()) {
            DocumentFile newFile = pickedDir.createFile("",item.getFilename());
            write(src + "/" + item.getFilename(),newFile.getUri());
        } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
            DocumentFile newDir = pickedDir.createDirectory(item.getFilename());
            recursiveFolderDownload(src + "/" + item.getFilename(), newDir.getUri());
        }
    }
}

Honestly speaking, every and each files&dirs I write are just written only on the same path

which is the top(content://com.android.externalstorage.documents/tree/E3AB-1A0D%3A)

I mean it!

Every files and directories are just written on top!

Am I missing something here?

If I do, please wise man guide me with a solution.

And again, Thank you for reading this question

hope u have a nice day


Solution

  • See if this works better:

    private void recursiveFolderDownload(String src, DocumentFile pickedDir) throws SftpException {
        Log.e("dst",dst.toString());
    
        Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(src);
    
        for (ChannelSftp.LsEntry item : fileAndFolderList) {
            if (!item.getAttrs().isDir()) {
                DocumentFile newFile = pickedDir.createFile("",item.getFilename());
                write(src + "/" + item.getFilename(),newFile.getUri());
            } else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
                DocumentFile newDir = pickedDir.createDirectory(item.getFilename());
                recursiveFolderDownload(src + "/" + item.getFilename(), newDir);
            }
        }
    }
    

    In your existing code, you:

    • Create a directory using createDirectory()
    • Unwrap the DocumentFile from createDirectory() using getUri()
    • Try to recreate the DocumentFile using fromTreeUri()

    It is safer, and more efficient, to just keep using DocumentFile until you absolutely need a Uri (in write()).

    Your initial call to recursiveFolderDownload() would use the DocumentFile.fromTreeUri(context, dst) call that I removed from your original sample.