Как создать файл с правами на чтение для всех в подкаталоге каталога файлов - PullRequest
16 голосов
/ 25 октября 2011

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

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

файл создается только в папке files.Использование

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

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

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

Ответы [ 4 ]

20 голосов
/ 12 июля 2013

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

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);
}
9 голосов
/ 09 ноября 2016

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

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


Для API> = 24

Начиная с API 24, Android ограничивает доступ до appdir (a.k.a / 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) не будет умеет их читать.

Мало того: попытка передать URI file:// во внешнее приложение вызовет FileUriExposedException .


Для API <24 </strong>

Папка appdir имеет разрешение world-execute по умолчанию:

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

Обратите внимание, что даже папка appdir/files имеет разрешение world-execute :

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

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

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

не будет иметь разрешения world-execute :

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
6 голосов
/ 29 июля 2012

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

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

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

0 голосов
/ 12 февраля 2015

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

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

...