Search code examples
androidstorage-access-frameworkcreate-directory

How to create a subfolder of a Uri folder, Android 10+?


It was here before SDK 29, but now it is required.

My app creates a cascade of folders to manage its content. All the content is meant to be stored inside any folder the user chooses, but for the living hell, I can't figure out, how to create a folder in a Uri folder and access it later (because Storage access framework - ACTION_OPEN_DOCUMENT_TREE).

I tried to create a folder and a file inside using DocumentFile, which worked well (now that doesn't work either), on the other hand, when I copied some files to that directory, it prohibited me from accessing those files in any way. I need to access those files even if I move them as I have a copy of the older content I had on a different device, but now it cannot access those files.

One more thing to add, the first time I tried to log the filenames it worked. But when I ran the code once again, it gave me SecurityExceptions about not using ACTION_OPEN_DOCUMENT to get those files' references. But it should give me full power over the selected directory, right?

Used code to create a subFile/subFolder:

DocumentFile file = DocumentFile.fromTreeUri(context, data.getData());

public DocumentFile getChild(String name) {
    DocumentFile child = file.findFile(name);
    if (name.matches(".*\\..{3,4}$")) {
        String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                name.substring(name.lastIndexOf('.')));
        return child != null ? child : file.createFile(
                mimetype == null ? "application/dat" : mimetype, name);
    }
    return child != null ? child : file.createDirectory(name);
}

Any reference to a manual I couldn't find would help.


Solution

  • Edited, you need to add getflags on creating anything in folder.

    final int takeFlags = intent.getFlags() & 
    (Intent.FLAG_GRANT_READ_URI_PERMISSION | 
    Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    

    The object t is a shared prefernce just to save the strings uri, you can switch them.out for your object.

    Use this when you need to create folder, use in public void as function

    Intent intent = new  
    Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 
    startActivityForResult(intent, 
    NEW_FOLDER_REQUEST_CODE);
    

    Use this to get activity result of created folder

    if (_resultCode == Activity.RESULT_OK) { 
    if (_requestCode == 
    NEW_FOLDER_REQUEST_CODE) { if (_data != 
    null) { Uri currentUri = 
    _data.getData();
    DocumentFile pickedDir = 
    DocumentFile.fromTreeUri(this, 
    currentUri);
    DocumentFile newDir =
    pickedDir.createDirectory("MyFolder");
    
    final int takeFlags = 
    Intent.FLAG_GRANT_READ_URI_PERMISSION | 
    Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 
    
    } } }