Is there a simple API call that would tell me if an app running on Android 10 or later must use Scoped Storage access, that is, if the normal file access, a.k.a. "Legacy External Storage" is disabled? Note that even if the app in AndroidManifest.xml, section declared:
android:requestLegacyExternalStorage="true"
the file access may still be denied due to Google policy changes in the future, so testing this value is useless. The only way I found is to test if the external storage root directory is readable, but for that, the app must first ask for Storage permission, which is useless for anything else, if legacy storage is disabled.
public static boolean mustUseScopedStorage() {
// Impractical must first ask for useless Storage permission...
File exSD = Environment.getExternalStorageDirectory();
return !exSD.canRead(); // this test works only if Storage permission was granted.
}
I think I have once seen a new API to detect this, but cannot find that article anymore...
You can use these two methods from android.os.Environment
:
isExternalStorageLegacy(File path)
Returns whether the shared/external storage media at the given path is a legacy view that includes files not owned by the app.
isExternalStorageLegacy()
Returns whether the primary shared/external storage media is a legacy view that includes files not owned by the app.
This value may be different from the value requested by
requestLegacyExternalStorage
in the app's manifest, since an app may inherit its legacy state based on when it was first installed.Non-legacy apps can continue to discover and read media belonging to other apps via
MediaStore
.
In case you discover that you have access to legacy storage, personally I think it's better to just migrate data over to scoped storage and use it instead since legacy storage may stop working without warning.