67

I'm having a hard time understanding the difference between ACTION_OPEN_DOCUMENT and ACTION_GET_CONTENT intents when they are used to open an openable document. If I am supporting Andriod before KitKat, which does not support ACTION_OPEN_DOCUMENT, should I just settle with ACTION_GET_CONTENT?

The documentation says this:

ACTION_OPEN_DOCUMENT is not intended to be a replacement for ACTION_GET_CONTENT. The one you should use depends on the needs of your app:

  • Use ACTION_GET_CONTENT if you want your app to simply read/import data. With this approach, the app imports a copy of the data, such as an image file.
  • Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to documents owned by a document provider. An example would be a photo-editing app that lets users edit images stored in a document provider.

Doesn't ACTION_GET_CONTENT also use document providers in KitKat? What would prevent me from having "long term, persistent access" and what exactly does that mean?

Basically, what is the difference between the following two snippets?

ACTION_GET_CONTENT

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");

ACTION_OPEN_DOCUMENT

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
cambunctious
  • 8,391
  • 5
  • 34
  • 53

1 Answers1

57

Doesn't ACTION_GET_CONTENT also use document providers in KitKat?

Not necessarily. That depends on the implementation of the app that is publishing the content. Also note that DocumentProvider is a specific type of ContentProvider.

What would prevent me from having "long term, persistent access"

The Uri that you get back from ACTION_GET_CONTENT may have a temporary permission grant with it for your app, to be able to read and/or write the content. That grant will eventually lapse (e.g., when your process terminates). So, for example, saving the Uri as a string in a database may be pointless.

Part of the Storage Access Framework includes the concept that a provider of content can offer permission grants that can last for an extended period ("long-term, persistent"). While there's nothing stopping an app from offering such persistent permissions with ACTION_GET_CONTENT on API Level 19+, they will be more common with ACTION_OPEN_DOCUMENT.

Basically, what is the difference between the following two snippets?

The user experience will be somewhat different, as ACTION_OPEN_DOCUMENT provides a standardized file explorer-style interface, whereas ACTION_GET_CONTENT is a traditional chooser dialog, followed by some app-specific UI.

From your standpoint as a consumer of this content, ACTION_GET_CONTENT is if you want to use the content now; ACTION_OPEN_DOCUMENT is if you want to use the content now and later.

Edit: Links to documentation:

ACTION_OPEN_DOCUMENT

ACTION_GET_CONTENT

From the Common Intents example for opening a specific type of file:

Instead of retrieving a copy of a file that you must import to your app (by using the ACTION_GET_CONTENT action), when running on Android 4.4 or higher, you can instead request to open a file that's managed by another app by using the ACTION_OPEN_DOCUMENT action and specifying a MIME type. To also allow the user to instead create a new document that your app can write to, use the ACTION_CREATE_DOCUMENT action instead. For example, instead of selecting from existing PDF documents, the ACTION_CREATE_DOCUMENT intent allows users to select where they'd like to create a new document (within another app that manages the document's storage)—your app then receives the URI location of where it can write the new document.

Whereas the intent delivered to your onActivityResult() method from the ACTION_GET_CONTENT action may return a URI of any type, the result intent from ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT always specify the chosen file as a content: URI that's backed by a DocumentsProvider. You can open the file with openFileDescriptor() and query its details using columns from DocumentsContract.Document.

Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 22
    In my experience, there is never a chooser dialog. The two actions result in the same fullscreen UI. It is like a file explorer, but you can also choose to slide out a left drawer full of app icons. The only difference when using each action is this list of apps on the left. When I pass image MIME types, GET_CONTENT allows me to explore not only my folders like downloads, but also has an entry on a slide out left drawer for Google Photos, Dropbox, etc. If I use OPEN_DOCUMENT, I get the exact same UI, there just are no apps in the left drawer willing to serve me content other than Google Drive. – Stephen Jan 05 '17 at 02:15
  • 3
    @Stephen: "there is never a chooser dialog" -- `ACTION_GET_CONTENT` will have one on Android 4.3 and older. "The only difference when using each action is this list of apps on the left" -- some apps support one of the actions, some support the other. Ideally, an app like Dropbox would support `ACTION_OPEN_DOCUMENT` on Android 4.4+, falling back to supporting `ACTION_GET_CONTENT` on Android 4.3 and lower. – CommonsWare Jan 05 '17 at 12:32
  • 1
    I just installed my application on a 4.3 device and you are correct! A "picker" did show up rather than the "file explorer" type interface. Thanks for the help! By the way, love your books. I've been subscribed for years. – Stephen Jan 05 '17 at 20:41
  • @Stephen: Thanks for the kind words! – CommonsWare Jan 05 '17 at 20:45