SAF(存储访问框架)是否解决了安卓4.4(奇巧巧克力)中SD卡写入问题?

10
在Android 4.4中,来自Play Store的应用只能写入其特定目录(例如:/storage/extSdCard/Android/data/com.example.myapp/),而且应用不能在micro SD卡上写入除此目录之外的其他文件。因此,我正在探索新的SAF API,以查看是否可以使用SAF在除应用程序特定目录之外的micro SD卡上进行写入。
我通过创建示例提供者和客户端应用程序来实现SAF。在我的提供者中,我尝试通过在queryRoots中实现以下代码来显示SD卡的整个内容:
    row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(new File("/storage/extSdCard")));
    row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_RECENTS | Root.FLAG_SUPPORTS_SEARCH);
我已经在我的客户端中创建了以下意图,并且我能够通过 SAF 的系统 UI 从我的提供程序中浏览整个 SD 卡的内容。
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_TITLE, "test.txt");
    startActivityForResult(intent, WRITE_REQUEST_CODE);
当我点击保存按钮时,出现了一个Toast错误“无法保存文档”。但是当我在系统UI中导航到我的提供程序的应用程序特定目录(/storage/extSdCard/Android/data/com.example.myprovider/)时,我可以保存该文档。同时,没有像Intent.CATEGORY_WRITABLE这样的意图,以便我只能获取可以编辑的文档。请帮我解决以下问题:
1.即使我们使用SAF,微型SD卡上的写入限制仍然保持不变。这是正确的吗? 2.是否有任何方法可以在微型SD卡的App特定目录之外创建、删除或修改已有文件? 3.谁决定普通用户文件(例如照片、视频、音乐、文档等)的FLAG_SUPPORTS_WRITE标志?
1个回答

4
当实现一个DocumentsProvider时,你只能扩展对已有访问权限的磁盘文件的访问权限。添加一个DocumentsProvider并不能给你任何新的权限,因此你可能不需要实现它。
通过使用你提到的ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT意图,你可以在SD卡上任何位置获得写入权限。系统内置了一个名为ExternalStorageProvider的提供程序,它可以访问所有SD卡,并且一旦用户通过这些意图确认,它将很乐意委派写入权限给你。
用户可能需要启用“设置>显示高级设备”来显示ExternalStorageProvider提供的SD卡。此外,如果你想限制用户与本地存储交互,则可以设置EXTRA_LOCAL_ONLY
至于(2),你可以使用ACTION_CREATE_DOCUMENT在包特定目录之外创建新文件,并可以使用任一意图选择现有文件。用户选择的文件可以使用DocumentsContract.deleteDocument()删除。
至于(3),当前内置于平台中的MediaDocumentsProvider未为照片、视频和音乐扩展FLAG_SUPPORTS_WRITE
希望这能帮到你。 :)

1
谢谢您的回复。有没有办法在不启动SAF系统UI的情况下获得对存储在micro SD卡中的文件的写入访问权限?像文件管理器这样的应用程序如何在不启动系统UI的情况下编辑或删除micro SD卡中的特定文件?由于系统UI再次像文件浏览器一样,因此文件管理器应用程序如何对位于micro SD卡中的特定文件执行写入/删除操作? - Sivaraj Velusamy
由于存储访问框架介入了对可能包含敏感用户数据的访问,因此在授予写入权限之前,它目前需要用户确认。您提到的文件管理器应用程序是否是OEM提供的?内置应用程序可能会使用其他权限直接访问设备。 - Jeff Sharkey
1
不,这不是OEM提供的应用程序。它是Play Store中提供的第三方应用程序。我仍然不清楚为什么只在microSD卡上实施此限制而不是在内部存储上实施。在内部存储器中也会有“可能敏感的用户数据”,我想知道为什么不将此限制应用于内部存储器。我们是否可以通过仅在micro SD卡上强制实施写入限制来获得任何优势? - Sivaraj Velusamy
自 API 1 开始,Android 设备上的主要共享存储已经对持有 WRITE_EXTERNAL_STORAGE 权限的应用程序可用,因此我们无法删除该功能。如果设备被配置为物理 SD 卡插槽是主要共享存储,则具有 WRITE_EXTERNAL_STORAGE 权限的应用程序可以在该媒体上的任何位置进行写入。(此设备配置因 OEM 而异。) - Jeff Sharkey
抱歉Jeff,我仍然没有得到我问题的答案。通过对主要和辅助存储设置不同的权限集,我们获得了什么优势?如果您说它在安全方面具有优势,那么这将使存储在主存储中的数据容易受到安全攻击,对吗?作为开发人员,我可以清楚地看到KitKat在此问题上存在一些不一致之处。您是否同意?如果不是,请详细解释。注意:众所周知,大多数OEM将内部嵌入式存储器作为主要存储器,将微型SD卡作为辅助存储器。 - Sivaraj Velusamy
似乎“不一致性”的原因是,遗留问题要求主要的ExternalStorage可以通过简单的清单权限直接访问。我阅读了抽象化二次/可移动存储接口背后的设计决策,以及如果今天从头开始设计,它可能会全部完成的方式,在这个世界上,Android已经(可以理解地)向第三方开发人员表示不信任,但不幸的是,远离了作为一个口袋*nix盒子的全部潜力,而恰好能够打电话;-) - Chris Stratton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接