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).
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.
i have app to write image file to folder, but when i publish to play store, the app got rejected because sensitive permission MANAGE_EXTERNAL_STORAGE.
Rejected App
I already change the compilesdk 29, but then got rejected again because minimal sdk is 30.
Please teach me how to publish my app with permission to write file on android 11 to playstore.
Why your app got rejected
On Android 11, to use MANAGE_EXTERNAL_STORAGE permission your app need to fill one of these usecases:
File managers
Backup and restore apps
Anti-virus apps
Document management apps
On-device file search
Disk and file encryption
Device-to-device data migration
As you said, your app only need to write a image to the storage, so you don't need the full-control of the Android OS file-system, which is the purpose of the MANAGE_EXTERNAL_STORAGE permission.
So, to fix that, you need to use a more privacy-friendly API like Shared Storage API WRITE_EXTERNAL_STORAGE. This API allows you to write to external storage but this has some constraints which makes this API more privacy-friendly.
What should I use?
It depends, depends on what your app need to do. But, in a nutshell, we can say that:
The app need to write and read files frequently and need to share across the OS (Show in gallery, Shared Downloads folder, or something else that will be visible to the user)
Use MANAGE_EXTERNAL_STORAGE API which allows you to manage external storage as well, refer to MANAGE_EXTERNAL_STORAGE_API reference.
The app need to export some files to shared scope (Gallery, Downloads folder, anything that will be visible to the user) but not frequently
Use Shared Media API WRITE/READ_EXTERNAL_STORAGE which allows you to read and write to shared folders but with some constraints.
The app only needs to storage user preferences, like, to keep theme, user config or something related to app data.
You don't need permission, see app-specific files
Resources
Android Data Storage Overview
WRITE_EXTERNAL_STORAGE Documentation
MANAGE_EXTERNAL_STORAGE Documentation
As google have changed storage security in android 11 and WRITE_EXTERANL_STORAGE won't work. So can we save images on phone without permission of user?
If you want to write any file in the External storage, then you must have WRITE_EXTERNAL_STORAGE permission in your app below android 10.
In android 10, you can use requestLegacyExternalStorage=true in the application tag in your manifest. It will provide you the access to write file anywhere in External storage.
But it's a temporary solution as it'll be removed in the future. So the best solution is using SAF (Storage Access Framework) or Scoped Storeage.
SAF : It's an Android framework to secure user's files and help developers in managing files. However, different API levels require different approaches to manage and access files. Higher API level means more restrictions given to developers.
Scoped Storage : After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag. So you must use Scoped storage or SAF to write any file into the storage.
With scoped storage, you can't write any files in the External storage in android 11 even If you have Write storage permission. It will be ignored. You can write your files in app's internal storage or in the Media directory related to the file you're writing.
For example, if you are going to write an Image, then you must write it in DCIM directory, For Videos - Movies, For Document - Documents, and so on.
The best part about scoped storage is that you don't need write storage permission in Android 10 & above and you can still write the files in their respected directories. If you're writing the image & your custom directory is not created in the storage, then android will automatically create it while writing the file. You don't have to do file.mkdir().
But if you want to write any file in the out of your app's scope, then you have to clarify why you need to do that while releasing the apk on Playstore.
And only File operations related apps can get that approval because most of apps do not need to write files out of their scope in the External storage.
So if you are writing files in android 10 or above, then simply don't request write permission, request only read storage permission if you're using Scoped storage or SAF.
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
Many major games start out by asking for full file read permissions: Allow APPNAME to access photos, media, and files on your device
I'm assuming that is android.permission.READ_EXTERNAL_STORAGE
This seems dangerous to grant arbitrary apps to read any files on your phone. Why wouldn't the games use Internal Storage?
I'm not the only one with this question, there are unanswered posts like this with the same concern. An example game that request it.
It’s actually recommended in the Android docs:
If you are handling files that are not intended for other apps to use
(such as graphic textures or sound effects used by only your app), you
should use a private storage directory on the external storage by
calling getExternalFilesDir()
https://developer.android.com/guide/topics/data/data-storage.html#filesExternal