Abrir arquivos com o framework de acesso ao armazenamento

O Android 4.4 (API de nível 19) introduz o Framework de acesso ao armazenamento (SAF, na sigla em inglês). O SAF simplifica a navegação e a abertura de documentos, imagens e outros arquivos em todos os provedores de armazenamento de documentos mais usados pelos usuários. A IU padrão fácil de usar permite aos usuários procurar arquivos e acessar documentos recentes de maneira consistente em todos os apps e provedores.

Os serviços de armazenamento local ou em nuvem podem participar desse ecossistema implementando um DocumentsProvider que encapsule os serviços. Os apps clientes que precisam acessar documentos de um provedor podem fazer a integração com o SAF com apenas algumas linhas de código.

O SAF contém o seguinte:

  • Provedor de documentos: um provedor de conteúdo que oferece um serviço de armazenamento, como o Google Drive, para exibir os arquivos que gerencia. Um provedor de documentos é implementado como subclasse da classe DocumentsProvider. O esquema do provedor de documentos é baseado em uma hierarquia de arquivos tradicional, mas depende de você a maneira como seu provedor armazena os dados fisicamente. A plataforma Android inclui vários provedores de documentos integrados, como Downloads, Imagens e Vídeos.
  • App cliente: um app personalizado que invoca as ações da intent ACTION_CREATE_DOCUMENT, ACTION_OPEN_DOCUMENT e ACTION_OPEN_DOCUMENT_TREE e recebe os arquivos retornados pelos provedores de documentos.
  • Seletor: uma IU de sistema que permite aos usuários acessar documentos de todos os provedores de documentos que satisfazem os critérios de pesquisa do app cliente.

Estes são alguns dos recursos oferecidos pelo SAF:

  • Permite que usuários procurem conteúdo de todos os provedores de documentos, não somente de um único app.
  • Isso permite que o app tenha acesso persistente e de longo prazo a documentos de propriedade de um provedor de documentos. Por meio desse acesso, os usuários podem adicionar, editar, salvar e excluir arquivos no provedor.
  • É compatível com várias contas de usuário e raízes transitórias, como provedores de armazenamento USB, que só aparecem se o drive estiver conectado.

Visão geral

O SAF consiste em um provedor de conteúdo que é uma subclasse da classe DocumentsProvider. Dentro de um provedor de documentos, os dados são estruturados como uma hierarquia de arquivo tradicional:

modelo de dados

Figura 1. Modelo de dados do provedor de documentos. Uma raiz aponta para um único documento que inicia a distribuição de dados de toda a árvore.

Observe o seguinte:

  • Cada provedor de documentos relata uma ou mais "raízes", que são pontos de partida para explorar uma árvore de documentos. Cada raiz tem um COLUMN_ROOT_ID único que aponta para um documento (um diretório) representando o conteúdo sob essa raiz. As raízes são naturalmente dinâmicas para oferecer compatibilidade a casos de uso como várias contas, dispositivos de armazenamento USB transitórios ou login/logout do usuário.
  • Sob cada raiz há um documento único. Esse documento indica de 1 a N documentos, e cada um deles pode indicar de 1 a N documentos.
  • Cada back-end de armazenamento exibe arquivos e diretórios individuais referenciando-os com um COLUMN_DOCUMENT_ID único. Os IDs de documentos precisam ser únicos e não podem ser mudados depois de emitidos. Isso porque eles são usados para concessões persistentes do URI em reinicializações do dispositivo.
  • Os documentos são arquivos que podem ser abertos (com um tipo MIME específico) ou diretórios contendo documentos extras (com o tipo MIME MIME_TYPE_DIR).
  • Cada documento pode ter diferentes funcionalidades, conforme descrito por COLUMN_FLAGS. Por exemplo, FLAG_SUPPORTS_WRITE, FLAG_SUPPORTS_DELETE e FLAG_SUPPORTS_THUMBNAIL. O mesmo COLUMN_DOCUMENT_ID pode ser incluído em vários diretórios.

