One of the areas where many people agree Android is superior to iOS is file management. On Android, you have the option to use the Files by Google app (preinstalled on GMS devices), the AOSP Files app, or one of many third-party file managers available on Google Play and other app repositories. If you choose to download a third-party file manager app, then all you have to do is grant a permission to start browsing the contents of your device’s external storage to your heart’s content.
However, there’s one folder on external storage that’s designed to be inaccessible to every app except the AOSP Files app. Even if a file manager app obtains “all files access”, it isn’t allowed to access /Android and its subdirectories /Android/obb and Android/data.
This is not a bug but rather an intentional restriction introduced in Android 11 as part of Google’s ongoing “Scoped Storage” efforts. Fortunately, file manager devs quickly discovered a loophole that let them access those restricted directories. Unfortunately, that loophole has been closed in Android 13, limiting the ability of third-party file managers to actually do their job. In this week’s edition of Android Dessert Bites, I’ll be sharing how this loophole worked and what Google did to close it.
The SAF loophole that file managers jumped on
Before I talk about the loophole, though, I want to explain why its closure is important to users. The /Android/data subdirectory is where many apps store files. Within this subdirectory you’ll find folders named after the package names of apps installed on your device. An app can read and write whatever files it wants in the folder matching its package name, and it doesn’t have to ask for permission to do so.
The Telegram app, for example, stores its cache under /Android/data/org.telegram.messenger/cache, so if there's a particular file you forgot to save but wanted to retrieve, you might be able to find it there. Google Podcasts stores downloaded podcasts to /Android/data/com.google.android.googlequicksearchbox/files/Podcasts/Downloads, so if you, say, downloaded a bunch of episodes of Android Bytes on your phone and wanted to transfer those to your PC, you'd need to navigate to that location to grab those files. /Android/data isn’t the only place where apps like Telegram and Google Podcasts can store files, but it offers more space to do so than internal storage and is just as convenient to access, which is why it's frequently used.
For many years, Google Play limited the size of APK files that devs could upload to be 100MB or less. Apps that ship with a lot of high quality assets (like games) could easily exceed this limit, so Google offered the ability to create APK expansion files that can be up to 2GB in size. These files are stored in /Android/obb with the .obb extension. It’s not uncommon to see Android gamers share .obb files in order to access some games early.
Though everyone’s setup is different, most readers have probably accessed a file or folder under /Android at one point in the past. When friend of the blog (and one-time Android Bytes guest) Braden Farmer posted on Reddit about Android 11’s file manager restriction, the post attracted over 100 comments from users expressing frustration with the change. It was noted quite quickly, however, that many file managers had rolled out updates enabling access to /Android/data and /Android/obb. All the user had to do was tap “use this folder” and then “allow” when requested, and the file manager would have access to those directories.
What file managers like MiXplorer are doing is using the Storage Access Framework (SAF) to request access to a particular directory’s contents. SAF was introduced all the way back in Android 4.4, while the ability to use SAF to prompt the user to choose a directory for an app to access was added in Android 5.0. This capability, thus, is quite old, so it’s not as if Google didn’t consider that apps would try to use SAF to request access to directories that are supposed to be restricted. In fact, Google explicitly blocked SAF directory access to /Android, but this implementation had a flaw: it didn’t block SAF directory access to subdirectories under /Android. In other words, while file managers couldn’t just use SAF to ask for access to all of /Android, they could use it to ask for access to /Android/data and /Android/obb, circumventing Android’s restrictions almost entirely.
The method behind this loophole is pretty simple to find online. This StackOverflow post sums it up quite nicely, though I first stumbled upon the method after reading this issue on the Amaze File Manager’s GitHub. One of the developers behind Amaze File Manager, TranceLove, published a proof of concept app that could access restricted directories in Android 11. Based on my understanding, the way it works is that, when constructing the intent to launch SAF, apps can set the initial location of the document chooser to be /Android/data or /Android/obb. This is intended functionality of SAF, but Google seemingly didn’t consider this when implementing Android’s restrictions on those directories. Oops.
Half a year after someone reported the existence of the loophole to Google, though, an employee said the issue will be fixed in a future Android release. That “future Android release” is now here in the form of Android 13, and I can confirm the loophole is closed through my own testing and code examination. As you can see in the video below, the loophole works on Android 12L but not on Android 13:
https://youtu.be/Mc4KHoaBMeM
This is because Google updated the shouldBlockFromTree method in ExternalStorageProvider that I linked to before. The updated method adds a new condition to check if the directory that’s being launched matches one of the directories that should be hidden from apps. If there’s a match, then a flag will be applied to the directory that blocks it from being selected through SAF.
Because of this change, file managers will need to find another way to access files under /Android. One solution might be to use the Shizuku library to run as shell, since the shell user still has access to /Android. Shizuku isn't a perfect solution, though, because the service doesn't persist across reboots and on some devices, it's killed when the device switches between WiFi and mobile data. Plus, Shizuku itself is a bit risky to rely on, because it's something I can see Google restricting in a future release.
While waiting for file manager devs to implement a workaround, users can access /Android through one of the officially supported ways: the AOSP Files app (if you can’t find it, this app acts as a shortcut), MTP (ie. from your PC), or ADB shell (with or without a PC). Although I haven't tested this myself, I suspect that file managers that have already been given access to subdirectories under /Android using the SAF loophole will retain that access when upgrading to Android 13, so one option would be to set up a file manager before upgrading.
While it’s understandable that Google is closing an obvious loophole to enforce behavior introduced in an earlier platform release, I still don’t agree with disallowing even file managers from having access to /Android. As I just mentioned, users can already access all content under /Android through the preinstalled Files app on most phones or from a PC using MTP or ADB. Thus, files saved to /Android are only hidden from other apps, not the user. I understand that’s the goal, but if the user wants to grant access to a file manager app so they themselves can access content that’s not intended to be hidden from them anyway, then I think they should be able to. Google Play already audits which apps can declare the MANAGE_EXTERNAL_STORAGE permission (the permission behind “all files access”), so why can’t those apps be trusted to actually access all files as the permission implies?
Thanks for reading this week’s edition of Android Dessert Bites. If you use a file manager app that’s not from Google or an OEM, then I recommend sending the developer a link to this article so they’re aware of this upcoming change in Android 13. Hopefully another workaround will be found because I’d like to continue using MiXplorer without restrictions.
By the way, if you want to know why I’ve been saying “external” storage in this article when the screenshots I’ve posted clearly say “internal” storage and the files themselves are actually stored on the device’s physical internal storage chip, there’s a reason for that…but an explanation here would make this already lengthy article go on for even longer. This article I wrote back in 2017 explains the reasoning, but it’s a bit outdated as Google has since deprecated the feature I mentioned and brought back the old implementation with some improvements. I might explore this topic in a future edition.
This article was updated at 1:05 PM PT to add information about the limitations with the Shizuku approach and the possibility that access to subdirectories under /Android will persist when upgrading from an older release to Android 13.