使用存储访问框架打开文件

Android 4.4(API 级别 19)引入了存储访问框架 (SAF)。SAF 允许用户浏览和打开所有首选文档存储提供程序中的文档、图片及其他文件。标准且易于使用的 UI 允许用户以跨应用和提供程序的方式一致地浏览文件和访问近期文件。

云存储或本地存储服务可以通过实现封装其服务的 DocumentsProvider 参与此生态系统。需要访问提供程序文档的客户端应用只需几行代码即可与 SAF 集成。

SAF 包括以下内容

  • 文档提供程序:一种内容提供程序,允许存储服务(例如 Google Drive)显示其管理的文件。文档提供程序是 DocumentsProvider 类的一个子类。文档提供程序 schema 基于传统文件层次结构,但文档提供程序如何物理存储数据取决于您。Android 平台包含多个内置文档提供程序,例如下载、图片和视频。
  • 客户端应用:一种自定义应用,调用 ACTION_CREATE_DOCUMENTACTION_OPEN_DOCUMENTACTION_OPEN_DOCUMENT_TREE intent 操作并接收文档提供程序返回的文件。
  • 选择器:一种系统 UI,允许用户从满足客户端应用搜索条件的所有文档提供程序访问文档。

SAF 提供以下功能

  • 允许用户浏览所有文档提供程序中的内容,而不仅仅是一个应用。
  • 使您的应用能够长期持久地访问文档提供程序拥有的文档。通过此访问权限,用户可以在提供程序上添加、编辑、保存和删除文件。
  • 支持多个用户帐号和瞬时根目录(例如 USB 存储提供程序),这些根目录仅在插入驱动器时显示。

概览

SAF 围绕着作为 DocumentsProvider 类子类的内容提供程序展开。在文档提供程序中,数据结构采用传统文件层次结构

图 1. 文档提供程序数据模型。根目录指向单个文档,然后开始树的扇出。

请注意以下事项

  • 每个文档提供程序会报告一个或多个根目录,这些根目录是浏览文档树的起始点。每个根目录都有唯一的 COLUMN_ROOT_ID,并指向一个文档(目录),该文档表示该根目录下的内容。根目录在设计上是动态的,以支持多种用例,例如多个帐号、瞬时 USB 存储设备或用户登录/注销。
  • 每个根目录下都有一个文档。该文档指向 1 到 N 个文档,每个文档又可以指向 1 到 N 个文档。
  • 每个存储后端通过唯一的 COLUMN_DOCUMENT_ID 引用单个文件和目录。文档 ID 是唯一的,一旦发出就不会更改,因为它们用于跨设备重新启动的持久性 URI 授权。
  • 文档可以是具有特定 MIME 类型的可打开文件,也可以是包含附加文档的目录,其 MIME 类型为 MIME_TYPE_DIR
  • 每个文档可以具有不同的功能,如 COLUMN_FLAGS 所述。例如,FLAG_SUPPORTS_WRITEFLAG_SUPPORTS_DELETEFLAG_SUPPORTS_THUMBNAIL。同一个 COLUMN_DOCUMENT_ID 可以包含在多个目录中。

控制流程

文档提供程序数据模型基于传统文件层次结构。但是,您可以根据需要物理存储数据,只要您可以使用 DocumentsProvider API 访问它即可。例如,您可以使用基于标签的云存储来存储数据。

图 2 显示了照片应用如何使用 SAF 访问存储的数据

图 2. 存储访问框架流程图。

请注意以下事项

  • 在 SAF 中,提供程序和客户端不会直接交互。客户端请求与文件交互的权限,即读取、编辑、创建或删除文件的权限。
  • 交互始于应用(在此示例中为照片应用)发出 ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT intent。该 intent 可以包含过滤器来进一步细化条件,例如“给我所有 MIME 类型为‘image’的可打开文件”。
  • intent 发出后,系统选择器会转到每个注册的提供程序,并向用户显示匹配的内容根目录。
  • 选择器为用户提供了访问文档的标准界面,即使底层文档提供程序差异很大也是如此。例如,图 2 显示了 Google Drive 提供程序、USB 提供程序和云提供程序。

在图 3 中,用户正在从为搜索图片而打开的选择器中选择“下载”文件夹。选择器还会显示客户端应用可用的所有根目录。

Folder selection in system picker.
图 3. 选择器显示已选择“下载”文件夹作为搜索位置。

用户选择“下载”文件夹后,将显示图片。图 4 显示了此过程的结果。用户现在可以按照提供程序和客户端应用支持的方式与图片进行交互。

图 4. “下载”文件夹中存储的图片,在系统选择器中查看。

编写客户端应用

在 Android 4.3 及更低版本上,如果想让应用从另一个应用检索文件,则必须调用 ACTION_PICKACTION_GET_CONTENT 等 intent。然后,用户会选择一个应用来选取文件。所选应用必须提供用户界面,供用户浏览可用文件并从中选取。

在 Android 4.4(API 级别 19)及更高版本上,您还可以选择使用 ACTION_OPEN_DOCUMENT intent,它会显示由系统控制的选择器 UI,供用户浏览其他应用提供的所有文件。通过此单一 UI,用户可以从任何受支持的应用中选取文件。

在 Android 5.0(API 级别 21)及更高版本上,您还可以使用 ACTION_OPEN_DOCUMENT_TREE intent,它允许用户选择一个目录供客户端应用访问。

注意:ACTION_OPEN_DOCUMENT 不能替代 ACTION_GET_CONTENT。您使用哪一个取决于您的应用需求

  • 如果您想让应用读取或导入数据,请使用 ACTION_GET_CONTENT。通过此方法,应用会导入数据副本,例如图片文件。
  • 如果您想让应用长期持久地访问文档提供程序拥有的文档,请使用 ACTION_OPEN_DOCUMENT。例如,照片编辑应用允许用户编辑存储在文档提供程序中的图片。

如需详细了解如何使用系统选择器 UI 支持浏览文件和目录,请参阅关于访问文档及其他文件的指南。

其他资源

如需详细了解文档提供程序,请利用以下资源

示例

视频