Search code examples
javaandroidstorage-access-framework

When i start the intent ACTION_OPEN_DOCUMENT_TREE it automatically opens empty recent folder?


What i'm trying to achieve is to delete a file on the sd card, i tried the file.delete method which didn't work because sd cards are read only now.

So i read a post about SAF (Storage Access Framework) to gain sd card write access by storing the treeUri we get in onActivityResult.

File deleting works fine now, but when i start the intent Intent.ACTION_OPEN_DOCUMENT_TREE sometimes it returns the recent folder which is empty and the way to show the files on the sdcard is to click on the overflow icon and then select show SDCARD or Internal Storage which may confuse some people when they run my app.

i tried adding these to my intent: intent.putExtra("android.content.extra.SHOW_ADVANCED", true); intent.putExtra("android.content.extra.FANCY", true); intent.putExtra("android.content.extra.SHOW_FILESIZE", true);

which works on some devices, but it's a private API and on some it doesn't work.

So is there a way to like automatically open a specific directory or show a hint dialog with steps explaining which directory they should chose?

private void getSDCardAccess(){
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath());
    startActivityForResult(intent, REQUEST_EXTERNAL_ACCESS);
} 


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_EXTERNAL_ACCESS && resultCode == RESULT_OK) {
        Uri treeUri = null;

        if (data != null){
            treeUri = data.getData();
        }

        if (treeUri != null && getActivity() != null) {
            getActivity().getContentResolver().takePersistableUriPermission(treeUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION |
                            Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            StorageUtil storageUtil = new StorageUtil(getActivity());
            //Takes the access so that we can use it again after the app reopens
            storageUtil.storeTreeUri(treeUri.toString());
            Log.d(TAG, "treeUri: " + treeUri.toString());
        }else{
            Log.d(TAG,"uri is empty!");
        }
    }
} 

Solution

  • is there a way to like automatically open a specific directory

    If you have a Uri to it that you got from ACTION_OPEN_DOCUMENT_TREE previously, you should be able to supply that via DocumentsContract.EXTRA_INITIAL_URI. Per the ACTION_OPEN_DOCUMENT_TREE documentation:

    Callers can set a document URI through DocumentsContract.EXTRA_INITIAL_URI to indicate the initial location of documents navigator. System will do its best to launch the navigator in the specified document if it's a folder, or the folder that contains the specified document if not.


    or show a hint dialog with steps explaining which directory they should chose?

    You would need to do that yourself, prior to calling startActivityForResult() for the ACTION_OPEN_DOCUMENT_TREE request.