Как создать файл с доступным для чтения разрешением в каталоге подкаталога файлов

Мне нужно создать файлы в myapp / files / subdir с глобальным разрешением в моем приложении. Я делаю это, потому что я использую внешние приложения для открытия некоторых файлов.

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_WORLD_READABLE); 

Создает файл только в папке с файлами. С помощью

  File dir=new File(Constants.TASK_DIRECTORY); dir.mkdirs(); File file=new File(dir, FILENAME); file.createNewFile(); FileOutputStream fos=new FileOutputStream(file); 

Создает файлы под подкаталогами, но с частными правами. Мне нужно найти способ скомпоновать эти файлы для создания файла в подкаталоге, чтобы он был доступен для чтения в мире

Я пытался много чего, но никто не помог мне, и это был самый длинный вопрос без ответа

Solutions Collecting From Web of "Как создать файл с доступным для чтения разрешением в каталоге подкаталога файлов"

Я знаю, что это старый вопрос, но вот правильный путь

 public void makeFileWorldReadable(String path) { File f = new File(path); if(!f.exists()) // Create the file if it does not exist. f.createNewFile(); f.setReadable(true, false); } 

Если вы используете его на корневом устройстве, измените права доступа к файлам, используя:

 Runtime.getRuntime().exec("chmod 777 " + PATH + fileName); 

Или попробуйте File.setReadable() , File.setWritable при создании файла.

OP спросил, как предоставить доступ к файлу в следующей иерархии: appdir/files/subdir/myfile .
Ответы, представленные здесь, не учитывают вложенную папку, поэтому я чувствую, что есть место для улучшения.

Чтобы получить доступ к файлу в иерархии, потребитель должен иметь разрешение на выполнение в каждой папке пути, чтобы получать доступ (читать, записывать и выполнять) файлы под ним.


Для API> = 24

Начиная с API 24, Android ограничивает доступ к appdir (aka / data / data / appdir):

В целях повышения безопасности личных файлов частный каталог приложений, ориентированных на Android 7.0 или выше, имеет ограниченный доступ (0700). Этот параметр предотвращает утечку метаданных личных файлов, таких как их размер или существование.

Приложение appdir не имеет разрешения на выполнение во всем мире, и поэтому вы не можете cd в него:

 angler:/ $ cd /data/data angler:/data/data $ cd com.myapp /system/bin/sh: cd: /data/data/com.myapp: Permission denied 

Итог: вы можете разрешить мир для одного из файлов в папке вашего приложения, но никакое другое приложение (пока они не используют один и тот же идентификатор пользователя Linux) сможет их прочитать.

Не только это: попытка передать file:// URI для внешнего приложения вызовет исключение FileUriExposedException .


Для API <24

По appdir папка appdir имеет разрешение на выполнение во всем мире :

 shell:/ $ cd /data/data shell:/data/data $ cd com.myapp shell:/data/data/com.myapp $ 

Обратите внимание, что даже appdir/files имеет разрешение на выполнение во всем мире :

 shell:/data/data/com.myapp $ cd files shell:/data/data/com.myapp/files $ 

Но если вы попытаетесь создать подпапку (под папкой files ), используя этот код:

 File subdir = new File(context.getFilesDir(), "subfolder"); subdir.mkdir(); 

У него не будет разрешения на выполнение во всем мире :

 shell:/ $ cd /data/data/com.myapp/files shell:/data/data/com.myapp/files $ cd subfolder /system/bin/sh: cd: /data/data/com.myapp/files/subfolder: Permission denied shell:/data/data/com.myapp/files $ run-as com.myapp shell:/data/data/com.myapp $ cd files shell:/data/data/com.myapp/files $ ls -l total 72 drwx------ 3 u0_a226 u0_a226 4096 2016-11-06 11:49 subfolder shell:/data/data/com.myapp/files $ 

Таким образом, вы должны явно предоставить вновь созданную папку world-execute с помощью метода File # setExecutable (добавленного в API 9):

 subdir.setExecutable(true, false); 

И только тогда, как это было предложено другими, вы можете создать свой файл и предоставить ему доступное для чтения разрешение:

 File file = new File(subdir, "newfile"); if(!file.exists()) { file.createNewFile(); file.setReadable(true, false); } 

Это позволит любому внешнему приложению читать ваш файл:

 shell:/ $ cd /data/data/com.myapp/files shell:/data/data/com.myapp/files $ cd subfolder shell:/data/data/com.myapp/files/subfolder $ cat newfile > /sdcard/1 shell:/data/data/com.myapp/files/subfolder $ cd /sdcard shell:/sdcard $ ls 1 1 

Одним из обходных решений, которые я использовал в прошлом, было повторное открытие уже существующего файла с использованием openFileOutput в режиме добавления и передача в мире читаемых и / или всемирно допустимых флагов за это время. Затем немедленно закройте файл, не записывая его.

Тем не менее, мне нравятся новые методы, добавленные в API 9.