Wednesday, November 17, 2021

[SOLVED] Can an Android app obtain write permission to /mnt/asec or /mnt/obb?

Issue

I have an application that performs a write operation on an external SD Card (external as in not the "external" in the device's flash memory), but as it has been thoroughly discussed here and in quite a few other questions, it appears there is no generic way / supported API to retrieve an SD Card mounting point that works on every phone, from different manufacturers.

With that in mind, something like the code below needs to be done to find out if an external storage device is mounted and where:

final String state = Environment.getExternalStorageState();

if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) {  // we can read the External Storage...           
    //Retrieve the primary External Storage:
    final File primaryExternalStorage = Environment.getExternalStorageDirectory();

    //Retrieve the External Storages' root directory:
    final String externalStorageRootDir;
    if ( (externalStorageRootDir = primaryExternalStorage.getParent()) == null ) {  // no parent...
        Log.i("SD Card Path", "External Storage: " + primaryExternalStorage + "\n");
    }
    else {
        final File externalStorageRoot = new File( externalStorageRootDir );
        final File[] files = externalStorageRoot.listFiles();

        for ( final File file : files ) {
            if ( file.isDirectory() && file.canRead() && (file.listFiles().length > 0) ) {  // it is a real directory (not a USB drive)...
                Log.i("SD Card Path", "External Storage: " + file.getAbsolutePath() + "\n");
            }
        }
    }
}

I could be wrong, but I understand the SD Card could be completely empty and that last condition (file.listFiles().length > 0) could return false. So I thought, instead of checking that length, I would add file.canWrite(). That worked as I expected on the phone I am currently testing on (Motorola Atrix MB860 - it's old, I know, but one of my requirements is make it compatible with versions starting from Gingerbread, API 9), but I am unsure whether or not that condition could return true to /mnt/asec/ or /mnt/obb on other phones , recent or not, since their both readable directories, thus also satisfying the first two conditions (and could even return true to (file.listFiles().length > 0) if it had something written on it (like a 50MB+ size file on /mnt/obb).

So, in short, what I need to know is whether an app will ever have write permission to these two locations or if only the system has such permission. If yes, what else can I check for in order to exclude them from the final path I wish to obtain: the external SD Card installed on the device?

Thank you in advance for any help!


Solution

This is the output on a Nexus 5

shell@hammerhead:/ $ ls -la /mnt/                                              
drwxr-xr-x root     system            1970-09-18 01:42 asec
drwx------ media_rw media_rw          1970-09-18 01:42 media_rw
drwxr-xr-x root     system            1970-09-18 01:42 obb

as you can see only root has write permission on the directory. So the only way an app can write that directory is to be executed as root



Answered By - Blackbelt