Controle de fluxo

Como indicado anteriormente, o modelo de dados do provedor de documentos é baseado em uma hierarquia de arquivos tradicional. No entanto, você pode armazenar fisicamente seus dados da maneira que quiser, contanto que possa acessá-los usando a API DocumentsProvider. Por exemplo, seria possível usar armazenamento em nuvem com base em tag para os dados.

A Figura 2 mostra como um app de fotos poderia usar o SAF para acessar dados armazenados:

app

Figura 2. Fluxo do Framework de acesso ao armazenamento.

Observe o seguinte:

  • No SAF, provedores e clientes não interagem diretamente. O cliente solicita permissão para interagir com arquivos (ou seja, ler, editar, criar ou excluir arquivos).
  • A interação começa quando um aplicativo (neste exemplo, um app de fotos) dispara a intent ACTION_OPEN_DOCUMENT ou ACTION_CREATE_DOCUMENT. A intent pode conter filtros para refinar ainda mais os critérios. Por exemplo, "quero todos os arquivos que podem ser abertos e que têm o tipo MIME 'image'".
  • Ao disparar a intent, o seletor do sistema contata cada provedor registrado e exibe para o usuário as raízes de conteúdo correspondentes.
  • O seletor fornece aos usuários uma interface padrão para acessar documentos, embora os provedores de documentos subjacentes possam ser bem diferentes. Por exemplo, a Figura 2 mostra um provedor do Google Drive, um de USB e outro de nuvem.

A Figura 3 mostra um seletor com a pasta Downloads selecionada por um usuário que fazia uma pesquisa por imagens. Ela também mostra todas as raízes disponíveis para o app cliente.

Captura de tela da seleção de pastas no seletor do sistema

Figura 3. Seletor.

Depois que o usuário seleciona a pasta Downloads, as imagens são exibidas. A Figura 4 mostra o resultado desse processo. Agora o usuário pode interagir com essas imagens de maneiras compatíveis com o provedor e o app cliente.

Captura de tela da pasta Downloads

Figura 4. Imagens armazenadas na pasta "Downloads", conforme visualizado no seletor do sistema.

Programação de um aplicativo cliente

No Android 4.3 e em versões anteriores, para o app recuperar um arquivo de outro app, ele precisa chamar uma intent como ACTION_PICK ou ACTION_GET_CONTENT. Em seguida, o usuário precisa selecionar um único app para retirar um arquivo, e o app selecionado precisa fornecer uma interface do usuário para a busca e seleção dos arquivos disponíveis.

No Android 4.4 (API de nível 19) e em versões mais recentes, também existe a opção de usar a intent ACTION_OPEN_DOCUMENT, que exibe uma IU do seletor controlada pelo sistema que permite ao usuário procurar todos os arquivos disponibilizados por outros apps. Nessa IU exclusiva, o usuário pode selecionar um arquivo de qualquer app compatível.

No Android 5.0 (API de nível 21) ou em versões mais recentes, você também pode usar a intent ACTION_OPEN_DOCUMENT_TREE, que permite que o usuário escolha um diretório para um app cliente acessar.

Observação: ACTION_OPEN_DOCUMENT não substitui ACTION_GET_CONTENT. O uso de cada um deles depende da necessidade do app:

  • Use ACTION_GET_CONTENT se quiser que o app simplesmente leia ou importe dados. Nessa abordagem, o app importa uma cópia dos dados, como um arquivo de imagem.
  • Use ACTION_OPEN_DOCUMENT se quiser que o app tenha acesso persistente e de longo prazo a documentos de propriedade de um provedor de documentos. Um exemplo seria um app de edição de fotos que permite aos usuários editar imagens armazenadas em um provedor de documentos.

Para ver mais informações sobre como oferecer compatibilidade com a navegação de arquivos e diretórios usando a IU do seletor do sistema, consulte o guia sobre como acessar documentos e outros arquivos.

Outros recursos

Para ver mais informações sobre provedores de documentos, use os seguintes recursos:

Amostras

Vídeos