SAF(存储访问框架)是不是解决了 Android 4.4(KitKat)中的 SD 卡 WRITE 问题?

Posted

技术标签:

【中文标题】SAF(存储访问框架)是不是解决了 Android 4.4(KitKat)中的 SD 卡 WRITE 问题?【英文标题】:Does SAF(Storage Access Framework) solve the SD card WRITE issue in Android 4.4 (KitKat)?SAF(存储访问框架)是否解决了 Android 4.4(KitKat)中的 SD 卡 WRITE 问题? 【发布时间】:2014-05-07 12:57:56 【问题描述】:

android 4.4 中,来自 Play 商店的应用程序只能写入它的应用程序特定目录(例如:/storage/extSdCar/Android/data/com.example.myapp/),并且不允许应用程序在此目录之外写入微型 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 错误“无法保存文档”。但是当我导航到应用程序特定目录(/storage/extSdCar/Android/data/com.example.myprovider/)时我在系统 UI 中的提供者,我能够保存文档。 也没有诸如 Intent.CATEGORY_WRITABLE 之类的意图,因此我只能获取可以编辑的文档。 请在以下几点上帮助我:

1.似乎即使我们使用 SAF,micro SD 卡的 WRITE 限制仍然保持不变。这是正确的吗?

2.有什么方法可以创建、删除或修改 micro SD 卡中我的应用特定目录之外的现有文件?

3.谁决定普通用户文件(如照片、视频、音乐、文档等)的 FLAG_SUPPORTS_WRITE 标志?

【问题讨论】:

【参考方案1】:

在实现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 的照片、视频和音乐。

希望这会有所帮助。 :)

【讨论】:

感谢您的回复。有没有办法在不启动 SAF 的系统 UI 的情况下获得对 micro SD 卡中文件的 WRITE 访问权限?文件管理器等应用程序如何在不启动系统 UI 的情况下编辑或删除 micro SD 卡中的特定文件?由于系统 UI 再次类似于文件的文件浏览器,文件管理器应用程序如何对位于 micro SD 卡中的特定文件执行 WRITE/DELETE 操作? 由于存储访问框架调解对潜在敏感用户数据的访问,因此目前需要用户确认才能授予写入访问权限。您提到的文件管理器应用程序是 OEM 提供的吗?内置应用可能会使用额外的权限直接访问设备。 没有。它不是 OEM 提供的应用程序。它是 Play 商店中提供的第 3 方应用程序。我仍然不清楚为什么这个限制只在 microSD 卡上实现,而不是在内部存储上。内部存储器中也会有“潜在敏感的用户数据”,我想知道为什么这个限制不适用于内部存储器。仅对 micro SD 卡施加 WRITE 限制是否有任何优势? 自 API 1 以来,Android 设备上的主要共享存储已可供持有 WRITE_EXTERNAL_STORAGE 的应用使用,因此我们无法删除该功能。如果设备配置为将物理 SD 卡插槽作为主要共享存储,则具有 WRITE_EXTERNAL_STORAGE 的应用程序可以在该媒体的任何位置写入。 (此设备配置因 OEM 而异。) 对不起杰夫。我仍然没有得到我的问题的答案。通过对主存储和辅助存储施加不同的权限集,我们可以获得什么优势?如果您说它在 SECURITY 方面具有优势,那么它会使存储在 PRIMARY 存储中的数据容易受到安全攻击,rgt?作为一个开发者,我可以清楚地看到KitKat在这个问题上的设计存在一些不一致的地方。你同意吗?如果不是,请详细说明。注意:众所周知,大多数 OEM 将内部嵌入式内存作为主存储,将 micro SD 作为辅助存储。

以上是关于SAF(存储访问框架)是不是解决了 Android 4.4(KitKat)中的 SD 卡 WRITE 问题?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SAF(存储访问框架)的 Android SD 卡写入权限

Android SAF(存储访问框架):从 TreeUri 获取特定文件 Uri

额外启用带有存储访问框架 (SAF) 的显示/隐藏 SD 卡

SAF(Storage Access Framework)使用攻略

在 Android 中从 File Api 迁移到 Storage Access Framework (SAF)

如何使用android存储访问框架正确覆盖文件内容