如何在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); 

在子目录下创建文件但具有私有权限。 我需要find一种方法来组合这两者,以在子目录中创建一个世界可读的文件

我一直在尝试很多东西,但没有人帮助我,这是我未解决的最长时间问题

Solutions Collecting From Web of "如何在files目录的子目录下创建具有世界可读权限的文件"

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

 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 (aka / data / data / appdir):

为了提高私人文件的安全性,针对Android 7.0或更高版本的应用的私人目录限制了访问(0700)。 此设置可防止私有文件的元数据泄漏,例如其大小或存在。

appdir没有世界执行权限,因此你无法进入它:

 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中添加)明确地为新创建的文件夹提供世界执行权限:

 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 

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

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

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

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

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