til
Tales of Android 11's External Storage
Scoped Storage is one of the major changes affecting developers in the latest and most shiny Android 11 release.
Not only is it meant to improve security for users, but also keep the external storage clean from apps flooding the directory structure.
Sadly it still has a few small problems...
Create Folders without permission
Let's have a look at the following code. Executed in an app targeting API 30 with no granted permissions, nor does it use the legacy storage flag. Executed on a Pixel 4XL with the latest Android 11 updates (8th of October 2020)
val test = File("/sdcard/someExistingFolder/someNonExistingFolder")
Log.e("TEST", "1) ${test.exists()}")
Log.e("TEST", "2) ${test.mkdirs()}")
Log.e("TEST", "3) ${test.exists()}")
Let's first look what an Android 10 devices will output
1) false // folder does not exist
2) false // folder was mpt created
3) false // folder does not exist
Seems about right. We have no permissions declared in the AndroidManifest.xml
nor did we grant permissions. So we shouldn't be able to create a folder.
So what will happen on Android 11?
1) false // folder does not exist
2) true // folder was created
3) true // folder does exist
You guess right. Bad things will happen :D.
Good news, this seems to be fixed in a future Android 11 release.
Fun fact: Doing the same experiment under the root of the SD-Card will behave as expected.
Let's look a bit further. What about files?
val subFile = File(test, "test.txt")
Log.e("TEST", "4) ${subFile.exists()}")
Log.e("TEST", "5) ${subFile.createNewFile()}")
Good news. This will behave as we expect on both Android 10 and Android 11
4) false // file does not exist
// no log for 5) -> Throws exception
Conclusion
Don't trust the circumstance that a directory can be created in a directory via .mkdirs()
to indicate having write access to a specific location.