I need to create files under myapp/files/subdir with global permission in my application. I do this because I use external applications to open some files Using this
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_WORLD_READABLE);
creates file only under files folder. Using
File dir=new File(Constants.TASK_DIRECTORY);
dir.mkdirs();
File file=new File(dir, FILENAME);
file.createNewFile(); FileOutputStream fos=new FileOutputStream(file);
creates files under subdirectories but with private permissions. I need to find a way to compose those both to create a file in a subdirectory to be world readable
I have been trying a lot of things but none helped me and this was the longest time unanswered question of mine
I know this is an old question, but here is the correct way
OP asked how to give access to a file in the following hierarchy:
appdir/files/subdir/myfile
.The answers provided here don't take subfolder into account, so I feel there's a room for improvement.
In order to access file in hierarchy, a consumer should have execute permission on each folder in a path in order to access (read, write, execute) files underneath it.
For API >= 24
Starting from API 24, Android restricts access to
appdir
(a.k.a /data/data/appdir):The
appdir
doesn't have world-execute permission, and therefore you can'tcd
into it:Bottom line: you can give world-readable permission to one of the files in your app's folder, but no other app (as long as they don't share the same Linux user ID) will be able to read them.
Not only that: attempt to pass a
file://
URI to external app will trigger a FileUriExposedException.For API < 24
The
appdir
folder has world-execute permission by default:Note that even the
appdir/files
folder has world-execute permission:But if you'll try to create a sub-folder (underneath
files
folder), using this code:it won't have world-execute permission:
Therefore, you have to explicitly give your newly created folder world-execute permission using File#setExecutable method (added in API 9):
And only then, as suggested by others, you can create your file and give it world-readable permission:
Doing that will allow any external application read your file:
If you are running it on a rooted device, change file permissions using:
Or try
File.setReadable()
,File.setWritable
while creating the file.One workaround I used in the past was to re-open the already existing file using openFileOutput in append mode, and pass in the world readable and/or world writable flags during that time. Then immediately close the file without writing to it.
I like the new methods added in API 9 better though.