android存储访问框架Storage Access Framework

在了解storage access framework 之前,我们先来看看android4.4中的一个特性。如果我们希望能选择android手机中的一张图片,通常都是发送一个Intent给相应的程序,一般这个程序是系统自带的图库应用(如果你的手机中有两个图库类的app 很可能会叫你选择一个),这个Intent一般是这样写的:

Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT  

intent.addCategory(Intent.CATEGORY_OPENABLE);  

intent.setType("image/jpeg");  

使用这样的一种方法来选择图片在android4.4中会直接弹出一个很漂亮的界面,有点像一个文件管理器,其实他比文件管理器更强大,他是一个内容提供器,可以按照目录一层一层的选择文件,也可以按照文件种类选择文件,比如图片、视频、音频等,还可以打开一个应用程序选择文件,界面如下:

 -- 

 -- 

其实这是一个叫做documentsui的内置程序,因为它的manifest 没有带LAUNCHER的activity所以不会显示在桌面上。

下面是正文:

Storage Access Framework

Android4.4中引入了Storage Access Framework存储访问框架,简称(SAF)。SAF为用户浏览手机中存储的内容提供了方便,这些内容不仅包括文档、图片,视频、音频、下载,而且还包括所有由特定ContentProvider(须具有约定的API)提供的内容。不管这些内容来自于哪里,不管是哪个应用调用浏览系统文件内容的命令,系统都会用一个统一的界面让你去浏览。

这种能力姑且叫做一种生态系统,云存储以及本地存储都可以通过实现DocumentsProvider来参与到这个系统中。而客户端app要使用SAF提供的服务只需几行代码即可。

SAF框架包括以下内容:

(1)Document provider文件内容提供方

这是一个特殊的content provider(内容提供方),他让一个存储服务(比如Google Drive)可以对外展示自己所管理的文件。一个Document provider其实就是实现了DocumentsProvider的子类。document-provider的schema 和传统的文件存径格式一致,但是至于你的内容是怎么存储的完全取决于你自己,android系统中已经内置了几个这样的Document provider,比如关于下载、图片以及视频的Document provider。(注意这里的红色DocumentsProvider是一个类,而分开写的Document provider只是一种描述,因为翻译出来可能会让人忘了他的特殊身份。)

(2)客户端app

一个触发ACTION_OPEN_DOCUMENT或者ACTION_CREATE_DOCUMENTintent的客户端软件。通过触发ACTION_OPEN_DOCUMENT或者ACTION_CREATE_DOCUMENT客户端可以接收来自于Document provider的内容。

(3)选择器Picker

选择器其实就是一个类似于文件管理器的界面,而且是系统级别的界面,他提供了访问满足客户端过滤条件的所有Document provider内容的通道。说的具体点选择器就是文章开头提到的documentsui程序。

SAF的一些特性:

用户可以浏览所有document provider提供的内容,不光是一个app。

提供了长期、持续的访问document provider中文件的能力以及数据的持久化,用户可以实现添加、删除、编辑、保存document provider所维护的内容。

支持多用户以及临时性的内容服务,比如USB storage providers只有当驱动安装成功才会出现。

概要

SAF的核心是实现了DocumentsProvider的子类,即内容提供者(document provider)。document provider中数据是以传统的文件目录树组织起来的:

流程图

虽说document provider中数据是以传统的文件目录树组织起来的,但是那只是对外表现的形式,至于你的数据在内部究竟是怎么样(甚至完全杂乱无章),完全取决于你自己,只要你对外的接口能够通过DocumentsProvider的api访问就可以。

下面的流程图展示了一个photo应用使用SAF可能的结构:

从上图可以看出选择器Picker(System UI)是一个链接调用者与内容提供者的桥梁。它提供了一个UI同时也告诉了调用者可以选择哪些内容提供者,比如这里的DriveDocProvider、 UsbDocProvider 、CloundDocProvider。

当客户端app与Document provider之间的交互是在触发了ACTION_OPEN_DOCUMENT或者ACTION_CREATE_DOCUMENT intent之后,intent还可以进一步设置过滤条件:比如限制MIME type为’image’。

当intent触发之后选择器去寻找每一个注册了的provider,并将provider的符合条件的根目录显示出来。

选择器(即documentsui)为访问不同形式、不同来源的文件提供了统一的界面,你可以看到我的文件形式可以是图片、视频,文件的内容可以是来自本地或者是Google Drive的云服务。

下图显示了用户在选择图片的时候点中了Google Drive的情况。

客户端是如何调用的

在android4.3时代,如果你想从另外一个app中选择一个文件,比如从图库中选择一张图片文件,你必须触发一个intent比如ACTION_PICK或者ACTION_GET_CONTENT。然后在候选的app中选择一个app,从中获得你想要的文件,最关键的是被选择的app中要具有能为你提供文件的功能,如果一个不负责任的第三方开发者注册了一个恰恰符合你需求的intent,但是没有实现返回文件的功能,那么就会出现意想不到的错误。

在4.4中,你多了一个选择方式,你可以发送ACTION_OPEN_DOCUMENTintent来调用系统的documentsui来选择任何文件,不需要再依赖于其他的app了。

但是并不是说ACTION_GET_CONTENT就完全没有用了,如果你只是打开读取一个文件,ACTION_GET_CONTENT还是可以的,如果你是要有写入编辑的需求,那就用ACTION_OPEN_DOCUMENT。

注: 实际上在4.4系统中ACTION_GET_CONTENT启动的还是documentsui。

下面演示如何用ACTION_OPEN_DOCUMENT选择一张图片:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Tag:

Freenovo 发表于2014-11-01 00:09:00 | 编辑 | 分享 0

引用地址:

原文地址:https://www.cnblogs.com/freenovo/p/4469768.html