I'm creating a file manager app for which I need the All files access permission and for which the target SDK has to be 30 and above as per play store requirements. Will having the MANAGE_EXTERNAL_STORAGE permission be enough for my use on all the android versions i.e work for android 10 devices and below or is it only applicable for android 11+?
If no,how do I gain such access for android 10 and below devices since the storage access framework won't be adequate for my purpose.
Short answer: READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE are enough for your use case in pre Android 11 devices.
Long answer: Prior to the introduction of Android 10, there was no such thing as scoped storage; that is READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE would be sufficient for a file manager since you wouldn't be restricted to reading your app's dirs. After Android 11, Google changed things and "scoped" your write access to your dirs and your dirs alone (unless you got MANAGE_EXTERNAL_STORAGE and got the user to consent to all files access in system prefs).
Related
I want to find an updated answer that works from android 5/6/7 to 13 with less possible permission. I know there are answers like Android saving file to external storage storage but those are very old.
You can understand accessing and storing files on android better from the google's official documentation here, mainly app-specific storage vs permission requirement, i.e. if you want to save file which are app specific, you won't need permission whether it being internal or external storage, but if you want to access locations which are not your app-specific, you will need permission for both internal and external storage.
Also, this behavior of permission requirement has been adopted after a particular API level, so you can start writing you code as per your targetSdk version and keep including options down to your minSdk versions and have a common method for permission for reusing it wherever is required.
The behaviour changes for Android 13 mention this:
If your app targets Android 13, you must request one or more new
permissions instead of the READ_EXTERNAL_STORAGE and
WRITE_EXTERNAL_STORAGE permissions.
(https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions)
The new permissions are:
Images and photos: READ_MEDIA_IMAGES
Videos: READ_MEDIA_VIDEO Audio
Audio files: READ_MEDIA_AUDIO
But how to handle this, if I e.g. need to read PDF files from an arbitrary folder? There's no permission like READ_MEDIA_DOCUMENT or something like that. What about other file types, which are not images, videos or audio? Can I still use READ_EXTERNAL_STORAGE permission for them?
I didn't find any information about this in the official documentation, but to be honest the documentation is focusing on media files only without any word about other file types (https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions).
I am also not sure about WRITE_EXTERNAL_STORAGE permission for other document types beside of videos, images and audio.
According to documentation (https://developer.android.com/training/data-storage/shared/media#storage-permission):
No permissions needed if you only access your own media files
On devices that run Android 10 or higher, you don't need any storage-related permissions to access and modify media files that your app owns, including files in the Media Store. Downloads collection. If you're developing a camera app, for example, you don't need to request storage-related permissions because your app owns the images that you're writing to the media store.
From android 10 you can not to ask permissions to get files from storage. Works perfectly with all kinds of files (pdf, excel...) on my app on android 13 without any permissions.
So you just need to ask READ_EXTERNAL_STORAGE permission for SDK, less than android 10.
But if you need special files (for example which was created by Instagram app but not stored in usual storage) you should ask for permission from your list.
Also look for types of Media storage:
https://developer.android.com/reference/android/provider/MediaStore
About WRITE_EXTERNAL_STORAGE - you don`t need it since sdkVersion=29
EDIT: Was rewriting my app and want to add something:
It depends on what your app needs to do, but I have removed all kinds of storage permissions (only WRITE_EXTERNAL_STORAGE left for SDK less than 29) from my app, and just use ACTION_OPEN_DOCUMENT, ACTION_OPEN_DOCUMENT_TREE to have access for all kind of files (but not for system folders, ACTION_OPEN_DOCUMENT_TREE also have no access for download folder).
I have been reading the documentation of the new way of saving files in android 11 and it is not clear to me ...
How could I save a file in /storage/emulated/0/?
My code only works on android 9 or lower (android 10 if I use preserveLegacyExternalStorage property in manifest, but on android 11 it doesn't work)
Android 11 introduces new approach to accessing storage, called Scoped Storage. Now for storing in any path you need new permission for Android 11: MANAGE_EXTERNAL_STORAGE (doc HERE, some rich FAQ aritcle in HERE)
This will allow you to get access to whole storage, all subfolders, not only folder dedicated for your app, but be aware that not every app with this permission declared in manifest will be published in Google Play. So you should respect new policy and keep your files only in context.getExternalFilesDir("subdirName"), for reading some common types (images, videos, docs) you can still use MediaStore API
I am using Samsung A30s phone for accessing phone storage files. My files location in device is /storage/emulated/0/MY_FILES/. I kept some files in MY_FIlES directory but my below code does
not show any containing files under this directory.
So how can I get all files belong to this MY_FIlES directory in phone storage?
File Directory = new File("/storage/emulated/0/MY_FIlES/");
File[] files = Directory.listFiles();
But files return null;
Note: I have a permission(READ_EXTERNAL_STORAGE) to access file.
One important thing, I updated my phone in latest API. But before update, I used this path, " /sdcard/MY_FIlES/ and it worked fine.
First, never hardcode paths for apps that you plan to distribute. For those, please use methods on Context, Environment, or StorageVolume (Android 11 only) to find the base directory to use.
For Android 10 and 11, you need to add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.
Note that in Android 11+, you will not be able to write to that directory, regardless of whether you have requested WRITE_EXTERNAL_STORAGE or not. Google would vastly prefer that you use the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT), so that users have more control over where files get placed on their devices or in their chosen cloud storage providers.
I would like to add something more to the #CommonsWare answer. As per the Android's storage update, they enforce scoped storage in the Android 11
version.
But to give developers additional time for testing, apps that target Android 10(API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows apps to temporarily opt-out of the changes associated with scoped storage, such as granting access to different directories and different types of media files. After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.
If your app opts out of scoped storage when running on Android 10 devices, it's recommended that you continue to set requestLegacyExternalStorage to true in your app's manifest file. That way, your app can continue to behave as expected on devices that run Android 10.
For more info on this, please check documentation
I've been learning about the new permission model for Android Marshmallow however I have some confusion about the storage permissions.
android.permission-group.STORAGE is a dangerous permission which we must ask the user for.
In my use case, I am just writing to my app's private directory in the external storage.
I've read that for KitKat, we do not need to request these permissions if I am just storing data related to my app only.
I can just use Context.getExternalFilesDirs()
But this is for API 19 / 20
My app targets 16 so I'm assuming the above does not apply to me.
my main question is that I use the Glide library for image caching and the Android download manager to download a file which will be stored in my app's external directory so how do I handle the external storage permission for these components and do I need to if i am just using my app's private directory?
To write data to external storage that are app-private you need to use the WRITE_EXTERNAL_STORAGE permission on anything below API 19. Add this to your manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
Since Android 4.4 (API 19) you don't need this but if your application supports lower APIs as you said, then you need the above. More on android storage options can be found here.