Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining available space within Storage Access Framework for 5.0+ OS ver

Tags:

android

I have an application that allows the user to select their media destination via SAF using OPEN_DOCUMENT_TREE. As new media files are added, I would like to check to make sure there is a minimum amount of space rather than filling it up. It is also could be used for selecting the amount of file cache if the size of the destination is known.

AFAIK, DocumentFile, etc., doesn't give you anything. Technically, if you go through OPEN_DOCUMENT_TREE, the actual destination isn't known, while it could be the sdcard, it could also be a cloud destination.

However, maybe someone has done enough experimentation to reliably determine the flash drive being used. If the user chooses the primary partition then it can be extracted from DocumentFile, at least I can excluded the primary space. Sdcard mount points vary among devices so getting an accurate map might be problematic.

I can get the space of the sdcards available using the standard getFilesDir or getMediaFilesDir and use the file to get available space.

So how to find the space if you only have a DocumentFile object?

like image 332
Bruce Avatar asked Jul 01 '15 21:07

Bruce


1 Answers

Ok, I have found some kind of solution. This was tested on android 5.1 set-top-box. First, get the treeUri from ACTION_OPEN_DOCUMENT_TREE. Then do the following:

    Uri docTreeUri = DocumentsContract.buildDocumentUriUsingTree(
            treeUri,
            DocumentsContract.getTreeDocumentId(treeUri)
    );
    try {
        ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(docTreeUri, "r");
        assert pfd != null;
        StructStatVfs stats = Os.fstatvfs(pfd.getFileDescriptor());
        Log.i(LOG_TAG, "block_size=" + stats.f_bsize + ", num_of_blocks=" + stats.f_bavail);
        Log.i(LOG_TAG, "free space in Megabytes:" + stats.f_bavail * stats.f_bsize / 1024 / 1024);
    } catch (FileNotFoundException | ErrnoException e) {
        Log.e(LOG_TAG, Log.getStackTraceString(e));
    }
like image 151
Gleb Avatar answered Oct 20 '22 01:10

Gleb