The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.

Consuming Documents

Android has long offered the ability for an app to pick some file or stream from another app and consume it. However, the original options were designed around an app loading content from another app. Even though our code would be requesting content based on abstractions like MIME types, the implementation and user experience would be based on the traditional “pick an app to fulfill this request” chooser.

Google, given its clear interest in cross-cutting storage engines like Google Drive, wanted something better. In Android 4.4, they added the Storage Access Framework (SAF) to provide a better user experience, with only modest changes to client code. With Android’s increasing reliance upon content and document providers for cross-app content sharing, understanding the Storage Access Framework is fairly important for modern app development.

In this chapter, we will examine what it takes to consume documents published via the SAF.


This chapter assumes that you have read the chapter on ContentProvider patterns or have equivalent experience with consuming streams published by a ContentProvider.

The Storage Access… What?

Let’s think about photos for a minute.

A person might have photos managed as:

Now, let’s suppose that person is in an app that allows the user to pick a photo, such as to attach to an email.

The classic Android solution would be for the user to have to first choose the app to use to find the photo (e.g., Gallery, Instagram, Google Drive, Dropbox), then find the photo using that app. Then, if all goes well, the original app would receive a Uri to that photo and be able to make use of it.

However, this flow has three main problems:

  1. From the user’s standpoint, they need to know where they have the photo before they can go looking for it. Given the prominence of generic file-storage services, the user might not remember where the photo is stored, but might remember enough details about the photo (e.g., timeframe when taken, tags that might have been attached to the photo) to find it… but the user has to sequentially search each possible photo-storing app until the right one is found.
  2. From the client app developer’s standpoint, too many apps screw up handling the classic ACTION_PICK and ACTION_GET_CONTENT activities, failing to return a result in all cases. Users then are as likely to blame the client app for the mistake as they are to blame the photo-storing app or Android itself.
  3. None of this was designed with online file-sharing services in mind. What happens if an app knows about a possible file, but the file is not available on the device right now, because it has not been downloaded from the online service?

The Storage Access Framework is designed to address these issues. It provides its own “picker” UI to allow users to find a file of interest that matches the MIME type that the client app wants. File providers simply publish details about their available files — including those that may not be on the device but could be retrieved if needed. The picker UI allows for easy browsing and searching across all possible file providers, to streamline the process for the user. And, since Android is the one providing the picker, the picker should more reliably give a result to the client app based upon the user’s selection (if any).

The Storage Access Framework Participants

The preview of this section was stepped on by Godzilla.

Picking How to Pick (a Peck of Pickled Pepper Photos)

The preview of this section is en route to Mars.

Opening a Document

The preview of this section is presently indisposed.

Why We Want Things To Be Openable

The preview of this section was lost in the sofa cushions.

The Rest of the CRUD

The preview of this section was whisked away by a shark-infested tornado.

The DocumentFile Helper

The preview of this section is out seeking fame and fortune as the Dread Pirate Roberts.

CWAC-Document and DocumentFileCompat

The preview of this section is in an invisible, microscopic font.

Getting Durable Access

The preview of this section was the victim of a MITM ('Martian in the middle') attack.

Another Durable Example: Diceware

The preview of this section was whisked away by a shark-infested tornado.

Document Trees

The preview of this section is en route to Mars.

Getting a Tree: Example

The preview of this section is en route to Mars.

Scoped Directory Access Bug

The preview of this section apparently resembled a Pokémon.

Android 8.0 Changes

The preview of this section was lost in the sofa cushions.