Android Marshmallow:新文件 (...) 授予权限被拒绝

Android Marshmallow: new File (...) gives permission denied

已编辑以反映进度。

如果这个问题已经得到解答,我深表歉意。

目前正在编写一个应用程序,其中的内容(在一个小的 zip 文件中)是从外部位置下载并存储在 /data/data/package_name_removed/files/ 中,以供稍后阅读。

我目前在该目录中有一个 zip 文件 "Test.zip"。

一个 try-catch 循环包含:

//where filename is Test.zip


Log.d("Target file is", sourceContext.getFilesDir() +"/"+ fileName);
File file = new File(sourceContext.getFilesDir() +"/"+ fileName);
ZipFile loadedFile = new ZipFile(file);  

//where sourceContext is passed into this object from the base Activity class

棉花糖似乎不起作用:

D/Target file is: /data/user/0/package_name_removed/files/Test.zip
W/package_name_removed: type=1400 audit(0.0:11699): avc: denied { open } for name="Test.zip" dev="mmcblk0p29" ino=57426 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0

这是一个Log.d的IOException getMessage;我认为这是从 new File() 语句生成的:

D/Log_title_omitted: /data/user/0/package_name_removed/files/Test.zip: open failed: EACCES (Permission denied)

我曾在 Lollipop 工作过;在我最近升级到 Marshmallow 之前,我也在为 pre-lollipop 调试它。在我解决这个问题之前,我认为我不能安全地继续,因为这意味着我的应用程序将不支持 6.0。

我已经设法将一个文本文件写入此目录,使用同一个应用程序没有任何问题,所以我不明白为什么尝试从该目录打开一个 zip 文件不起作用。

编辑:我也曾尝试将有问题的 zip 文件解压缩到它自己的目录,但无济于事:

//where file is now a json file "Test.json"
//located in .getFilesDir()/Test/
String loadedName = fileName.substring(0, fileName.length() - 5); //I need to reuse the string later.".json" is 5 char.
Log.d("Target is", sourceContext.getFilesDir() +"/"+ loadedName +"/" + fileName);
File file = new File(sourceContext.getFilesDir() + "/"+ loadedStoryName +"/" + fileName);

得到:

D/DOH: /data/user/0/package_name_removed/files/Test/Test.json: open failed: EACCES (Permission denied)
W/package_name_removed: type=1400 audit(0.0:22152): avc: denied { search } for name="Test" dev="mmcblk0p29" ino=57184 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:app_data_file:s0 tclass=dir permissive=0

我知道 Marshmallow 现在确实在强制执行 SELinux,我必须为这种可能发生的情况编写代码 - 但我一直无法弄清楚如何在代码中获得适当的权限。根据文档,我不应该在任何地方都需要 READ_EXTERNAL ,不需要请求对内部存储中应用程序自己的文件目录的权限。

有什么帮助吗?

注:包名省略,不重要。

来自 CommonsWare 用户:

"Rooting does not disable SELinux" -- no, but it does not mean that files that >you create through a root shell somehow get the same permission bits/ACLs/etc. as >do files you create through your application code. adb shell run-as might behave >better in this fashion.

是的,确实是因为我自己复制了文件,而不是让应用程序来做;全面拥有 r 权限不足以满足 SELinux,应用程序必须 "own" 文件是 "creates" 它的文件。

我还没有在外部写入目录上测试过这个,但是对于内部应用程序自己的目录是这样。