как создать файл с разрешением world readable в подкаталоге каталога files

мне нужно создать файлы под 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 ответов


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

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);
}

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

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


для API >= 24

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

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

на appdir не имеет разрешения world-execute, и поэтому вы не можете 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

на имеет мир-выполнить разрешение по умолчанию:

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

обратите внимание, что даже и мир-выполнить разрешение:

shell:/data/data/com.myapp $ cd files
shell:/data/data/com.myapp/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 $ 

таким образом, вы должны явно дать вновь созданную папку мир-выполнить разрешение с помощью файл#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

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

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

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


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

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