如何在files目录的子目录下创建具有世界可读权限的文件

时间:2011-10-25 08:58:04

标签: android storage file-permissions java-io android-file

我需要在我的应用程序中使用全局权限在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 个答案:

答案 0 :(得分:20)

我知道这是一个老问题,但这是正确的方法

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

答案 1 :(得分:9)

OP询问如何授予以下层次结构中文件的访问权限:appdir/files/subdir/myfile 这里提供的答案不考虑子文件夹,所以我觉得还有改进的余地。

为了访问层次结构中的文件,消费者应该对路径中的每个文件夹具有执行权限,以便访问(读取,写入,执行)其下的文件。

对于API> = 24

从API 24,Android restricts accessappdir(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用户ID)能够阅读它们。

不仅如此:尝试将file:// URI传递给外部应用也会触发FileUriExposedException

对于API< 24

默认情况下,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 $ 

因此,您必须使用File#setExecutable方法(在API 9中添加)明确地为新创建的文件夹 world-execute 提供权限:

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

答案 2 :(得分:6)

如果您在root设备上运行它,请使用以下命令更改文件权限:

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

或者在创建文件时尝试File.setReadable()File.setWritable

答案 3 :(得分:0)

我过去使用的一种解决方法是在追加模式下使用openFileOutput重新打开现有文件,并在此期间传入世界可读和/或世界可写标志。然后立即关闭文件而不写入文件。

我更喜欢API 9中添加的新方法。