In Android 29, I want to be able to share large files between multiple Android users. Is it possible to make a shared directory that users can access? And can that directory be made browse-able by applications that the users have installed?
Or perhaps have one user with the original directory and files, and other users have a mounted/symlinked directory?
It is important for my implementation that an installed app can access this directory.
I have been navigating the Android filesystem and trying to get my head around:
/mnt/user/0, /storage/emulated/0, and /data/media/0/ but I cannot see a way to make a symlink in another user's home directory to a folder within these directories.
The directory that you are looking for is actually /storage/emulated/0 in your case. I mean the only directory that could be used/accessible by all other applications is the external storage.
However, from Android Q (targetSDKVersion 29), the external storage permission has quite a few changes.
I would recommend looking into the documentation of getExternalStoragePublicDirectory if you are on an Android version that is less than Android Q.
For Android Q and greater, I would recommend looking into the documentation of getExternalFileDir.
Also, there is a great article from #CommonsWare regarding this. Please have a look here in his blog post. I am quoting from his blog here.
For Android Q, you can 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.
Technically, you only need this once you update your
targetSdkVersion to 29. Apps with lower targetSdkVersion values
default to opting into legacy storage and would need
android:requestLegacyExternalStorage="false" to opt-out.
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.
In my existing app(Android 10) I have a folder under /storage/emulated/0/<my_folder>. After looking to various sources on Google Developers I don't think that it's possible to longer access the /storage/emulated/0/<my_folder> directory under Android 11, because of the changes made in storage access permission.
Of course I can create these folder under Android 11 inside the so called "scoped storage" as mentioned by Google. But if a user updates the app from 10 to 11, how can I access the old folder for copying the files inside to the new folder inside "scoped storage" when I am on Android 11?
Or is there some other way to migrate this folder under /storage/emulated/0/<my_folder> safely?
With intent ACTION_OPEN_DOCUMENT_TREE you can let the user choose your <myfolder>.
For new installations use /storage/emulated/0/Documents/<my_folder> instead.
There is no reason to copy files or folders.
You can reclaim the permissions for your old app folder via SimpleStorage:
storageHelper.requestStorageAccess(
expectedStorageType = StorageType.EXTERNAL,
expectedBasePath = "<my_folder>"
)
Ever since Scoped storage introduction, you can no longer create your folders under root directory without special permission, I.E manage external storage, but i doubt play store will allow that access to your app if the core functionality isnt affected,
You can do one of the following
store your required files in respected folders [Recommended] (Documents for docs, DCIM for images/videos, Music for audio files and so on)
Require Permission to folder by open document tree intent (Last resort)
We developed two android applications, one that creates a folder with multiple files (.xml /.txt /.db) and another one that needs to access these files. Both application needs read and write authorizations to these files.
Before Android 11, we use to store these files in the app-specific external storage (Android/data/com...), the other app was able to read/write those files.
With Android 11 and enforcement of scoped storage, secondary app cannot access the primary app folder.
Is there any way of creating a "public" directory that store all shareable files ?
While searching, i found about the FileProvider component but i don't know if it will work despite scoped storage.
I'm aware of the new authorization MANAGE_EXTERNAL_STORAGE, but if i use this i'm afraid that playstore might reject my apps.
Despite all my researches, i didn't find a solution to my problem.
Thank you for your help.
On Android 11:
Make your own directory in one of the public directories like Documents, DCIM, Pictures, Alarms and so on, and put your files there.
I understand in current SDKs that external storage files for my app are created in the /data/data/"package" folder. However, I am integrating with another app that I have no control over and it reads from the "Internal Storage" (Which is the PRIMARY EXTERNAL STORAGE? AARG! :) folder on my Android 10 (R) phone. I've searched for 2 days now how to create a simple .csv file in the folder labeled "Internal Storage" (My Files->Internal Storage) and simply can't find a solution to getting the path to that location.
I'm setting my Android Studio to minSdkVersion at 16, complileSdkVersion to 28, so at least I can use some of the earlier methods for file management. I expect my app to run on phones/tablets at least 3 years old and newer. There is NO UI necessary (picker-as new doc suggests to use) to select a folder to save the file, just simply create a file there is all I need. I'm an old Java programmer but new to Android. Most posts point to deprecated functions we lose in >28 SDKs.
I understand in current SDKs that external storage files for my app are created in the /data/data/"package" folder.
No, that is internal storage.
However, I am integrating with another app that I have no control over and it reads from the "Internal Storage" (Which is the PRIMARY EXTERNAL STORAGE? AARG! :) folder on my Android 10 (R) phone
That app will need to be updated soon.
I've searched for 2 days now how to create a simple .csv file in the folder labeled "Internal Storage" (My Files->Internal Storage) and simply can't find a solution to getting the path to that location
For Android 10 and below, you can use Environment.getExternalStorageDirectory() for the root of external storage. Note that for Android 10 itself, you will need to add android:requestLegacyExternalStorage="true" in the <application> element.
On Android 11+, you can no longer write to the root of external storage using filesystem APIs, unless you hold MANAGE_EXTERNAL_STORAGE. That permission will require justification for use, if you plan on distributing your app via the Play Store (and perhaps elsewhere).
There is NO UI necessary (picker-as new doc suggests to use) to select a folder to save the file
The user may disagree with you. Google definitely disagrees with you. On Android 11, if you do not want your app to be banned from the Play Store, you will need to use ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE and allow the user to decide where the user's file goes on the user's device.
Most posts point to deprecated functions we lose in >28 SDKs.
"Deprecated" in Android does not always mean "lose". It always means "there is another option that Google wishes for you to consider. So, for example, Environment.getExternalStorageDirectory() still exists, even in Android 11. It is just less useful, and Google would prefer that you use methods on StorageVolume instead.
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