OP 询问如何授予对以下层次结构中文件的访问权限:appdir/files/subdir/myfile
.
这里提供的答案没有考虑子文件夹,所以我觉得还有改进的余地。
为了访问层次结构中的文件,消费者应该对路径中的每个文件夹具有执行权限,以便访问(读取、写入、执行)其下的文件。
对于 API >= 24
从 API 24 开始,Android限制访问(appdir
又名 /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